CVE-2016-3081(Struts2)漏洞分析以及F5应对方法
摘要::该漏洞对F5本身并无影响,但是通过F5 iRule可以快速对该漏洞进行修补,防范该漏洞!F5在安全上的价值再一次得到体现!请看我们为大家分享由F5合作伙伴力尊信通南区资深技术经理陈林撰写的漏洞分析及F5解决方案。
CVE-2016-3081漏洞对F5有无影响?
该漏洞对F5本身并无影响,但是通过F5 iRule可以快速对该漏洞进行修补,防范该漏洞!F5在安全上的价值再一次得到体现!
目前新出现的CVE-2016-3081即Struts2的漏洞,对部分金融等行业应用中间件的特定版本有影响。F5合作伙伴力尊信通的南区资深技术经理陈林在得知此漏洞出现后,彻夜奋战,撰写了详实的漏洞分析报告及利用F5快速屏蔽该漏洞的解决方案,以备不时之需。在过后的上午10点,有客户问询F5对此漏洞是否有解决方案,通过陈林的文档,客户的问题得以解决。客户对F5和力尊信通对此安全事件的迅捷应对,专家级别响应,及问题得以及时解决给予了高度的赞许!
漏洞概要
2016年4月21日Struts2官方发布两个CVE,其中CVE-2016-3081官方评级为高。主要原因为在用户开启动态方法调用的情况下,会被攻击者实现远程代码执行攻击。
漏洞影响
2016年4月21日Struts2官方发布两个CVE,其中CVE-2016-3081官方评级为高。主要原因为在用户开启动态方法调用的情况下,会被攻击者实现远程代码执行攻击。从乌云的情况来看,国内开启这个功能的网站不在少数,尤其是金融类的网站。所以这个“ Possible Remote Code Execution”漏洞的被打的可能性还是很高的。
漏洞分析
漏洞原理
直接进行版本比对,我们可以看到针对这个问题,只对DefaultActionMapper.java这个文件进行了修改,修改内容如下:
只是把method成员变量的值进行了一次过滤,cleanupActionName这个方法是在对“action:”滥用的问题进行添加的,禁止了绝大多数的特殊字符。但是在后来的版本变更中忽略了之前的问题,将method也引入了ONGL表达式,代码在 DefaultAction.java的invokeAction中:
我们可以看到methodName被带入到getValue了,熟悉Struts相关漏洞的朋友应该都明白这是什么意思,虽然后面被强制添加了一对圆括号,但是想办法语法补齐就好了。相对应的我们来看下在2.3.18版本之前的代码是怎么处理methodName的:
漏洞利用
这是一个威胁很大的漏洞。但是官方说的受影响版本Struts 2.0.0-Struts Struts 2.3.28(except 2.3.20.2and2.3.24.2)是不严谨的,应该是2.3.18-2.3.28(除了 2.3.20.2and2.3.24.2)。
利用方式主要难点在于两个地方,一个是上文提到的对于表达式最后的圆括号给予正确的表达式意义。另一个就是在传输过程中method会经过一次转义,双引号和单引号的没有办法使用了,所以需要找到一个绕过。剩下的就是原来套沙盒绕过,命令执行的那套东西了。
对于圆括号,可以直接使用new java.lang.String这样来拼接成new java.lang.String()构成正确OGNL语法。
至于不能使用印好的话,命令执行我们可以使用引用参数的方法来完成对字符串的提取,例如:使用#parameters.cmd来提取http的cmd参数。
漏洞现状
虽然该CVE已经发布了,但是从目前网上情况上(twitter和微博)来看,并没有安全研究人员关注到这两个CVE,可能是因为官方发布过太多鸡肋的CVE了,国内的各路炒洞高手已经对Struts2麻木了。所以目前的情况是属于漏洞存在那里,发布了CVE,但是没有任何人去研究利用,发布相关分析。这个漏洞和Struts2前N次被炒的热热闹闹的漏洞影响和危害相比,真是不可同日而语,这个漏洞真的很实在。
看到这里,打算磨拳擦掌要去调回显PoC的朋友们,这里我要在提醒一次。虽然我在之前说了存在这个问题的站点很多,但是这个漏洞存在版本限制,在Struts2.3.18及其以上的版本才可以触发。而国内大多数的站点由于Struts在2.3.16之后再也没有出现过大的问题,所以绝大多数停留在2.3.16这个版本,这让这个看似很不错的漏洞略显鸡肋了。
F5 应对方法
经内部安全小组评估,CVE-2016-3081漏洞对F5系统本身无影响。
对于Struts在2.3.16之后的圆括号,可以直接使用new java.lang.String这样来拼接成new java.lang.String()构成正确OGNL语法。而这个关键字必须通过URL Request注入。
所以可以通过F5添加一条iRules,利用UIE引擎将含有 “ java.lang.String”这个关键字构成完整的语法, 将含有这个关键字的URL Request屏蔽即可。 正常的业务的URL是不需要这个关键字的。