[CVE-2012-1876] Internet Explorer堆溢出漏洞分析

 0x0漏洞分析
 1.开启页堆调试,!gflag +hpa,由于IE8会产生子进程,所以.childdbg 1开启子进程调试
  1.1运行poc
Windbg导入mshtml模块的符号文件
1:020> .reload /f mshtml.dll
1:020> lm
  1.2中断后,栈回溯下,产生问题的函数为mshtml!CTableLayout::CalculateMinMax

Eax的值是从[ebp+10h]传过来的,[ebp+10h]是从[eax+0ch]传过来的,这里猜测[eax+0ch]里的eax是一个对象

2.分析下mshtml!CTableLayout::CalculateMinMax这个函数
      2.1 sxe ld:mshtml 加载mshtml模块时断下,再下断点
其中[ebp-90h]pocspan元素的值


mshtml!CTableLayout::CalculateMinMax分析大概






3.进入mshtml!CImplAry::EnsureSizeWorker函数分析
大概就是根据 传进来的span元素*0x1c 后得到结果 进行内存分配,分配成功保存的地址为edi+0ch,edi是从html!CTableLayout::CalculateMinMax函数传进来的:edi = [ebx+90h],  ebxCTableLayout:对象
分配成功的地址:2cb408

mshtml!CImplAry::EnsureSizeWorker分析大概


4.mshtml!CImplAry::EnsureSizeWorker函数返回后,继续单步跟,遇到mshtml!CTableCol::GetAAspan函数,第一次获取后,ebx对象如下

    mshtml!CTableCol::GetAAspan分析大概

   第一次执行完后mshtml!CTableColCalc::AdjustForCol后,分配的heap变化(esi = pHeapAddr

5.对GetAAspan下断
    g执行后,会中断2次,都是对span属性进行修改操作


6.第三次g后,将第2次断到mshtml!CTableLayout::CalculateMinMax,继续单步分析下
   查看下此时CTableLayout对象
 
单步执行到GetAAspan函数跟进,可以看出获取到的span已经更改为1000,通过eax传出

由于等于3e8,后面的跳转不会实现,接着 [ebp+nDenominator]被赋值3e8

得到width的值后乘以100

一直单步到CTableColCalc::AdjustForCol函数,基本可以知道溢出的原因了
   [ebp+nNum]为增加的次数,esipHeapAddr,每循环一次pHeapAddr增加0x1c,[ebp+nDenominator]为循环结束的判断条件



CTableColCalc::AdjustForCol函数里,也对pHeapAddr增加0x18,对增加后的值进行 赋值,分配的堆空间大小为0x70,经过不断的循环赋值操作后,最后会超过堆分配的内存,去改写堆内存以外的数据

每次填入的的数据为width*100width*100+4




0x01 exploit分析
  1.javascript释放内存的函数为jscript!JsCollectGarbage,先对该函数下断点,中断后清除该断点,查看下mshtml!CImplAry::EnsureSizeWorker函数


对其里面分配的内存函数下2条指令处下断点
bp 65ee34e4 ".if(poi(ebp-8) == 0xfc){.echo ok;db poi(esi) l 300;}.else{gc;}"
主要是断到分配0xfc大小的内存,打印堆块里面的数据
    





2.可能分配的位置不一定是,后面溢出操作的堆块,为了能断到操作的堆块
    根据exp中的改变span处代码(第一处)
    
改变span时,需要先获取span吧(CTableCol::GetAAspan(void)),那么可以在获取span,对返回值进行判断是否为190x13),是的话就断下.先禁止之前的断点
29F31F (偏移)  =>  cmp     eax, 3E8h
bp 65FAF31F ".if(eax == 0x13){.echo run ok;}.else{.echo error;gc;}"



断下后,对后面对产生漏洞的堆块操作,也下断点,禁止前面的断点
29F480 =>  add     [ebp+var_24], 1Ch
bp 65FAF480 "!heap -p -a esi;.echo;db esi l 200"
主要是获取堆块的信息,还有里面的数据


占用了“E”释放的内存


看下其他占用的“E”释放的内存


跑几下,对比下填充的数据



第一次溢出,最后会填充到“B”BSTR字符串)的长度值,通过读取字符串后,就会读取CButtonLayout虚表指针,泄露虚表地址,再通过虚表地址减(mshtml模块到虚表的偏移),就能得到mshtml模块的加载基址,从而绕过aslr,构造rop


3.第二次溢出
   根据exp中的改变span处代码(第二处)

bp 65FAF31F ".if(eax == 0x2c){.echo run ok;}.else{.echo error;gc;}"
然后禁止掉65FAF480 处的断点


启用刚刚禁止掉的断点,看下堆块地址也是刚刚的


直接查看溢出完后的堆块


第二次溢出主要覆盖CButtonLayout虚表指针为07070024,再通过HeapSpray,把shellcode喷射到调用虚函数的地址处,达到漏洞利用(具体参考《漏洞战争》)


总结:该漏洞的漏洞利用是非常巧妙的,绕过了ASLRDEP,分析该漏洞的漏洞利用,可以收获不少东西



评论

此博客中的热门博文

Opencart-v3-0-3-0 user changes password at csrf vulnerability

Charles 4.2.7 XML External Entity

Docker's latest version of privilege escalation vulnerability