JAVA出了漏洞,CVE-2010-4476,会导致拒绝服务攻击。大家能从公告上,看到这样一段代码,挺长的。意思是只有开发人员写出这样的代码,才会对服务器造成影响。 人人
我们肯定会首先考虑,这么长的代码,究竟有多少开发会傻乎乎的写出来?而我们究竟打不打补丁呢?其实作者知道,目前还有很多公司没有打补丁,不过没关系,等会儿你就要打了。
先看看官方给出的代码。
Send a Java Program Into An Infinite Loop
Compile this program and run it; the program will hang (at least it does on a 32-bit system with the latest JRE/JDK):
class runhang {
public static void main(String[] args) {
System.out.println(“Test:”);
double d = Double.parseDouble(“2.2250738585072012e-308″);
System.out.println(“Value: ” + d);
}
}
—————————————————————————————————————-
Send the Java Compiler Into An Infinite Loop
Try to compile this program; the compiler will hang:
class compilehang {
public static void main(String[] args) {
double d = 2.2250738585072012e-308;
System.out.println(“Value: ” + d);
}
}
以上代码,其实举了两个例子,首先简化一下代码:
这段代码会在编译时挂掉:
double d = 2.2250738585072012e-308;
这段代码会在运行时挂掉:
double d = Double.parseDouble(“2.2250738585072012e-308″);
作者很奇怪后面的System.out是啥意思,按照实际测试以及官方原理,这句压根不会执行,楼上都已经“无限循环”了,怎么可能走下来呢?不过这个不重要。债务追讨
下文所说的漏洞,是指假设我们的开发人员写了“XXX”的代码,攻击者就可能攻击我们服务器。
我们来逆推攻击过程,从漏洞的角度上说,只有程序传入的值,由用户控制,才会导致漏洞触发,毕竟开发不会直接写这个值。而编译中挂掉,几乎不可能存在,很难有正常的业务需要用户提交代码,让服务器编译执行。所以,漏洞的产生只会出在这一句上:
这段代码会在运行时挂掉:
double d = Double.parseDouble(“2.2250738585072012e-308″);
那么再次逆推,要求这个值有用户控制,如果环境是java web application,开发想写出有漏洞的代码,必须这样搞:
这段代码会在运行时挂掉:
double d = Double.parseDouble(request.getParameter(“double”));
于是,程序就”hang!”(其实我不知道这个词的意思),挂了,从表面上看不出来,但是实际上你的CPU会立刻100%,当前线程走不下去,页面
卡死,不给你任何响应。当然,其他页面也许会好,因为web容器是多线程的,可惜已经有人100%CPU了,页面速度可想而知。
很多人,就考虑到了这段,除非开发人员真的写了这样的代码,否则很难出现漏洞,所以没有打补丁。
Java web在很多年前,都已经开始走框架路线了,我们熟知的spring
mvc、struts2、webwork等等,甚至还有一些公司自己实现框架,比如阿里巴巴公司的开源框架webx(宣传一下
http://code.taobao.org/project/view/401/)。在这样的框架中,开发人员更不可能自己去做转义,这都是框架自己
负责的。是不是意味着,漏洞不可能存在呢?
这恰恰是最可怕的地方,这些框架没有让开发人员参与类型转义,用户本来提交的是一个String的2.2250738585072012e-308,框架会自动转义类型为Double,经测试,所有的框架都有自动类型转义(否则框架意义何在啊)。
开发什么都不需要做,只要在action中有一个对象,对象中有一个字段类型为double,或许他都不需要定义对象,其他开发早定义好了,他只需要写一个action。比如:
//订单处理action
public class OrderAction extends ActionSupport{
//订单对象
public Order order;
public String execute(){
return SUCCESS;
}
}
//Order对象的内容
Public class Order{
//前面还有其他字段,这里只说Double类型的。
Double money;
}
这就“hang”了。我们可以写个扫描器,那么会有哪些字段通常被定义为double呢?扫描器自己去抓页面,抓回来的input,如果为user.name,我们就猜测
user对象中可能存在money,可能存在score、point等,然后让它们等于那个值,自动提交。这等于挂字典,猜测对象中可能存在的
double类型字段。
有没有线上的例子呢?
posted on 2011-04-26 09:35
墙头草 阅读(271)
评论(0) 编辑 收藏