CVE-2015-2080 分析

       jetty是一个使用非常广泛的java容器,在开发javaweb的应用的时候,使用jetty作为嵌入式的容器,调试起来非常方便。很多大的互联网公司都使用它来替代tomcat,就我所知,阿里里面使用jetty也是比tomcat多的。

       2015年2月25号的时候gdssecurity公布了jetty的一个缓冲区数据泄露的漏洞,以及漏洞的利用方式

http://blog.gdssecurity.com/labs/2015/2/25/jetleak-vulnerability-remote-leakage-of-shared-buffers-in-je.html

这个漏洞可能导致攻击者获取同时访问该jetty的其他用户http请求中的敏感数据。

       乌云上面已经有一篇翻译文章了(http://drops.wooyun.org/papers/4972),我学习了一下,并总结原理如下:

        1、jetty在处理http请求的时候,会把http请求的内容都保存在一个特定的buffer里面。每一次新的请求,都会覆盖这个buffer。jetty使用了nio,所以主要的保存在bytebuffer中

        2、在收到http请求之后,jetty会逐个字符解析和判断http头,http内容的信息。其中如果判断到http头部中包含非ascii的字符,则会抛出一个IllegalCharacter的异常

3、该异常会在http返回里面打印一些用户友好的debug信息,这就需要jetty继续去解析buffer里面的值。在将buffer里面的内容转换成debug信息的时候,由于没有考虑周全,buffer里面包含了上一次正常的用户请求的内容。如果本次请求比上一次请求短,则会连带将上一次请求的内容打印出来。

我画了一个图,看完了应该非常容易理解这个漏洞。



  蓝色部分就是我们构造的非法数据,在抛出异常的时候,本来只应该返回蓝色部分的数据。但是jetty继续往下读,会读到绿色部分的16个字节,然后后面以“...”省略,再读取最后的16个字节。

这样,只要构造特定长度的蓝色部分,就可以将黄色部分的数据全部读出返回。

修复:

官方已经发布了修复代码。https://github.com/eclipse/jetty.project/commit/4df5647f6dfdc5fa7abb812afe9290d60b17c098

我们可以看到,修复方式也是非常简单的。

for (int i = buffer.position(); i < buffer.limit(); i++)
            {
                appendContentChar(buf,buffer.get(i));
                if (i == buffer.position() + 16 && buffer.limit() > buffer.position() + 32)
                {
                    buf.append("...");
                    i = buffer.limit() - 16;
                }
            }
            buf.append(">>>\"");
            
            // ignore content beyond limit()
                        return buf.toString();
ignore content beyond limit()

    这样就不回显后面的数据了,一切都恢复了平静。  

          

猜你喜欢

转载自dingody.iteye.com/blog/2187676