BinRec: Attack Surface Reduction Through Dynamic Binary Recovery Taddeus Kroes, Anil Altinay, Joseph Nash, Yeoul Na, Stijn Volckaert, Herbert Bos, Michael Franz, Cristiano Giuffrida October 19, 2018
Attack Surface Reduction x = getenv(“SET_ME”); if (x) cold_code(); hot_code(); 2
Attack Surface Reduction x = getenv(“SET_ME”); if (x) Buggy features cold_code(); hot_code(); ROP gadgets 3
Attack Surface Reduction x = getenv(“SET_ME”); if (x) Remove unwanted features cold_code(); hot_code(); d e c u d e r e a c r f u s k c a t A t e d o c d e s t e t l - e l w o t 4
Attack Surface Reduction setme_str: .asciz: “SET_ME” push setme_str call getenv Want to work on cmp eax, 0 COTS binaries je main call cold_code main: call hot_code 5
Static approach Input Transformed Transform binary binary 6
Static approach Input Transformed Transform binary binary i n c o m p l e t e d i s a s s e m b l y PIC? obfuscated? 7
Static approach w contains cold h i c h c o d e i s code r e a c h e d ? Input Transformed Transform binary binary i n c o m p l e t e d i s a s s e m b l y PIC? obfuscated? 8
Dynamic approach by BinRec e s c i r e p y b l m e s s a s d i Input Transformed Execute Transform binary binary only hot code 9
Dynamic approach by BinRec Recovery Input Recovered Execute Transform binary binary 10
Dynamic approach by BinRec Recovery Input Recovered Execute Transform binary binary can we make this more generic? 11
BinRec goal: complex binary transformation many applications Attack Surface Reduction / Binary rejuvenation / Input Recovered Execute binary Profile-guided binary optimization / (De)obfuscation / ISA retargeting 12
BinRec goal: complex binary transformation many applications Attack Surface Reduction / Binary rejuvenation / Input Recovered Execute binary Profile-guided binary optimization / (De)obfuscation / ISA retargeting s e r u i q e r l e v e l - h g i h ! e d o c 13
BinRec design Compiler IR Transform Machine Code Input Recovered Execute binary binary 14
BinRec design Compiler IR Transform Lift Lower Machine Code Input Recovered Execute binary binary 15
BinRec design Compiler IR Transform Lift Lower Machine Code Input Recovered Execute binary binary Sometimes we want more code coverage than a single code path 16
BinRec design Compiler IR Transform Lift Lower Machine Code Input Symbolic Recovered binary execution binary Run with “symbolic” input and follow both sides of a branch 17
BinRec design Compiler IR Transform Lift Lower Machine Code Input Symbolic Recovered binary execution binary Want to support multiple architectures Need to observe each instruction 18
BinRec design Compiler IR Transform Lift in VM Lower Machine Code Input Symbolic Recovered binary execution binary , V M i n t e u l a E m I R t o n s c t i o r u n s t e i s l a t a n t r 19
BinRec design Compiler IR Transform Lift in VM Lower Machine Code Input Symbolic Recovered binary execution binary 20
BinRec design Compiler IR Transform Lift in VM Compile Machine Code Input Symbolic Recovered binary execution binary J u s t u s e t h e c o m p i l e r 21
BinRec design Compiler IR Transform Lift in VM Compile Machine Code Input Symbolic Recovered binary execution binary 22
BinRec design Compiler IR Transform Lift in VM Compile Machine Code Input Symbolic Recovered binary execution binary What about unlifted code paths? ... if (getenv(“SET_ME”)) { puts(“thanks!”); // not recovered! } ... 23
BinRec design Compiler IR Transform Lift in VM Compile Machine Code Input Symbolic Recovered binary execution binary What about unlifted code paths? 1. do nothing (breaks conservative behavior) ... getenv(“SET_ME”); ... 24
BinRec design Compiler IR Transform Add errors Lift in VM Compile Machine Code Input Symbolic Recovered binary execution binary What about unlifted code paths? 2. yield error ... if (getenv(“SET_ME”)) { abort(); } ... 25
BinRec design Compiler IR Transform Add errors / fallbacks Lift in VM Compile Machine Code Input Symbolic Recovered binary execution binary What about unlifted code paths? 3. fallback to old code ... if (getenv(“SET_ME”)) { goto old_code_address; } ... 26
BinRec design Compiler IR Transform Add errors / fallbacks Lift in VM Compile Machine Code Input Symbolic Recovered binary execution binary R e f e r e n c e s d a t a f r o m i n p u t b i n a r y 27
BinRec design Compiler IR Transform Add errors / fallbacks Lift in VM Compile Machine Code Link data sections Input Symbolic Recovered binary execution binary 28
BinRec design Compiler IR Transform Add errors / fallbacks Lift in VM Compile Machine Code Link data sections Input Symbolic Recovered binary execution binary IR interacts with VM runtime 29
BinRec design Compiler IR Transform Add errors / fallbacks Lift in VM Compile Machine Code Link data sections Input Symbolic Recovered binary execution binary IR interacts with VM runtime // machine code // Lifted code emit_event(BASIC_BLOCK_START) 0x1000: cpu_state.pc = 0x1000 add ebx, 1 ebx = &cpu_state.registers[R_EBX] jmp 0x1234 *ebx = *ebx + 1 cpu_state.icount++ cpu_state.pc = 0x1234 30 emit_event(BASIC_BLOCK_END)
BinRec design Compiler IR Transform Add errors / fallbacks Lift in VM Compile Machine Code Link data sections Input Symbolic Recovered binary execution binary // machine code // Lifted code emit_event(BASIC_BLOCK_START) 0x1000: cpu_state.pc = 0x1000 add ebx, 1 events, counters ebx = &cpu_state.registers[R_EBX] jmp 0x1234 *ebx = *ebx + 1 cpu_state.icount++ cpu_state.pc = 0x1234 31 emit_event(BASIC_BLOCK_END)
BinRec design Compiler IR Transform Strip emulation Add errors / fallbacks Lift in VM Compile Machine Code Link data sections Input Symbolic Recovered binary execution binary // machine code // Lifted code emit_event(BASIC_BLOCK_START) 0x1000: cpu_state.pc = 0x1000 add ebx, 1 control flow through ebx = &cpu_state.registers[R_EBX] jmp 0x1234 virtual program counter *ebx = *ebx + 1 cpu_state.icount++ registers in CPU state cpu_state.pc = 0x1234 32 emit_event(BASIC_BLOCK_END)
BinRec design Compiler IR Transform Strip emulation Add errors / fallbacks Lift in VM Compile Machine Code Link data sections Input Symbolic Recovered binary execution binary // machine code // Lifted code // stripped code emit_event(BASIC_BLOCK_START) 0x1000: global ebx cpu_state.pc = 0x1000 add ebx, 1 lifted_1000: ebx = &cpu_state.registers[R_EBX] jmp 0x1234 ebx = ebx + 1 *ebx = *ebx + 1 goto lifted_1234 cpu_state.icount++ cpu_state.pc = 0x1234 33 emit_event(BASIC_BLOCK_END)
BinRec design Compiler IR Transform Pre-process Post-process Strip emulation Add errors / fallbacks Lift in VM Compile Machine Code Link data sections Input Symbolic Recovered binary execution binary Needed to prevent over-optimization during transformations (details in paper) 34
This is quite bit of code 35
Implementation Transform Pre-process Post-process Strip emulation Add errors / fallbacks Lift in VM Compile Link data sections Input Symbolic Recovered binary execution binary 36
Implementation Transform Pre-process Post-process Strip emulation Add errors / fallbacks Lift in VM Compile Link data sections S 2 E Input Symbolic Recovered binary execution binary 37
Implementation LLVM Transform Pre-process Post-process Strip emulation Add errors / fallbacks Lift in VM Compile Link data sections S 2 E Input Symbolic Recovered binary execution binary 38
Implementation LLVM Transform Pre-process Post-process Strip emulation Add errors / fallbacks Lift in VM Compile Binutils Link data sections S 2 E Input Symbolic Recovered binary execution binary Bash + Python 39
Case study 40
Transform Pre-process Post-process Strip emulation Add errors / fallbacks Lift in VM Compile Link data sections Input Symbolic Recovered binary execution binary // ab.c int main(int argc, char **argv) { char a = argv[1][0]; char b = argv[1][1]; if (a == 'a') { if (b == 'b') { puts("You entered \"ab\""); } } return 0; } 41
Transform Pre-process Post-process Strip emulation Add errors / fallbacks Lift in VM Compile Link data sections Input Symbolic Recovered binary execution binary 42
Transform Pre-process Post-process Strip emulation Add errors / fallbacks Lift in VM Compile Link data sections Input Symbolic Recovered binary execution binary Raw code is heavily instrumented - event triggers - instruction counter - program counter, registers, flags, etc. stored in CPU state in memory 43
Recommend
More recommend