CVE-2020-11651 SaltStack认证绕过分析


简介

SaltStack是一种基于C/S架构的服务器基础架构集中管理平台,它是一种全新的基础设施管理方式,部署轻松,在几分钟内可运行起来,扩展性好,很容易管理上万台服务器,速度够快,服务器之间秒级通讯。
Saltstack使用Python开发,是一个非常简单易用和轻量级的管理工具。由Master和Minion构成,通过ZeroMQ进行通信,master可以通过发布消息来管理多个minion。
Saltstack的master端监听4505与4506端口,4505为salt的消息发布系统,4506为salt客户端与服务端通信的端口;salt客户端程序不监听端口,客户端启动后,会主动连接master端注册,然后一直保持该TCP连接,master通过这条TCP连接对客户端控制,

2020年4月30日 F-Secure 安全团队披露了关于SaltStack两个安全漏洞:CVE-2020-11651 权限缺陷、CVE-2020-11652 任意文件读写漏洞。受影响的版本为:

  • 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

本文来分析并复现下CVE-2020-11651这个漏洞。

SaltStack安装

SaltStack有多种安装方式,这个是官方的安装教程,涵盖了多个平台的安装。但是我推荐使用Salt bootstrap的快速安装方式,只需一个脚本即可完成安装,项目地址:https://github.com/saltstack/salt-bootstrap/tree/stable.

由于本次只是为了漏洞的演示,所以使用docker快速安装。
使用以下命令即可完成安装

docker pull vulfocus/saltstack-cve_2020_11651
docker run -d -p 4506:4506 -p 4505:4505 vulfocus/saltstack-cve_2020_11651

其实VULFOCUS上也集成了这个靶场.

20200811111407

先试用exp进行下验证, 使用的exp是github上开源的一个,https://github.com/0xc0d/CVE-2020-11651:

20200811150805

漏洞分析

在漏洞分析之前需要先梳理下SaltStack的认证方式:

20200824172454

上图为SaltStack Master和Monion的一个简单架构,Master负责管理众多Monion.

Salt master 与 minion 通讯采用的是”订阅-发布“的模式。
通讯的连接由 Salt minion 发起,这意味着 minion 无须开启进向的端口(注意:此方式极大地简便了网络规则的设定)。
而 Salt master 的 4505 和 4506 端口(默认)必须开启,以接收外部的连接。其中端口功能如下表所示。

20200824174132

1.当 minion 启动时,其将搜索网络中的 master。当找到时, minion 将发送公钥给 Salt master,从而实现初次握手。
2.当初次握手后,Salt minion 的公钥将被保存在服务端,此时 master 需要使用过 salt-key 命令接收公钥(也可以采用自动机制)。注意:在 Salt minion 的公钥被接收前,Salt master 是不会将密钥发放给 minion 的,也就是说 minion 在此之前不会执行任何命令。
3.当 Salt minion 的公钥被接收后,Salt master 就会把公钥连同用于加解密 master 信息的可变动 AES 密钥发送至 Salt minion。其中,返回给 Salt minion 的 AES 密钥由 minion 的公钥加密,可由 Salt minion 解密。

当密钥交换完毕后,后续的通讯过程就可以使用AES进行加密。

本次漏洞发生的原因就出在了4506端口上,由于Master端的ClearFuncs类处理未经身份验证的请求,并且调用_send_pub()方法,此方法可以获取root key从而导致可以以root权限执行任意命令。

看一下POC的核心语句:

20200825105904

在看代码:/salt/transport/zeromq.py

@salt.ext.tornado.gen.coroutine
    def send(self, load, tries=3, timeout=60, raw=False):
        '''
        Send a request, return a future which will complete when we send the message
        '''
        if self.crypt == 'clear':
            ret = yield self._uncrypted_transfer(load, tries=tries, timeout=timeout)
        else:
            ret = yield self._crypted_transfer(load, tries=tries, timeout=timeout, raw=raw)
        raise salt.ext.tornado.gen.Return(ret)

salt.transport.client.ReqChannel.factory 最后被实例化为AsyncZeroMQReqChannel,而且带有clear参数,即发给master的命令是clear没有AES加密的.

salt-master普遍使用这两行代码进行认证,其中clear_load是可控输入点。

auth_type, err_name, key, sensitive_load_keys = self._prep_auth_info(clear_load)
auth_check = self.loadauth.check_authentication(clear_load, auth_type, key=key)

_prep_auth_info首先会识别clear_load输入的字段并选用其中之一作为认证方式,然后传参到check_authentication方法检验认证是否有效。

    def _prep_auth_info(self, clear_load):
        sensitive_load_keys = []
        key = None
        if "token" in clear_load:
            auth_type = "token"
            err_name = "TokenAuthenticationError"
            sensitive_load_keys = ["token"]
        elif "eauth" in clear_load:
            auth_type = "eauth"
            err_name = "EauthAuthenticationError"
            sensitive_load_keys = ["username", "password"]
        else:
            auth_type = "user"
            err_name = "UserAuthenticationError"
            key = self.key

        return auth_type, err_name, key, sensitive_load_keys

在第三种认证方式auth_type==’user’中,会由_prep_auth_info获取到系统opt的key,传递到check_authentication中和API参数中携带的key进行==比对。

理论上_prep_auth_info是不可被外部调用的,漏洞成因即是攻击者通过匿名API直接调用_prep_auth_info方法,在回显中拿到self.key,并在后续的请求中使用获取到的key过验证,以root权限执行高危指令。

参考


文章作者: darkless
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 darkless !
评论
 上一篇
浅析php反序列化字符串逃逸 浅析php反序列化字符串逃逸
php序列化与反序列化我们在开发的过程中常常遇到需要把对象或者数组进行序列号存储,反序列化输出的情况。特别是当需要把数组存储到mysql数据库中时,我们时常需要将数组进行序列号操作。 序列化(串行化):是将变量转换为可保存或传输的字符串的过
2020-09-29
下一篇 
你还在忍受龟速下载吗?--mac上使用aria2的最佳实践 你还在忍受龟速下载吗?--mac上使用aria2的最佳实践
首发于freebuf:https://www.freebuf.com/sectool/244962.html aria2简介aria2是一个轻量级多协议和多源命令行下载实用程序。它支持HTTP/HTTPS、FTP、SFTP、BitTor
2020-07-29
  目录