Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Computer Security 資安實務: Windows Reversing [Dark Art]

229b1596ce57cd0935a2bacd410d87a0?s=47 adr
October 04, 2018
1.4k

Computer Security 資安實務: Windows Reversing [Dark Art]

台科資安實務 2018/10/05
直播連結: https://www.youtube.com/watch?v=cBAXClitYIQ

229b1596ce57cd0935a2bacd410d87a0?s=128

adr

October 04, 2018
Tweet

Transcript

  1. C0mput3r 5ecur!7y Windows ReversingDarkArt aaaddress1@chroot.org !1

  2. • Master degree at CSIE, NTUST • Security Researcher -

    chrO.ot, TDOHacker • Speaker - BlackHat, DEFCON, beVX, VXCON, HITCON >_cat ./Bio !2
  3. • General Compiler • Recap: Intel x86 Basic • x86

    Instruction Set • x86 Calling Convention • Let's Mess Up IDA Pro ;) • Obfuscation Tricks • Junk Instructions • Control Flow Obfuscation • Structured Exception Handling (SEH) • Virtual Machine (Packer Style) >_cat ./lab !3
  4. aaaddress1@chroot.org General Compiler !4

  5. General Compiler !5 Source.cpp Object Files Main.exe Compiler Assembly Codes

    Assembler Linker
  6. >_cat msgbox.c !6 #include <Windows.h> int main() { MessageBoxA( 0,

    "hi there.", "info", 0 ); return 0; }
  7. based on x86 Calling Convention !7 #include <Windows.h> int main(void)

    { MessageBoxA( 0, "hi there.", "info", 0 ); return 0; } push 0 push "info" push "hi there." push 0 call MessageBoxA xor eax, eax ret en.wikipedia.org/wiki/X86_calling_conventions
  8. >_Compiler 8 xor eax, eax ret push 0 push "info"

    push "hi there." push 0 call MessageBoxA 0xdead: "info" 0xbeef: "hi there." .rdata section 0xcafe: 0x7630EA99 .idata section (Import Address Table)
  9. >_Compiler !9 xor eax, eax ret push 0 push offset

    "info" push offset "hi there." push 0 call MessageBoxA 0xdead: "info" 0xbeef: "hi there." .rdata section 0xcafe: 0x7630EA99 .idata section (Import Address Table)
  10. >_Compiler !10 xor eax, eax ret push 0 push 0x40dead

    push 0x40beef push 0 call ds:0x40cafe 0xdead: "info" 0xbeef: "hi there." .rdata section 0xcafe: 0x7630EA99 .idata section (Import Address Table)
  11. aaaddress1@chroot.org >_Periodic Table? !11 sparksandflames.com/files/x86InstructionChart.html

  12. >_Assembler push 0 ; 6A 00 push 0x40dead ; 68

    AD DE 40 00 push 0x40beef ; 68 EF BE 40 00 push 0 ; 6A 00 call ds:0x40cafe ; FF 15 FE CA 00 00 xor eax, eax ; 33 C0 ret ; C3 !12
  13. !13 Main.exe .text Section 6A 00 68 AD DE 00

    00 68 EF BE 00 00 6A 00 FF 15 FE CA 00 00 33 C0 C3 0xdead: "info" 0xbeef: "hi there." 0xcafe: 0x7630EA99 .rdata Section .idata Section
  14. aaaddress1@chroot.org Address Space Layout Randomization !14

  15. >_Memory Process iexplorer.exe ntdll.dll kernel32.dll ... Low Address custom.dll xxxxxx.dll

    module.dll High Address Thread Stack
  16. >_Memory Process iexplorer.exe ntdll.dll kernel32.dll ... Low Address custom.dll xxxxxx.dll

    module.dll High Address *.exe file should be loaded at 0x400000 by default third-party *.dll file System Modules Thread Stack
  17. >_ASLR Process iexplorer.exe ntdll.dll kernel32.dll ... custom.dll xxxxxx.dll module.dll Process

    iexplorer.exe ntdll.dll kernel32.dll ... custom.dll xxxxxx.dll module.dll Process iexplorer.exe ntdll.dll kernel32.dll ... custom.dll xxxxxx.dll module.dll third-party *.exe & *.dll files are loaded at different addresses when create process. System Modules are only randomized after reboot.
  18. !18 Main.exe .text Section 6A 00 68 AD DE 40

    00 68 EF BE 40 00 6A 00 FF 15 FE CA 40 00 33 C0 C3 0xdead: "info" 0xbeef: "hi there." 0xcafe: 0x7630EA99 .rdata Section .idata Section >_Issue I don't know how to randomize *.exe module address :(
  19. !19 Main.exe .text Section 6A 00 68 AD DE 40

    00 68 EF BE 40 00 6A 00 FF 15 FE CA 40 00 33 C0 C3 0xdead: "info" 0xbeef: "hi there." 0xcafe: 0x7630EA99 .rdata Section .idata Section Relocation Table (aka PIE)
  20. >_Relocation • Process loader won't implement ASLR on *.exe module

    without relocation table, even if you enable the ASLR option on the *.exe file. • There're serval relocation blocks stored the offset of assembly codes which includes resource, global variable, data from the other section. • In the .text section, every 0x1000 bytes of assembly code are grouped into a relocation block. All the relocation blocks are grouped into a relocation table. !20
  21. >_PE Bear !21

  22. >_PE Bear !22

  23. aaaddress1@chroot.org Recap: x86 Assembly !23

  24. aaaddress1@chroot.org >_Periodic Table? !24 sparksandflames.com/files/x86InstructionChart.html

  25. 雅量量 x86 指令集是⼀一種很有雅量量的語⾔言 !25 ⼈人總會去尋求⾃自⼰己喜歡的事物,每個⼈人的看法或觀點不同, 並沒有什什麼關係,重要的是──⼈人與⼈人之間,應該有彼此容忍 和尊重對⽅方的看法與觀點的雅量量。

  26. >_CISC !26 Bytecodes on .text section 35 FF 15 FE

    CA 40 00 0: 35 ff 15 fe ca - xor eax,0xcafe15ff 5: 40 - inc eax
  27. 0: ff 15 fe ca 40 00 - call DWORD

    PTR ds:0x40cafe !27 Bytecodes on .text section 35 FF 15 FE CA 40 00 0: 35 ff 15 fe ca - xor eax,0xcafe15ff 5: 40 - inc eax >_CISC
  28. 0: ff 15 fe ca 40 00 - call DWORD

    PTR ds:0x40cafe !28 Bytecodes on .text section 35 FF 15 FE CA 40 00 0: 35 ff 15 fe ca - xor eax,0xcafe15ff 5: 40 - inc eax 0: 15 fe ca 40 00 adc eax,0x40cafe >_CISC
  29. 0: ff 15 fe ca 40 00 - call DWORD

    PTR ds:0x40cafe !29 Bytecodes on .text section 35 FF 15 FE CA 40 00 0: 35 ff 15 fe ca - xor eax,0xcafe15ff 5: 40 - inc eax 0: 15 fe ca 40 00 adc eax,0x40cafe >_CISC ROP-Chain
  30. >_Thread !30 addr @ 401000: 6A 00 68 AD DE

    40 00 68 EF BE 40 00 6A 00 FF 15 FE CA 40 00 33 C0 C3 push 0 push 0x40dead push 0x40beef push 0 call ds:0x40cafe xor eax, eax ret via x86 Instruction Set Registers eax 41414141 ebx 42424242 ecx 43434343 edx 44444444 ... ... esp 7ffffffc ebp 7ffffffc eip 401000
  31. >_Thread !31 addr @ 401000: 6A 00 68 AD DE

    40 00 68 EF BE 40 00 6A 00 FF 15 FE CA 40 00 33 C0 C3 push 0 push 0x40dead push 0x40beef push 0 call ds:0x40cafe xor eax, eax ret via x86 Instruction Set Registers eax 41414141 ebx 42424242 ecx 43434343 edx 44444444 ... ... esp 7ffffffc ebp 7ffffffc eip 401000 Process aaaaaaaaa.exe ntdll.dll kernel32.dll ... Low Address custom.dll xxxxxx.dll module.dll High Address Thread Stack
  32. >_Heap uint32_t buf[3] = { 1, 2, 3 }; buf[1]

    = 0xAAAAAAAA; buf[2] = 0x12345678; !32 Low Address = 0x100 (buf) High Address &(buf[0]) = 0x100 buf[0] = 1 00 00 00 01 &(buf[1]) = 0x104 buf[1] = 0xAAAAAAAA AA AA AA AA &(buf[2]) = 0x108 buf[2] = 0x12345678 78 56 34 12
  33. >_Stack uint32_t stack[100]; uint32_t index = 99; void x86_push(uint32_t in)

    { stack[--index] = in; } void x86_pop(&out) { x = stack[index++]; } !33 Low Address = 0x100 (stack) High Address esp = 0x100 + sizeof(uint32_t) * 99 Allocate Local Memory Release Local Memory
  34. >_Stack push eax push ebx pop edx !34 Low Address

    = 0x100 (stack) High Address eax 1 ebx 2 edx 3 esp = 0x28c index = 99
  35. >_Stack push eax push ebx pop edx !35 Low Address

    = 0x100 (stack) High Address eax 1 ebx 2 edx 3 00 00 00 01 esp = 0x288 index = 98 esp = 0x28c index = 99
  36. >_Stack push eax push ebx pop edx !36 Low Address

    = 0x100 (stack) High Address eax 1 ebx 2 edx 3 00 00 00 01 esp = 0x288 index = 98 esp = 0x28c index = 99 00 00 00 02 esp = 0x284 index = 97
  37. >_Stack push eax push ebx pop edx !37 Low Address

    = 0x100 (stack) High Address eax 1 ebx 2 edx 2 00 00 00 01 esp = 0x288 index = 98 esp = 0x28c index = 99 00 00 00 02 esp = 0x284 index = 97
  38. aaaddress1@chroot.org x86 Calling Convention !38

  39. >_Calling Convention !39 en.wikipedia.org/wiki/X86_calling_conventions add: push ebp mov ebp, esp

    sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret
  40. >_Calling Convention !40 en.wikipedia.org/wiki/X86_calling_conventions add: push ebp mov ebp, esp

    sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret The Begin of function The end of function
  41. >_Function !41 Low Address = 0x100 (stack) High Address esp

    = 0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3)
  42. !42 Low Address = 0x100 (stack) High Address esp =

    0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) 00 00 00 03 esp = 0x288 index = 98
  43. !43 Low Address = 0x100 (stack) High Address esp =

    0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) 00 00 00 03 esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97
  44. !44 Low Address = 0x100 (stack) High Address esp =

    0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) 00 00 00 03 esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96
  45. !45 Low Address = 0x100 (stack) High Address esp =

    0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96 ret addr esp = 0x27c index = 95 00 00 00 03
  46. !46 Low Address = 0x100 (stack) High Address esp =

    0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96 ret addr esp = 0x27c index = 95 old ebp esp = 0x278 index = 94 00 00 00 03
  47. !47 Low Address = 0x100 (stack) High Address esp =

    0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96 ret addr esp = 0x27c index = 95 old ebp esp = 0x278 index = 94 ebp = 0x278 (the base pointer for the current stack frame) 00 00 00 03
  48. !48 Low Address = 0x100 (stack) High Address esp =

    0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96 ret addr esp = 0x27c index = 95 old ebp esp = 0x278 index = 94 ebp = 0x278 (the base pointer for the current stack frame) local buf esp = 0x274 index = 93 00 00 00 03
  49. !49 Low Address = 0x100 (stack) High Address esp =

    0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96 ret addr esp = 0x27c index = 95 old ebp esp = 0x278 index = 94 ebp = 0x278 (the base pointer for the current stack frame) local buf esp = 0x274 index = 93 ebp ebp+4 arg1: ebp+8 arg2: ebp+0x0c arg3: ebp+0x10 00 00 00 03
  50. !50 Low Address = 0x100 (stack) High Address esp =

    0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96 ret addr esp = 0x27c index = 95 old ebp esp = 0x278 index = 94 ebp = 0x278 (the base pointer for the current stack frame) local buf esp = 0x274 index = 93 ebp ebp+4 arg1: ebp+8 arg2: ebp+0x0c arg3: ebp+0x10 00 00 00 03
  51. !51 Low Address = 0x100 (stack) High Address esp =

    0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96 ret addr esp = 0x27c index = 95 old ebp esp = 0x278 index = 94 ebp = 0x278 (the base pointer for the current stack frame) 6 esp = 0x274 index = 93 ebp ebp+4 arg1: ebp+8 arg2: ebp+0x0c arg3: ebp+0x10 00 00 00 03
  52. !52 Low Address = 0x100 (stack) High Address esp =

    0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96 ret addr esp = 0x27c index = 95 old ebp esp = 0x278 index = 94 ebp = 0x278 (the base pointer for the current stack frame) 6 ebp ebp+4 arg1: ebp+8 arg2: ebp+0x0c arg3: ebp+0x10 00 00 00 03
  53. !53 Low Address = 0x100 (stack) High Address esp =

    0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96 ret addr esp = 0x27c index = 95 old ebp 6 ebp ebp+4 arg1: ebp+8 arg2: ebp+0x0c arg3: ebp+0x10 00 00 00 03
  54. !54 Low Address = 0x100 (stack) High Address esp =

    0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) esp = 0x288 index = 98 00 00 00 02 esp = 0x284 index = 97 00 00 00 01 esp = 0x280 index = 96 ret addr old ebp 6 ebp ebp+4 arg1: ebp+8 arg2: ebp+0x0c arg3: ebp+0x10 00 00 00 03
  55. !55 Low Address = 0x100 (stack) High Address esp =

    0x28c index = 99 add: push ebp mov ebp, esp sub esp, 0x04 mov eax, [ebp+0x08] add eax, [ebp+0x0C] add eax, [ebp+0x10] mov [ebp-0x04], eax mov eax, [ebp-0x04] mov esp, ebp pop ebp ret push 3 push 2 push 1 call add add esp,0x0c // add(1, 2, 3) 00 00 00 03 00 00 00 02 00 00 00 01 ret addr old ebp 6 ebp ebp+4 arg1: ebp+8 arg2: ebp+0x0c arg3: ebp+0x10
  56. aaaddress1@chroot.org Structured Exception Handling (SEH) !56

  57. Structured exception handling enables you to have complete control over

    the handling of exceptions, provides support for debuggers, and is usable across all programming languages and machines. Vectored exception handling is an extension to structured exception handling. >_SEH docs.microsoft.com/en-us/windows/desktop/debug/structured-exception-handling
  58. >_Visual C++ !58 Actually SEH is a feature to support

    try {} catch (...) {} and...
  59. !59

  60. >_Visual C++ !60

  61. aaaddress1@chroot.org Thread Information Block —— Break into how Win32 API

    works !61
  62. >_TIB In computing, the Win32 Thread Information Block (TIB) is

    a data structure in Win32 on x86 that stores information about the currently running thread. This structure is also known as the Thread Environment Block (TEB). The TIB can be used to get a lot of information on the process without calling Win32 API. Examples include emulating GetLastError(), GetVersion(). Through the pointer to the PEB one can obtain access to the import tables (IAT), process startup arguments, image name, etc. It is accessed from the FS segment register when operating on 32 bits, and from GS in 64 bits. !62 en.wikipedia.org/wiki/Win32_Thread_Information_Block
  63. >_TIB !63

  64. aaaddress1@chroot.org >_TIB (undocumented) !64 struct TEB { //NT_TIB structure portion

    EXCEPTION_REGISTRATION* ExceptionList; //0x0000 / Current Structured Exception Handling frame void* StackBase; //0x0004 / Bottom of stack (high address) void* StackLimit; //0x0008 / Ceiling of stack (low address) void* SubSystemTib; //0x000C union { void* FiberData; //0x0010 DWORD Version; //0x0010 } dword10; void* ArbitraryUserPointer; //0x0014 TEB* Self; //0x0018 //NT_TIB ends (NT subsystem independent part) void* EnvironmentPointer; //0x001C CLIENT_ID ClientId; //0x0020 // ClientId.ProcessId //0x0020 / value retrieved by GetCurrentProcessId() // ClientId.ThreadId //0x0024 / value retrieved by GetCurrentThreadId() void* ActiveRpcHandle; //0x0028 void* ThreadLocalStoragePointer; //0x002C PEB* ProcessEnvironmentBlock; //0x0030 ... bytepointer.com/resources/tebpeb32.htm
  65. aaaddress1@chroot.org >_TIB (undocumented) !65 struct TEB { //NT_TIB structure portion

    EXCEPTION_REGISTRATION* ExceptionList; //0x0000 / Current Structured Exception Handling frame void* StackBase; //0x0004 / Bottom of stack (high address) void* StackLimit; //0x0008 / Ceiling of stack (low address) void* SubSystemTib; //0x000C union { void* FiberData; //0x0010 DWORD Version; //0x0010 } dword10; void* ArbitraryUserPointer; //0x0014 TEB* Self; //0x0018 //NT_TIB ends (NT subsystem independent part) void* EnvironmentPointer; //0x001C CLIENT_ID ClientId; //0x0020 // ClientId.ProcessId //0x0020 / value retrieved by GetCurrentProcessId() // ClientId.ThreadId //0x0024 / value retrieved by GetCurrentThreadId() void* ActiveRpcHandle; //0x0028 void* ThreadLocalStoragePointer; //0x002C PEB* ProcessEnvironmentBlock; //0x0030 ... bytepointer.com/resources/tebpeb32.htm EXCEPTION_REGISTRATION* ExceptionList; //0x0000
  66. >_x64dbg !66 We can use the command "teb()" to fetch

    the current TEB table address.
  67. >_x64dbg !67 We can use the command "teb()" to fetch

    the current TEB table address. Point to handler-chain
  68. >_x64dbg !68 teb() = 0x5b0000

  69. >_SEH Record !69 Thread Exception TEB fs:[0] SEH Chain fs:[4]

    StackBase fs:[8] StackLimt fs:[c] SubSystem Handler 3 Callback Handler Ptr Prev Handler Handler 2 Callback Handler Ptr Prev Handler Handler 1 Callback Handler Ptr -1 (end)
  70. >_SEH !70

  71. >_SEH !71 push ebp mov ebp, esp push offset __ehhandler$_main

    push fs:[0] mov fs:[0], esp mov [0], 1 xor eax, eax mov ecx, [esp] mov large fs:0, ecx mov esp, ebp pop ebp retn Return value Function codes Register a handler Unregister a handler The begin of function The end of function
  72. >_Stack Frame !72 Low Address (stack) High Address ret addr

    old ebp ebp (current stack frame) SEH record esp ebp ebp+4 arg3 arg2 arg1 ebp+8 ebp+0x0c ebp+0x10 canery SEH record Previous SEH Record addr Current Handler buffer
  73. >_Buffer Overflow !73 Low Address (stack) High Address ret addr

    old ebp ebp (current stack frame) SEH record esp ebp ebp+4 arg3 arg2 arg1 ebp+8 ebp+0x0c ebp+0x10 canery SEH record Previous SEH Record addr Current Handler buffer
  74. >_Buffer Overflow !74 Low Address (stack) High Address ret addr

    old ebp ebp (current stack frame) SEH record esp ebp ebp+4 arg3 arg2 arg1 ebp+8 ebp+0x0c ebp+0x10 canery SEH record Previous SEH Record addr Current Handler buffer Buffer Overflow from low addr to high addr
  75. >_Buffer Overflow !75 Low Address (stack) High Address ret addr

    old ebp ebp (current stack frame) SEH record esp ebp ebp+4 arg3 arg2 arg1 ebp+8 ebp+0x0c ebp+0x10 canery SEH record Previous SEH Record addr Current Handler buffer Buffer Overflow from low addr to high addr buffer memory out of bounds
  76. aaaddress1@chroot.org Lab 1: Knock down the handler !76

  77. aaaddress1@chroot.org Th3 D4Rk Art: Anti-analysis Techniques D4Rk !77

  78. >_Anti-analysis • Most static analysis tools (e.g. IDA Pro, Snowman,

    Hopper, etc.) transform machine code to Control-Flow Graph or C-like pseudocode based on the x86 Calling Convention. !78
  79. >_Anti-analysis • Issues • Break Stack Frame • Junk Instructions

    • Relace Orignal Instructions • VM-like Protection • Abusing SEH !79
  80. aaaddress1@chroot.org Obfuscation Tricks !80

  81. >_Junk Instructions • nop • xchg eax, ebx; xchg ebx,

    eax • inc eax, dec eax; • lodsb, lodsw, lodsd • stosb, stosw, stosd • scasb • std, stc, sti • rdtsc • Just do nothing !81
  82. >_Junk Instructions !82 IDA Pseudocode

  83. >_Junk Instructions !83 IDA Pseudocode

  84. >_Replacing Codes • jmp xxx = push xxx; ret •

    call xxx = push retAddr; jmp xxx
 = push retAddr; push xxx; ret • mov eax, ebx = push ebx; pop eax • sub esp, 0x04 = lea esp, [esp-0x04] • push xxx = sub esp, 0x04; mov [esp], xxx
 = lea esp, [esp-0x04]; mov [esp], xxx ...etc !84
  85. Black Hat Asia 2018: BREAKING STATE-OF-THE-ART BINARY CODE OBFUSCATION VIA

    PROGRAM SYNTHESIS • https://www.blackhat.com/docs/asia-18/asia-18-Blazytko- Breaking-State-Of-The-Art-Binary-Code-Obfuscation-Via- Program-Synthesis.pdf • https://www.blackhat.com/docs/asia-18/asia-18-Blazytko- Breaking-State-Of-The-Art-Binary-Code-Obfuscation-Via- Program-Synthesis-wp.pdf >_Virtual Machines !85
  86. !86 >_Virtual Machines

  87. >_Virtual Machines !87

  88. !88 >_Virtual Machines

  89. !89 >_Virtual Machines

  90. • Call $+5; pop eax • push xx; push xx;

    call entry
 entry: add esp, 0x0c • push next; push xxxx; call [esp+0x04]; add esp, 0x08
 next: add esp, 0x0c • ret 0xff !90 >_Control Flow
  91. !91 >_Control Flow

  92. !92 >_Abusing SEH

  93. !93 >_Abusing SEH The SEH handler is always a lonely

    region.
  94. aaaddress1@chroot.org Lab 2: Obfuscation Challenge !94

  95. Thanks. aaaddress1@chroot.org Slide Github @aaaddress1 Facebook !95