SaltStack_CVE-2020-11651/11652分析
文章首发于先知社区
SaltStack是一种基于C/S架构的服务器基础架构集中管理平台,最近披露出存在两个安全漏洞 CVE-2020-11651 权限缺陷、CVE-2020-11652 任意文件读写漏洞,官方公告SALT 3000.2 RELEASE NOTES, 两个CVE漏洞可以造成远程命令执行。Ghost 使用SaltStack管理自身的机器,漏洞披露后被恶意入侵并植入挖矿程序,Ghost的安全公告
Critical vulnerability impacting all services
受影响的version
- CVE-2020-11651
- SaltStack Salt before 2019.2.4 and 3000 before 3000.2
- CVE-2020-11652
- SaltStack Salt before 2019.2.4 and 3000 before 3000.2
0x00 CVE-2020-11651
官方公告对其描述
1 | The salt-master process ClearFuncs class does not properly validate method calls. This allows a remote user to access some methods without authentication. These methods can be used to retrieve user tokens from the salt master and/or run arbitrary commands on salt minions. |
POC
现有已公开POC核心逻辑
1 | def get_rootkey(): |
获取对应的rootkey后续可执行恶意命令达到远程命令执行目的
1 | def master_shell(root_key,command): |
poc调用salt packages 分析
1 | clear_channel = salt.transport.client.ReqChannel.factory(minion_config, crypt='clear') |
salt.transport.client.ReqChannel.factory 最后被实例化为AsyncZeroMQReqChannel,而且带有clear参数,即发给master的命令是clear没有AES加密的
SaltStack master端逻辑
SaltStack 逻辑非常复杂,只对涉及漏洞及其利用点的master端工作流程做简单梳理,可以结合SaltStack官方doc梳理
1 | 提交任务 -> ReqServer(TCP:PORT:4506) -> MWorker -> workers.ipc -> auth -> Publisher -> EventPulisher |
根据官方描述 ClearFuncs class 没有正确校验调用的method,即发生在 woker认领任务并发送publish命令处,结合POC在salt packages的调用流程
1 | salt/master.py |
启动主server及生成相应数量的woker线程
1 | salt/master.py |
通过_bind方法来绑定端口并接受请求,建立多进程模型
1 | salt/master.py |
通过post_fork()传入self._handler_payload 任务处理函数,在_handle_payload()方法中可以看由于poc的send 带有'enc': 'clear' 'cmd': '_prep_auth_info'
,所以调用
1 | def _handle_clear(self, load): |
调用_prep_auth_info
1 | def _prep_auth_info(self, clear_load): |
返回rootkey
修复代码
1 | method = self.clear_funcs.get_method(cmd) |
限制传入的method
0x01 CVE-2020-11652
官方公告对其描述
1 | The salt-master process ClearFuncs class allows access to some methods that improperly sanitize paths. These methods allow arbitrary directory access to authenticated users.zu |
POC
1 | SaltStack Test类 |
1 | msg = { |
缺陷代码
salt/wheel/file_roots.py
1 | def write(data, path, saltenv="base", index=0): |
使用os.path.isabs 判断是否是绝对路径,防止任意路径写入,但是被../绕过
修复代码
commit_id
新增校验函数
salt/utils/verify.py
1 | def _realpath(path): |
0x02 Other-salt packages安装issue
mac python3 -m pip install salt
会报错
1 | ext-date-lib/timelib_structs.h:24:10: fatal error: 'timelib_config.h' file not found |
python3 -m pip download timelib
1 | setup(name="timelib", |
python3 setup.py build
python3 setup.py install