Struts 2.2.3 DOS漏洞

作者:hack1990 时间:12-11-26 阅读数:692人阅读

在struts2和webwork中,曾出现了远程代码执行漏洞

但是后来因为补丁会导致部分应用出现BUG,所以官方又给出了2次补丁

这次的修补,重新开启一个小小的功能,也同时开启了一个必杀dos炸弹 这个炸弹需要结合java浮点漏洞使用

该漏洞会覆盖所有最新版本的struts2:

Struts 2.2.3 (GA)

Struts 2.0.14 (GA)

只有打了“java浮点漏洞官方补丁”,才能逃过一劫。

这是作者对该漏洞的一篇分析文:  《Java浮点值拒绝服务漏洞危害分析》,后文会用到。

Struts2为了修补漏洞,首先推出了补丁:

private String acceptedParamNames = "[a-zA-Z0-9\\.\\]\\[_'\\s]+";

只允许“字母、数字、.、[、]、_、’、空格”出现在参数名称中,然而这个限制,

也同时直接禁止了 (引自 http://www.sunxin.org/forum/thread/19682.html)

这导致开发人员本身定义的数据类型Set,本来可以提交

Persons(1).name=空虚浪子心

赋值的,打了这个补丁后,这种用法直接被拦截了。所以struts2官方也意识到这个这个补丁过于严格

导致正常业务不能通行,必须要把圆括号放开,同时圆括号也不会重现漏洞,所以再次补丁

http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java?r1=956389&r2=956397&diff_format=h
private String acceptedParamNames = "[a-zA-Z0-9\\.\\]\\[\\(\)_'\s]+";

最新版本的struts2也是这样的代码。从作者的调查上看,大多数开发都不会直接使用官方补丁

特别是有经验的开发,他们只会过滤掉补丁中的“exp特征码”(官方补丁误杀太多),允许小括号的出现

那么不管怎样,现在允许小括号了。

看过我分析struts2远程代码执行文章的同学们(http://www.inbreak.net/archives/167

都知道这个漏洞和ognl的关系,本文不再叙述,只是引用一篇OGNL官方文给大家看:

http://www.opensymphony.com/ognl/html/LanguageGuide/constructors.html

OGNL的LanguageGuide中,写明自己是允许“new Object”的,而OGNL的代码

实际意义上,是先编译,后执行。就是说,我们提交了一个ognl语句后,引擎会负责转换为java代码

之后编译、执行。注意,前文提到了“编译”这个词。

那么再次引用上一篇文章的话:

这段代码会在编译时挂掉:

  double d = 2.2250738585072012e-308;
这段代码会在运行时挂掉:
  double d = Double.parseDouble(“2.2250738585072012e-308″);

那时的作者,其实也发现了编译的漏洞,只是不愿意发出来,所以使用了“而编译中挂掉,几乎不可能存在,很难有正常的业务需要用户提交代码,让服务器编译执行。”这样的话来误导大家。具体原因大家懂得。

  提醒过大家,会有更加直接的利用发出来的。上次讲过,只要action的方法中,存在DOUBLE类型的属性,就可以直接攻击,利用的是“运行时挂掉”原理。

  在ognl语句中,执行“new Double(2.2250738585072012e-308)”,就会直接在编译中挂掉,现在struts2允许用户提交用于编译的代码,又允许了小括号,就可以直接提交:


http://www.inbreak.net/app/secTest.action?new java.lang.Double(2.2250738585072012e-308)

经过测试,可以直接CPU跑满了。请注意实际上这里的”new java.lang.double”根本没有真的“new”,而是挂在了编译的时候。

刚发邮件,就被KJ牛鄙视了:“里面有短横线”,会被struts2补丁过滤掉。还好,作者复习了一遍“科学计数法”,绕过了struts2的补丁执行,才没有丢人:

http://www.iick.blog/app/secTest.action?(new java.lang.Double(0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072012))
这段东西,也可以直接在eclipse中跑,请测试时,提前打开“任务管理器”,你会用到的。

对这种数字转换形式,不懂的自己百度一下“0.xxxE-xx”的含义,学习一下“科学计数法”。最终没有“短横线”了,同时也把测试环境跑挂。

如果看了上一篇分析文,你没有老老实实的打官方补丁,而是采用了“by pass exp特征码”的方法,过滤了字符串中的“2.2250738”,那么看了这串数字,相信你会比作者更激动的
 

发表评论