by kxlzx http://inbreak.net
1月份,SEC Cousult发布了一篇关于struts2漏洞的文章,写到4个struts2的最新漏洞。一个漏洞可以做远程代码执行,一个漏洞引出了新的远程代码执行,一个漏洞曾经我在blog上发布过(没有投CVE),以及一个之前也曾看到过,但是认为是鸡肋的漏洞。
这篇文章题目叫做
《Multiple critical vulnerabilities in Apache Struts2》
四个漏洞,本文一个一个的讲一讲它们的前世今生。
Remote command execution in Struts
新的远程代码执行漏洞,已经在我的blog分析过它的利用和分析文章,具体地址在
《STRUTS2类型转换错误导致OGNL表达式注入漏洞分析》http://inbreak.net/archives/363
这里就不再多讲,我猜想或许就是因为这个漏洞被人爆了出来,才引出了老外发的这篇文章。
Remote command execution in Struts
COOKIE拦截器的远程代码执行,这看起来表面上很嚣张的样子,但其实较少用到,至少默认是不用的,必须要开发人员手工配置某个action才可以攻击,注意是一个单独的action,不懂这个的可以理解为URL。攻击者可能不知道是具体哪个action启用了这个配置,这会导致增加了漏洞发现的难度。也许攻击者要扫描所有的action,才能碰巧遇到一个做这样配置的地方。根据作者的经验,也许攻击者要扫描很多STRUTS2应用,才能遇到一个用到这个技术的应用。
下面的代码是示例:
<action name="testCookie" class="TestCookie"> <interceptor-ref name="cookie"> <param name="cookiesName">*</param> <param name="cookiesValue">*</param> </interceptor-ref> <result name="success">/T1.jsp</result> </action> |
可以看到,这是一个只针对testCookie这个action的配置。
由于CookieInterceptor在处理cookiesName时,会遍历cookiesMap,把cookie中的每个key和value做如下:
stack.setValue(cookieName, cookieValue); |
这样的OGNL赋值处理。可以看到,cookiename将会作为一个ognl表达式执行。cookiename刚好是用户提交来的,所以触发了漏洞。通常应用程序都会指定一个cookiename,只接受指定cookiename,这样做是不存在漏洞的。但是如果真的有开发,把它配置为“*”号,这样就允许接受所有的cookiename,也就存在漏洞了。
除此之外,一个不可忽视的限制,是tomcat等服务器是默认不允许很多非主流符号,这导致这种攻击,在tomcat服务器下,无法进行,这个问题暂时没有发现绕过的方式。
相关代码如下,给各位喜欢bypass的同学做参考:
//以下为cookieName中不允许的字符 public static final char SEPARATORS[] = { '\t', ' ', '\"', '(', ')', ',', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '{', '}' }; |
总之很少用到,意味着很鸡肋,不是我们想象中的,只要有COOKIE就默认处理。即使开发人员需要处理cookie,也不见得会使用这个东西,在以往所接触到的项目中,从来没有见过这种配置方法。
还有更有趣的地方,这肯定是个彩蛋,struts给出的官方修补方案,居然犯了一个错误。首先看看官方公告:
http://struts.apache.org/2.x/docs/s2-008.html |
特意抓个图证明。
解决方案是这样讲的:
Update to Struts 2.3.1 and apply a stronger acceptedParamNames filter to the ParameterInterceptor and CookieInterceptor: acceptedParamNames = "[a-zA-Z0-9\.][()_']+"; |
修补这个漏洞只需要在CookieInterceptor这个拦截器代码中,加入一个白名单列表,注意这个列表中,是有“小括号”符号的(小括号的作用,可以见本文下一个小节)。还好struts在真正实现的代码中,并没有这样做,而是把小括号也去掉了,否则这又是一个bypass,后面的内容会详细讲解有没有小括号的区别。
Arbitrary File Overwrite in Struts
这个漏洞,讲的是因为没有过滤小括号而导致的问题,其实我的blog比他先爆出来,只是在利用方式上,并没有想到使用
java.io.FileWriter
去写个空的文件出来,覆盖原本的文件内容。
我的blog曾经发的一篇,目的是DOS攻击,结合java一些版本的漏洞,new出来一个浮点型的变量,具体漏洞细节见以下文章。
《Struts 2.2.3 DOS漏洞》http://inbreak.net/archives/274
当时没有报告CVE,所以大家可能不知道。当然,我承认他们利用的比我精彩。
这个漏洞的精彩点,其实并不在谁先发现的,也不在于谁利用的更好,重点是这个团队在使用这个漏洞时,发出来一个OGNL语法小技巧。这个小小的技巧,刚好让一个大牛看到了,于是引出了一个不亚于当年秒杀所有struts框架的漏洞。
我相信,很多人都和我一样,垂首顿足的在讲:“擦!我怎么没想到”,当然,他们可能说的是英文版。
这个技巧先不讲,也就是小括号的事情,等下一个漏洞再讲。
Remote command execution in Struts
看到这个漏洞,我真的无语了,老外这是鸡肋的超神了。一点实用价值都没有的漏洞,事实上,我在看代码时,一看到struts代码中出现:
If (devMode) XXXXX |
就自觉跳过了。
原因是我认为没有人会傻到把debug默认开到公网上去,而struts官方也鄙视了一下这个漏洞:
While not being a security vulnerability itself……balabala… |
开启debug模式,意味着速度超级慢,意味着大批的无意义的log文件输出。所以,这个漏洞没什么可讲的,已经鸡肋到基本上你不会见到了。
它的具体成因,是当一个开发人员实在笨到啥都要问元芳的地步,以至于在线上开启debug模式后,struts2会有一个专门的拦截器,用于处理特殊的参数,当这个拦截器接收ognl命令时,可以直接执行,方便开发人员做调试。确切的说,这并不是漏洞,而是struts2专门给开发人员的调试模式。
从黑客技术的角度上讲,总会有开发人员这么做,所以不该放过,POC大家可以留着,好消息是官方不准备出补丁,只是轻轻的鄙视了一下这么做的开发人员。
CVE-2011-3923: Yet another Struts2 Remote Code Execution
前文两次提到这个漏洞,这是最新的BYPASS,这个漏洞的发布者看到了上文所述的“Arbitrary File Overwrite in Struts
http://blog.o0o.nu/2012/01/cve-2011-3923-yet-another-struts2.html |
0 条评论。