bypassing different defense schemes via crash resistant
play

Bypassing Different Defense Schemes via Crash-Resistant Probing of - PowerPoint PPT Presentation

Bypassing Different Defense Schemes via Crash-Resistant Probing of Address Space Robert Gawlik Ruhr University Bochum Horst Grtz Institute for IT-Security Bochum, Germany About me Playing with InfoSec since 2010 Currently in academia


  1. Bypassing Different Defense Schemes via Crash-Resistant Probing of Address Space Robert Gawlik Ruhr University Bochum Horst Görtz Institute for IT-Security Bochum, Germany

  2. About me • Playing with InfoSec since 2010 • Currently in academia at Systems Security Group @ Horst Görtz Institute / Ruhr University Bochum • Focusing on binary analysis / attacks / defenses / static and dynamic analysis • Little time for bug hunting and exploiting • Fun fact: Recently discovered favorite toy: DynamoRIO CanSecWest 2016

  3. Agenda • Crash-Resistance • Crash-Resistance in IE 32-bit (CVE 2015-6161) • Memory Scanning : Bypass ASLR • Export Resolving : Bypass EMET's EAF+ • Function Chaining : Bypass Control Flow Guard & EMET's UNC library path restriction • Crash-Tolerant Function Dispatching : Fun ! • Mitigations/Fixes CanSecWest 2016

  4. Crash-Resistance

  5. Crash-Resistance char* addr = 0; void crash(){ addr++; printf("reading %x", addr); char content = *(addr); printf("read done"); } int main(){ MSG msg; SetTimer(0, 0, 1, crash); while (1){ GetMessage(&msg, NULL, 0, 0); DispatchMessage(&msg); } } CanSecWest 2016

  6. Crash-Resistance char* addr = 0; • Set timer callback crash() void crash(){ addr++; printf("reading %x", addr); char content = *(addr); printf("read done"); } int main(){ MSG msg; SetTimer(0, 0, 1, crash); while (1){ GetMessage(&msg, NULL, 0, 0); DispatchMessage(&msg); } } CanSecWest 2016

  7. Crash-Resistance char* addr = 0; • Set timer callback crash() void crash(){ • Dispatch crash() each ms addr++; printf("reading %x", addr); char content = *(addr); printf("read done"); } int main(){ MSG msg; SetTimer(0, 0, 1, crash); while (1){ GetMessage(&msg, NULL, 0, 0); DispatchMessage(&msg); } } CanSecWest 2016

  8. Crash-Resistance char* addr = 0; • Set timer callback crash() void crash(){ • Dispatch crash() each ms addr++; printf("reading %x", addr); • crash() generates a fault on char content = *(addr); first execution printf("read done"); } int main(){ MSG msg; SetTimer(0, 0, 1, crash); while (1){ GetMessage(&msg, NULL, 0, 0); DispatchMessage(&msg); } } CanSecWest 2016

  9. Crash-Resistance char* addr = 0; • Set timer callback crash() void crash(){ • Dispatch crash() each ms addr++; printf("reading %x", addr); • crash() generates a fault on char content = *(addr); first execution printf("read done"); } Program should int main(){ MSG msg; terminate abnormally SetTimer(0, 0, 1, crash); while (1){ GetMessage(&msg, NULL, 0, 0); DispatchMessage(&msg); } } CanSecWest 2016

  10. Crash-Resistance CanSecWest 2016

  11. Crash-Resistance char* addr = 0; • Set timer callback crash() void crash(){ • Dispatch crash() each ms addr++; printf("reading %x", addr); • crash() generates a fault on char content = *(addr); first execution printf("read done"); } Instead: int main(){ MSG msg; Program runs endlessly SetTimer(0, 0, 1, crash); while (1){ GetMessage(&msg, NULL, 0, 0); DispatchMessage(&msg); } } CanSecWest 2016

  12. Crash-Resistance char* addr = 0; • Set timer callback crash() void crash(){ • Dispatch crash() each ms addr++; printf("reading %x", addr); • crash() generates a fault on char content = *(addr); first execution printf("read done"); } int main(){ MSG msg; SetTimer(0, 0, 1, crash); while (1){ GetMessage(&msg, NULL, 0, 0); DispatchMessage(&msg); } } CanSecWest 2016

  13. Crash-Resistance 0:000:x86> g (370.e4): Access violation - code c0000005 (first chance) crash_resistance!crash+0x2d: 009b104d 8a02 mov al,byte ptr [edx] ds:002b:00000001=?? 0:000:x86> gn (370.e4): Access violation - code c0000005 (first chance) crash_resistance!crash+0x2d: 009b104d 8a02 mov al,byte ptr [edx] ds:002b:00000002=?? 0:000:x86> !exchain [...] 0057f800: USER32!_except_handler4+0 CRT scope 0, filter: USER32!DispatchMessageWorker+36882 func: USER32!DispatchMessageWorker+36895 CanSecWest 2016

  14. Crash-Resistance 0:000:x86> g (370.e4): Access violation - code c0000005 (first chance) crash_resistance!crash+0x2d: 009b104d 8a02 mov al,byte ptr [edx] ds:002b:00000001=?? pass exception unhandled 0:000:x86> gn (370.e4): Access violation - code c0000005 (first chance) crash_resistance!crash+0x2d: 009b104d 8a02 mov al,byte ptr [edx] ds:002b:00000002=?? 0:000:x86> !exchain [...] 0057f800: USER32!_except_handler4+0 CRT scope 0, filter: USER32!DispatchMessageWorker+36882 func: USER32!DispatchMessageWorker+36895 CanSecWest 2016

  15. Crash-Resistance Behind the Scenes (Simplified) char* addr = 0; DispatchMessage: void crash(){ __try addr++; { printf("reading %x", addr); crash() char content = *(addr); access violation } printf("read done"); __except( filter ) } filter returns 1 { int main(){ execute handler MSG msg; } SetTimer(0, 0, 1, crash); continue execution while (1){ return GetMessage(&msg, NULL, 0, 0); DispatchMessage(&msg); } } CanSecWest 2016

  16. Crash-Resistance Behind the Scenes (Simplified) char* addr = 0; DispatchMessage: void crash(){ __try addr++; { printf("reading %x", addr); crash() char content = *(addr); } printf("read done"); __except( filter ) } { int main(){ MSG msg; } SetTimer(0, 0, 1, crash); while (1){ return GetMessage(&msg, NULL, 0, 0); DispatchMessage(&msg); } } CanSecWest 2016

  17. Crash-Resistance Behind the Scenes (Simplified) char* addr = 0; void crash(){ addr++; printf("reading %x", addr); If a fault is generated, char content = *(addr); execution is printf("read done"); transferred to the end } of the loop int main(){ MSG msg; SetTimer(0, 0, 1, crash); Program continues while (1){ running despite GetMessage(&msg, NULL, 0, 0); producing faults DispatchMessage(&msg); } } CanSecWest 2016

  18. Crash-Resistance Behind the Scenes (Simplified) char* addr = 0; void crash(){ addr++; printf("reading %x", addr); If a fault is generated, char content = *(addr); execution is printf("read done"); transferred to the end } of the loop int main(){ MSG msg; SetTimer(0, 0, 1, crash); Program continues while (1){ running despite GetMessage(&msg, NULL, 0, 0); producing faults DispatchMessage(&msg); } } CanSecWest 2016

  19. Crash-Resistance DEMO 1 CanSecWest 2016

  20. Crash-Resistance • Similar issues: - ”Why it's not crashing ?” [1] - ANI Vulnerability (CVE 2007-0038) [2] - ”Escaping VMware Workstation through COM1” (JPEG2000 parsing) [3] - ”The Art of Leaks” (exploit reliability) [4] CanSecWest 2016

  21. Crash-Resistance in Internet Explorer 11

  22. Crash-Resistance in IE 11 JS callback() set with setInterval() or setTimeout() in web worker is crash-resistant: • Start worker • Launch timed callback() with setInterval() • callback() function may produce access violations without forcing IE into termination (a) : if an AV is triggered in callback() , then callback() stops running and is executed anew (b) : if callback() produces no fault, it is executed completely and then started anew → usable as side channel CanSecWest 2016

  23. Crashless Memory Scanning in Internet Explorer 11

  24. Memory Scanning The Plan: • Spray the heap • Use vulnerabilty to change a byte → Create a type confusion and craft fake JS objects • Utilize fake objects in web worker with setInterval() to scan memory in a crash-resistant way → Discover Thread Environment Block (TEB) → Discover DLL Base Addresses • Don't control EIP yet – instead: use only JS → bypass ASLR CanSecWest 2016

  25. Memory Scanning Spray the heap • Alternate between Object Arrays and Integer Arrays • Object Arrays become aligned to 0xYYYY0000 • Integer Arrays become aligned to +f000 +f400 +f800 +fc00 → Object Array: ObjArr[0] = new String() // saved as reference; bit 0 never set ObjArr[1] = 4 // integer saved as 9 = 4 << 1 | 1 → Integer Array: IntArr[0] = 4 // saved as 4 CanSecWest 2016

  26. Memory Scanning Spray the heap ObjArr[0] = 0x808f880 // saved as 0x808f880 << 1 | 1 = 0x1011f101 ObjArr[1] = new Uint32Array() // saved as reference 0x100ff1b0 0:036> dd 10110000 L0x0c 0:036> dd 10110000 L0x0c 10110000 00000000 0000eff0 00000000 00000000 10110000 00000000 0000eff0 00000000 00000000 10110010 00000000 000000fc 00003bf8 00000000 10110010 00000000 000000fc 00003bf8 00000000 10110020 1011f101 100ff1b0 80000002 80000002 10110020 1011f101 100ff1b0 80000002 80000002 0:036> dds 100ff1b0 L1 0:036> dds 100ff1b0 L1 100ff1b0 7193803c jscript9!Js::TypedArray<unsigned int,0>::`vftable' 100ff1b0 7193803c jscript9!Js::TypedArray<unsigned int,0>::`vftable' CanSecWest 2016

Recommend


More recommend