堆溢出学习之CVE-2012-1876
diffway 漏洞分析 7321浏览 · 2017-08-15 23:33

1 分析环境

​ 操作系统:Window 7
​ 软件 :IE 8

2 基本信息

​ 漏洞类型:堆溢出

​ 影响范围: Microsoft Internet Explorer 6至9版本中存在漏洞

这个漏洞就是在Pwn2Own黑客大赛上用于攻破IE9的漏洞,我们一起来分析一下

​ POC MD5:97bff46c1f8ad00d05520b531aace884

我们打开页堆,打开IE8,用windbg附加上以后,将windbg设置成跟踪子进程(.childbg)后,我们可以看到发生异常,edi是页堆地址

我们首先看一下POC,我们确定了主要出问题的地方为col元素,通过js的over_trigger重置一些col的span和width元素的属性来触发漏洞

我们可以发现溢出点edi,来自上面的[esi+18h],而esi在函数内没有被操作,肯定来自上一层函数,上层函数从栈回溯中可以看出来是CalculateMinMax这个函数,我们断到这个函数

这个函数CalculateMinMax是处理col中的属性的,这个函数一共会被调用两次,第二次是在调用 js函数 over_trigger()时候,再次处理col中的属性

在第一次调用的时候,我们运行发现一个分配空间的函数,我们看看分配的空间

进去之后可以看到开辟了0x70字节的空间,我们老看看这0x70字节的空间是如何计算出来的

从上面可以看出来是从参数取出的0x1c乘以4然后分配的内存,我们在来看看为什么要分配这个内存

我们看到是在一个比较后才进行的分配的内存,我们分别看看这两个比较的值

我们向上追溯edx的值,可以看到程序的开始处将CTableLayout的对象取出,并取出CTableLayout对象偏移0x54的值,而这个值正式spannum 也就是POC中的span中的值

我们另一个比较数据是从CTableLayout 对象+0x90的位置这个是CImplPtrAry对象,而0x90 CImplPtrAry对象+8的位置是AllocCount(已经申请出来内存的可存放的指针数量),这里一个都没有申请所以去内存分配

我们来看一下申请的内存放到什么位置了,最后CTableLayout 对象+0x9c的位置上,也是CImplPtrAry对象+C的位置上指针数组

由于over_trigger函数更新col属性我们继续断到CalculateMinMax,来继续来看一下,可以看到这次并没有进行堆内存分配,而是在这里进行了跳过,因为ebx+94h,已经在上次分配内存的时候变成了4,而导致比较的时候没有跳过

我们在这里看下在上次分配完内存后,对CTableLayout 对象+0x94的地方进行了把span取出并乘以4,放入ebx+94h

而我们知道我们已经在over_trigger函数中将span的值设置为1000了,我们向下执行,看到了CTableCol::GetAAspan函数来获取span数值,可以看到span数值最大能为1000,

在将span数值拿到后,将进行一个堆空间利用循环1000次每次利用1ch个字节

而这个堆空间正是CTableLayout 对象+0x9c,而这个堆空间只分配了0x70字节的空间,导致溢出。

我们在来看看拷贝的字节拷贝的字节跟width属性有关,是通过CWidthUnitValue::GetPixelWidth这个函数取出的


知道了怎么溢出的,我们看看怎么才可以进行利用,我们先看看整个利用对堆的控制,可以看到先分配250次的100个字节的E和100个字节的A和100个字节的B,最后在后面分配一个Button对象,并将E释放掉,来让分配的占用到这个堆中

我们断到CTableLayout::CalculateMinMax,然后执行到分配内存的地方,我们知道分配的内存在ebx+9C的地方,可以看到整个堆空间的情况

我们看到分配的下面的A和B和B下面的BUTTON对象

之后便对构造的堆进行第一次溢出,这次溢出主要是覆盖到B字符串的大小,这样在覆盖之后,B字符串大小变大,实现内存泄漏,这样就可以读取Button对象的虚函数地址

由于对象的虚函数地址和基地址相差一段固定的距离,所有我们能取得mshtml的基地址,这样我们就可以绕过ASLR

我们在通过基地址构造ROP绕过 DEP

最后通过再一次溢出,覆盖Button的虚函数地址,并实现堆喷,实现控制EIP

0 条评论
某人
表情
可输入 255