作者:be4c0n

SaltStack介绍

  • SaltStack是一款Python开发的开源配置管理工具;

  • 可用来发现、监控、响应、协调、自动化管理本地、混合、云和IOT资产;

  • 其最主要的差异是主从模式,分为master和minions(slave);

  • 经过配置之后master可以管理成千上万个minions;

  • master安装的是服务端组件salt-mater,minions安装的是salt-minion;

  • Salt使用基于ZeroMQ的强大异步网络拓扑,主要是为实现最快的通信;

  • Salt Master运行2个网络服务,ZeroMQ PUB系统,默认运行在4505端口;ZeroMQ REP系统,用于与Salt Minion进行双向通信,默认运行在4506端口;

  • Salt客户端(salt命令)发送的命令将通过ZeroMQ PUB/SUB广播给各个Salt Minion。前提是Salt Minion配置了Mater,并且Salt Master通过salt-key命令信任了对应的Salt Minion。建立连接之后,Salt Minion可以接收到广播命令,并且执行;

  • PUB/SUB是单向通信,因此一旦广播结束,Master服务器上的PUB接口就不会再与Minion进行任何通信。Minion在运行命令之后,通过REP端口(4506)将命令的返回数据发回Master。

SaltStack配置

Salt-Master服务的配置

 以centos为例

#master服务器执行

yum install -y salt-master

#默认配置文件路径

/etc/salt/master

#关键配置项,master的内网IP

interface: 192.168.1.3

注意:该配置项去掉注释之后默认是0.0.0.0,属于不安全的配置,如果在防火墙等无ACL限制,会导致master对外,因此攻击者可以利用后文中的漏洞进行攻击,建议配置成内网IP地址。

#PUB系统(广播发布)使用的端口

publish_port: 4505

#文件服务、认证、job结果返回对应的端口,不配置默认是4506端口

ret_port: 4506

#存储master的公私钥文件,以及拒绝和接受的minions的公钥文件的目录

pki_dir: /etc/salt/pki/master

Salt-minion服务的配置

 #minions服务器执行

yum install -y salt-minion

#默认配置文件路径

/etc/salt/minion

#关键配置项master,指定要连接的master服务器

master: 192.168.1.3

#存储pki相关文件的目录,默认如下

pki_dir: /etc/salt/pki/minion

Salt-master和Salt-minion的认证过程

通过以上的配置,启动salt-master和salt-minion之后,双方的通信认证过程如下:

  • Minion会在默认的/etc/salt/pki/minion/目录下自动生成minion.pem (私钥)、minion.pub(公钥)文件;

  • Master服务启动之后,会在默认的/etc/salt/pki/master目录下自动生成master.pem、master.pub文件;

  • Minion配置了master项,启动之后会将自己的公钥文件发送给Master;

  • Master上执行salt-key -L命令,可以查看到未接受的Minion的公钥名称,执行salt-key -a [Key名称]可以接受指定Minion的公钥,并在/etc/salt/pki/master/minions/目录下保存Minion的公钥文件内容,默认是以Minion的主机名命名的。

SaltStack漏洞介绍

近日,国外安全团队发现了多个SaltStack的漏洞,其中包含2个严重漏洞,身份验证绕过漏洞(CVE-2020-11651)和目录遍历漏洞(CVE-2020-11652)。

CVE-2020-11651(身份验证绕过漏洞)

ClearFuncs类处理未经身份验证的请求,并且无意中公开了_send_pub()方法,该方法可用于直接在master服务器上创建消息队列,此类消息可用于触发minions以root身份运行任意命令。

ClearFuncs类还公开了_prep_auth_info()方法,该方法返回用于验证master服务器上本地root用户命令的“root key”。可以使用此“root key”在主服务器上远程调用管理命令。这种无意的暴露为远程未经身份验证的攻击者提供了与salt-master相同的根访问权限。因此未经身份验证的远程攻击者可以使用此漏洞执行任意命令。

CVE-2020-116512(目录遍历漏洞)

wheel模块包含在特定目录路径下读取和写入文件的命令。这些函数的输入参数与目标目录连接在一起,生成的路径未规范化处理,从而绕过了预期的路径限制。

salt.tokens.localfs类的get_token()方法(由ClearFuncs类暴露给未经身份验证的攻击者)无法清除token输入参数,该参数随后用作文件名,从而允许插入“ ..”路径元素并读取预期目录之外的文件。

受漏洞影响的SaltStack版本

SaltStack Salt<2019.2.4

SaltStack Salt<300.2

漏洞环境搭建及测试

周二的上午,有国外的安全研究者在github上公开了漏洞利用检测poc,应该是从官方发布的补丁测试程序中发现了利用实现方法。经过测试发现,使用yum安装的默认应该是已经打了补丁,无法利用成功。建议从github下载源代码,进行安装。

  • 下载https://github.com/saltstack/salt/releases/tag/v3000

  • 要求setuptools>=9.1;

  • 从yum安装的其它机器拷贝一个/etc/salt/master配置文件;

  • 修改配置文件,去掉interface选项的注释;

  • 执行salt-master -c /etc/salt/ 来启动

利用github上公开的漏洞利用payload读取/etc/passwd文件内容,在被攻击的master上可以看到如下日志:

 [DEBUG ] Sending event: tag = salt/auth; data = {u"id": "root", u"_stamp": "2020-05-05T17:12:51.430372", u"result": True, u"pub": "-----BEGIN PUBLIC KEY-----\n攻击者的公钥文件内容\n-----END PUBLIC KEY-----\n", u"act": u"pend"}

[TRACE ] Client disconnected from IPC /var/run/salt/master/master_event_pull.ipc

[TRACE ] Process manager iteration

[TRACE ] Process manager iteration

[TRACE ] Clear payload received with command ping

[TRACE ] Clear payload received with command _prep_auth_info

[TRACE ] Clear payload received with command wheel

[DEBUG ] Sending event: tag = salt/wheel/20200505171256350117/new; data = {u"fun": u"wheel.file_roots.read", u"jid": u"20200505171256350117", u"tag": "salt/wheel/20200505171256350117", u"user": u"root", u"_stamp": "2020-05-05T17:12:56.350227"}

[DEBUG ] MasterEvent PUB socket URI: /var/run/salt/master/master_event_pub.ipc

[DEBUG ] MasterEvent PULL socket URI: /var/run/salt/master/master_event_pull.ipc

[TRACE ] IPCClient: Connecting to socket: /var/run/salt/master/master_event_pull.ipc

[TRACE ] IPCServer: Handling connection to address:

[DEBUG ] Sending event: tag = salt/wheel/20200505171256350957/new; data = {u"fun": u"wheel.file_roots.read", u"fun_args": ["/etc/passwd", {"saltenv": "base"}], u"jid": u"20200505171256350957", u"user": u"UNKNOWN", u"_stamp": "2020-05-05T17:12:56.353228"}

[DEBUG ] Sending event: tag = salt/wheel/20200505171256350957/ret; data = {u"fun_args": ["/etc/passwd", {"saltenv": "base"}], u"jid": u"20200505171256350957", u"return": [{"/etc/passwd": u"/etc/passwd文件内容"}, {"/etc/passwd": u"passwd文件内容"}], u"success": True, u"_stamp": "2020-05-05T17:12:56.354988", u"user": u"UNKNOWN", u"fun": u"wheel.file_roots.read"}

[DEBUG ] LazyLoaded nested.output

[TRACE ] data = [{"/etc/passwd": u"passwd文件的内容"}]

可以按照如上的日志特征,进行日志的审计和检查,判断是否有被进行过攻击,可成功读取被攻击服务器的敏感文件内容,以及执行任意命令等。

修复方法

官方在多天以前就进行了更新发布了新版本

Fix CVE-2020-11651

https://github.com/saltstack/salt/commit/a67d76b15615983d467ed81371b38b4a17e4f3b7

Fix CVE-2020-11652

https://github.com/saltstack/salt/commit/d5801df94b05158dc8e48c5e6912b065044720f3

最新修复后的版本:

https://github.com/saltstack/salt/releases/tag/v3000.2

https://github.com/saltstack/salt/releases/tag/v2019.2.4

其它建议:

  • Master的配置文件中interface项绑定本机的内网IP

  • 维护iptables规则,只允许指定的机器访问Master的4506端口

  • 参考官网的整体安全建议

    https://docs.saltstack.com/en/master/topics/hardening.html

声明:本文来自毕方安全实验室,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。