Sun Java虚拟机畸形Gif文件处理堆溢出漏洞初步分析

    技术2022-05-11  94

    Sun Java虚拟机畸形Gif文件处理堆溢出漏洞初步分析 by jb绕脖 昨天晚上看到漏洞信息,于是开始整,一开始就觉得applet方面利用起来 应该比较有价值,于是我和云舒同学就往这个方向鼓捣了,我用我遗忘了 差不多的java知识整出了个简单的applet程序,用来下载并显示一个GIF 图片文件。 之后,我们便根据漏洞描述来构造GIF图片,开始理解为图片头部的宽度 和高度,后来云舒同学仔细看了下发现不是这样的,而是图片块,这个玩 意是GIF图片内部一个结构,于是我们开始琢磨GIF图片格式,云舒尝试手 工构造这个图片块的宽度,而我则开始写程序来构造,幸运的是云舒同学 很快找到了图片块宽度的地方,在UE里搜索2c,这个是图片块之间的分隔 字符,于是我们随便整了个图片,搜索2c,然后往后观察,如果后面8个字 节看起来依次很像是x,y,width,height这样的值的话,那说明找对地方了, 我们把width值改为0。 我们把图片和我的applet程序放到本地的http server下面,这里为什么要 放在http server下面是因为如果不这样做会因为权限问题,applet不能访 问本地资源。我的IE 7 with JVM 1.5.0_6成功的crash了,而云舒同学的 IE 7 with JVM 1.4.2_7 怎么也不能成功。另外测试了一台1.5.0的机器也 成功crash了,初步判断是版本的问题,我们构造的poc只能适用于1.5.0.x 系列。 晚上我回来一个人继续调试,crash基本都出现在jvm.dll的JVM_ArrayCopy 这个函数里,漏洞的具体形成的代码还没有分析到,但是连猜带蒙搞出了 个劣质的POC执行代码。调试时发现crash时eax指向堆内地址,之前看描述 也大致猜出是个堆溢出覆盖函数指针,于是我观察了下eax指向的内存,发 现有大量连续的0x01,我怀疑0x01就是堆溢出覆盖的结果,于是往宽度后 面找,果然找到了个0x01的值,我试着修改了看看,结果还真蒙对了,这 个值最终在堆里面形成覆盖,并且由于在JVM_ArrayCopy函数里的一些运算 使得ecx和edi寄存器可以控制,最终call一个edi计算得到的地址,于是才 有了这个POC。 JVM_ArrayCopy里代码片断: .text:6D709EFA                 mov     eax, [eax]    ; eax存放被覆盖的堆内存的地址 .text:6D709EFC                 push    edi .text:6D709EFD                 push    esi .text:6D709EFE                 push    [ebp+arg_18] .text:6D709F01                 mov     ecx, [eax+4]    ; ecx得到覆盖的内容,可以通过上面提到的那个值控制 .text:6D709F04                 add     ecx, 8 .text:6D709F07                 push    [ebp+arg_14] .text:6D709F0A                 mov     edi, [ecx]    ; edi值是取得ecx作为地址指向的值,因为ecx可控制,所以edi同样可以控制 .text:6D709F0C                 push    dword ptr [edx] .text:6D709F0E                 push    [ebp+arg_C] .text:6D709F11                 push    eax .text:6D709F12                 call    dword ptr [edi+24h] ; 调用edi+24h,edi可控制,这里就可以用来执行我的代码 这里看明白了,你肯定第一个想起的就是0x0x0x0x,里面存放的内容也是0x0x0x0x,又是Heap Spary,于是就整出这个没啥技术含量的POC,在我机器上测试了下IE 7和Firefox都可以成功,而且成功率较高,这个漏洞主要是出在jvm,所以应该是浏览器无关的,只要支持applet,都会受影响,所以我觉得这个漏洞危害还是挺大的。 3.GIF里偏移19B处就是宽度值,被我们设置为0,3.GIF里偏移1A3处就是我用来控制寄存器的值,这里我填的05,当然你也可以填0c,0d,Heap还是利用javascript的方式来分配的 POC地址:暂时去掉 (如果成功的话浏览器会挂掉,然后你的任务管理器里发现多一个~.exe的进程,是一个NOTEPAD.EXE,从 http://icylife.net/1.exe下载,这些因为时间问题直接拷贝的别人的硬编码的shellcode) 代码:暂时去掉 (你要在本地测试这个代码的话,要搭建个http server的环境,把poc.html 3.gif和Test.class放到一个目录里,然后修改html代码里的applet的img_src属性,指名图片的绝对路径,注意图片要和html的url在一个域下面,要不然由于跨域的安全问题会导致不能成功。) 之所以认为这个POC很没有技术含量,是因为我觉得还有几个有技术含量的事情值 得去做的: 1. 漏洞具体成因的代码分析,分析透了的话也许有更好的利用方式 2. 不要用外置的图片,直接在java程序里硬编码生成一个图片 3. 不要在javascript里的heap spary,而是利用java的特性,至少可以试试java里面 进行heap分配,分析分析java applet的内存结构的话,也许有更好的利用方式。 4. 搞定jvm 1.4.2系列的问题,如果不同版本利用方式有差异的话,可以考虑在java 里判断jvm的版本决定使用针对性的方式。 5. 不挂浏览器 最终的目的就是exp完全用一个java代码搞定,不需要额外的东西,除了一个html页用来放applet,等下面有空再深入整整看 

    最新回复(0)