从防护角度看Struts2历史漏洞
字数 2603 2025-08-18 11:39:23
Struts2历史漏洞分析与防护指南
一、Struts2框架概述
Struts2是一个基于MVC设计模式的Java Web应用框架,其核心特性是引入了OGNL(Object-Graph Navigation Language)表达式,这使得框架具有灵活的动态性。然而,正是这种动态性导致了Struts2历史上出现了一系列严重的安全漏洞。
二、Struts2框架识别
2.1 常见识别特征
-
URL后缀特征:
.action或.do结尾的URL- 不带后缀的URI(当配置文件中
struts.action.extension值以逗号结尾或有空值时)
-
REST插件特征:
.xhtml、.xml或.json结尾的请求- 使用不同的处理流程:
xhtml:HtmlHandler处理xml:XStreamHandler处理json:JsonLibHandler处理
2.2 配置文件示例
<constant name="struts.action.extension" value="action,," />
<constant name="struts.action.extension" value="xhtml,,xml,json" />
三、Struts2漏洞原理
3.1 核心漏洞机制
Struts2漏洞的根源在于OGNL表达式的执行机制:
- OGNL表达式可以获取运行变量的值并执行函数调用
- 当恶意请求参数被送入OGNL执行流程时,会导致任意代码执行
3.2 关键执行点
OGNL表达式的执行主要在OgnlUtil类的以下方法中:
getValue()compileAndExecute()
调试时可对这些方法下断点分析执行流程。
四、主要历史漏洞分析
4.1 S2-045/S2-046
漏洞特点:
- 通过Content-Type头注入OGNL表达式
- 限制条件少,利用成功率高
利用流程:
- 请求包含
multipart/form-data的Content-Type - 框架将请求封装为
MultiPartRequestWrapper - 处理出错时调用
buildErrorMessage - 错误信息构造过程中执行OGNL表达式
补丁修复:
- 修改
buildErrorMessage不调用LocalizedTextUtil.findText函数
4.2 S2-001
漏洞特点:
- Struts2框架最早出现的漏洞
- 通过表单提交的参数执行OGNL表达式
利用流程:
- JSP生成Java类时对表单参数调用
evaluateParams - 调用文本处理类的OGNL求值功能
4.3 S2-016
漏洞特点:
- 通过redirect标签执行OGNL表达式
- 利用
DefaultActionMapper解析URI
利用流程:
- URI中包含redirect标签
ServletRedirectResult的execute函数执行- 通过
conditionalParse调用OGNL执行
4.4 S2-032/S2-033/S2-037
漏洞特点:
- S2-032需要开启动态方法执行配置
- S2-033/S2-037是REST插件漏洞
利用前提:
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
利用流程:
- URI中包含OGNL表达式作为方法名
DefaultActionMapper设置method属性invokeAction直接调用OGNL表达式
4.5 S2-052
特殊之处:
- 非OGNL表达式漏洞
- 使用unmarshal漏洞执行代码
- 依赖REST插件且需要JDK 1.8+
4.6 S2-057
利用条件:
- 开启
alwaysSelectFullNamespace配置为true - 使用服务器跳转的结果类型:
redirectAction(ServletActionRedirectResult)chain(ActionChainResult)postback(PostbackResult)
利用流程:
- OGNL表达式被提取为namespace
- 结果处理时将namespace送入OGNL引擎执行
五、Struts2沙盒防护与绕过
5.1 防护机制
最新版本(Struts2.5.20)的防护措施:
禁止访问的类:
<constant name="struts.excludedClasses"
value="
java.lang.Object,
java.lang.Runtime,
java.lang.System,
java.lang.Class,
java.lang.ClassLoader,
java.lang.Shutdown,
java.lang.ProcessBuilder,
com.opensymphony.xwork2.ActionContext" />
禁止访问的包:
<constant name="struts.excludedPackageNames"
value="
ognl.,
javax.,
freemarker.core.,
freemarker.template.,
freemarker.ext.rhino.,
sun.reflect.,
javassist.,
org.objectweb.asm.,
com.opensymphony.xwork2.ognl.,
com.opensymphony.xwork2.security.,
com.opensymphony.xwork2.util." />
5.2 常见绕过技术
- 通过
ActionContext获取Container - 使用
Container的getInstance方法获取ognlUtil实例 - 调用
ognlUtil的公开方法清空禁止访问的类和包:getExcludedPackageNames().clear()getExcludedClasses().clear()
- 设置
_memberAccess为DEFAULT_MEMBER_ACCESS
六、防护规则设计
6.1 检测策略
-
检测漏洞发生点:
- 特定URL模式
- 特殊HTTP头(如Content-Type)
- 特定参数位置
-
检测攻击代码:
- OGNL表达式特征
- 沙盒绕过技术
6.2 关键检测点
高价值检测点:
_memberaccessgetExcludedPackageNamesgetExcludedClassesDEFAULT_MEMBER_ACCESSServletActionContext@getResponsejava.lang.ProcessBuilderjava.lang.Runtimejava.io.FileOutputStreamgetParameterorg.apache.commons.io.IOUtils
低价值检测点:
- 特定包全名(易变形绕过)
- 过长字符串(易被截断或变形)
6.3 规则设计原则
- 站在攻击者角度思考
- 理解漏洞或攻击工具原理
- 平衡误报和漏报
- 规则字符串尽量短小精悍
- 关注核心不可变特征
七、总结与建议
7.1 现状分析
- Struts2新漏洞发现难度增大
- 现有漏洞利用成功率低
- 网络流量中主要为S2-045/S2-046的自动化扫描
7.2 防护建议
-
及时更新:
- 使用最新Struts2版本(2.5.20+)
- 关注安全公告及时打补丁
-
配置加固:
- 禁用动态方法调用
- 限制命名空间选择
- 谨慎使用REST插件
-
防护措施:
- 部署WAF/IPS设备
- 配置针对性防护规则
- 监控异常请求模式
-
开发规范:
- 避免使用危险的结果类型
- 严格控制用户输入处理
- 实施安全编码规范
通过深入理解Struts2漏洞原理和防护机制,可以有效提升系统安全性,防范潜在攻击。