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。
以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
#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的漏洞,其中包含2个严重漏洞,身份验证绕过漏洞(CVE-2020-11651)和目录遍历漏洞(CVE-2020-11652)。
ClearFuncs类处理未经身份验证的请求,并且无意中公开了_send_pub()方法,该方法可用于直接在master服务器上创建消息队列,此类消息可用于触发minions以root身份运行任意命令。
ClearFuncs类还公开了_prep_auth_info()方法,该方法返回用于验证master服务器上本地root用户命令的“root key”。可以使用此“root key”在主服务器上远程调用管理命令。这种无意的暴露为远程未经身份验证的攻击者提供了与salt-master相同的根访问权限。因此未经身份验证的远程攻击者可以使用此漏洞执行任意命令。
wheel模块包含在特定目录路径下读取和写入文件的命令。这些函数的输入参数与目标目录连接在一起,生成的路径未规范化处理,从而绕过了预期的路径限制。
salt.tokens.localfs类的get_token()方法(由ClearFuncs类暴露给未经身份验证的攻击者)无法清除token输入参数,该参数随后用作文件名,从而允许插入“ ..”路径元素并读取预期目录之外的文件。
SaltStack Salt<2019.2.4
SaltStack Salt<300.2
周二的上午,有国外的安全研究者在github上公开了漏洞利用检测poc,应该是从官方发布的补丁测试程序中发现了利用实现方法。经过测试发现,使用yum安装的默认应该是已经打了补丁,无法利用成功。建议从github下载源代码,进行安装。
要求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端口
参考官网的整体安全建议