SaltStack RCE (CVE-2020-11651) 简单分析
[Vulnerability Analysis]
漏洞原理比较简单,看advisory可以很快调出来,因此黑产批量利用较快。
Patch
- https://github.com/saltstack/salt/commit/a67d76b15615983d467ed81371b38b4a17e4f3b7#diff-81ea017b5c8f831cea8ab4e035970b92
认证
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
方法检验认证是否有效。
在第三种认证方式auth_type=='user'
中,会由_prep_auth_info
获取到系统opt的key,传递到check_authentication
中和API参数中携带的key进行==
比对。
理论上_prep_auth_info
是不可被外部调用的,漏洞成因即是攻击者通过匿名API直接调用_prep_auth_info
方法,在回显中拿到self.key
,并在后续的请求中使用获取到的key过验证,以root权限执行高危指令。
路由
Mworker daemon进程处理API请求:
class MWorker(salt.utils.process.SignalHandlingProcess):
"""
The worker multiprocess instance to manage the backend operations for the
salt master.
"""
其中 _handle_clear & _handle_aes 函数分别处理明文和加密指令:
在这里,self._clear_funcs
是 class ClearFuncs
的实例,在这里API访问者可以无认证调用任意的类函数。
class ClearFuncs(TransportMethods):
"""
Set up functions that are safe to execute when commands sent to the master
without encryption and authentication
"""
ClearFuncs._prep_auth_info()
将self.key返回给API造成泄露。攻击者可先通过这一方法拿到key,然后通过认证接口下发shell指令。
之前存在漏洞的代码中仅过滤掉__
开头的private方法,导致_prep_auth_info
泄露,patch中对clearfuncs和aesfuncs两个类添加了expose白名单过滤:
目前仅有这些方法可以通过clearfuncs访问,除了ping以外均需要认证。
防御
request无脑拦:{'cmd': '_prep_auth_info'}
检测成功利用:关联response的'[\w\d\/\+\=]{64,}'
匹配到则利用成功。
Ref
- https://labs.f-secure.com/advisories/saltstack-authorization-bypass