zoukankan      html  css  js  c++  java
  • Java浮点值拒绝服务漏洞危害分析

    By 空虚浪子心 http://www.inbreak.net/

    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”));

    当开发人员写出这样的代码,攻击者可以提交:

    http://www.inbreak.net/double.do?double=2.2250738585072012e-308

    于是,程序就”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;
    }


    这是很常见的写法,只要Order对象中,有一个字段是Double的。我们就可以对此action提交:

    http://www.inbreak.net/order.do?order.money=2.2250738585072012e-308

    这就“hang”了。
    我们可以写个扫描器,那么会有哪些字段通常被定义为double呢?扫描器自己去抓页面,抓回来的input,如果为user.name,我们就猜测 user对象中可能存在money,可能存在score、point等,然后让它们等于那个值,自动提交。这等于挂字典,猜测对象中可能存在的 double类型字段。
    有没有线上的例子呢?
    163的网易宝单日支付金额限制:

    正常的情况,填入1元,看看效果:

    立刻来到了
    但是我们填上:2.2250738585072012e-308

    等啊等,等啊等。。。等到花儿也谢了,还是不响应!
    你猜猜它们的服务器怎样了?
    Java web框架化以后,开发人员和架构师都忘记了转义类型的事情,也不需要自己做转义,代码变得越来越简单。作者为了研究漏洞,去询问有些资深架构师时,甚至 以为“开发不会写这样的代码”,所以我们的程序不会受到影响。最终还是作者亲手用现有框架搭建了环境,把CPU真的跑到100%,才开始相信这个漏洞对框 架的危害。
    作者相信,J2EE框架对这个漏洞的完美支持,足以使很多门户网站沦陷。而这只是刚刚开始,你可以抱有侥幸心理,不过下一篇和这个漏洞有关的文章,会让你彻底打消这个念头。

  • 相关阅读:
    RESTFul-service guideline
    logback推荐配置
    MongoDB 存活時間 TTL 用法
    IntelliJ IDEA 的热部署插件JRebel 安装及使用(破解)
    Idea远程调试
    学习方法记录
    2017年3月9日日记
    maven整合SSM总结
    【转】 SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
    【转】如何用Maven创建web项目(具体步骤)
  • 原文地址:https://www.cnblogs.com/sunxucool/p/3208698.html
Copyright © 2011-2022 走看看