BinRec: Attack Surface Reduction Through Dynamic Binary Recovery - - PowerPoint PPT Presentation

binrec attack surface reduction through dynamic binary
SMART_READER_LITE
LIVE PREVIEW

BinRec: Attack Surface Reduction Through Dynamic Binary Recovery - - PowerPoint PPT Presentation

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 =


slide-1
SLIDE 1

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

slide-2
SLIDE 2

Attack Surface Reduction

x = getenv(“SET_ME”); if (x) cold_code(); hot_code();

2

slide-3
SLIDE 3

Attack Surface Reduction

x = getenv(“SET_ME”); if (x) cold_code(); hot_code();

3

Buggy features ROP gadgets

slide-4
SLIDE 4

Attack Surface Reduction

x = getenv(“SET_ME”); if (x) cold_code(); hot_code();

4

Remove unwanted features A t t a c k s u r f a c e r e d u c e d t

  • w

e l l

  • t

e s t e d c

  • d

e

slide-5
SLIDE 5

Attack Surface Reduction

5

setme_str: .asciz: “SET_ME” push setme_str call getenv cmp eax, 0 je main call cold_code main: call hot_code

Want to work on COTS binaries

slide-6
SLIDE 6

Static approach

Input binary Transformed binary

6

Transform

slide-7
SLIDE 7

Static approach

Input binary Transformed binary

7

i n c

  • m

p l e t e d i s a s s e m b l y PIC?

  • bfuscated?

Transform

slide-8
SLIDE 8

Static approach

Input binary Transformed binary

8

i n c

  • m

p l e t e d i s a s s e m b l y contains cold code PIC?

  • bfuscated?

w h i c h c

  • d

e i s r e a c h e d ?

Transform

slide-9
SLIDE 9

Dynamic approach by BinRec

Transform

Input binary

9

Transformed binary p r e c i s e d i s a s s e m b l y

  • nly hot code

Execute

slide-10
SLIDE 10

Recovery

Dynamic approach by BinRec

Input binary Recovered binary

10

Transform Execute

slide-11
SLIDE 11

Recovery

Dynamic approach by BinRec

Input binary Recovered binary

11

Transform Execute

can we make this more generic?

slide-12
SLIDE 12

BinRec goal: complex binary transformation

Attack Surface Reduction / Binary rejuvenation / Profile-guided

  • ptimization

/ (De)obfuscation / ISA retargeting

Input binary Recovered binary

12

many applications

Execute

slide-13
SLIDE 13

BinRec goal: complex binary transformation

Attack Surface Reduction / Binary rejuvenation / Profile-guided

  • ptimization

/ (De)obfuscation / ISA retargeting

Input binary Recovered binary

13

many applications r e q u i r e s h i g h

  • l

e v e l c

  • d

e !

Execute

slide-14
SLIDE 14

BinRec design

Input binary Recovered binary Compiler IR Machine Code

14

Execute Transform

slide-15
SLIDE 15

BinRec design

Lift

Input binary Recovered binary Compiler IR Machine Code

15

Execute Transform Lower

slide-16
SLIDE 16

BinRec design

Lift

Input binary Recovered binary Compiler IR Machine Code

16

Execute Transform Lower

Sometimes we want more code coverage than a single code path

slide-17
SLIDE 17

BinRec design

Lift

Input binary Recovered binary Compiler IR Machine Code

17

Symbolic execution

Transform Lower

Run with “symbolic” input and follow both sides of a branch

slide-18
SLIDE 18

BinRec design

Lift

Input binary Recovered binary Compiler IR Machine Code

18

Symbolic execution

Transform Lower

Need to observe each instruction Want to support multiple architectures

slide-19
SLIDE 19

BinRec design

Lift in VM

Input binary Recovered binary Compiler IR Machine Code

19

Symbolic execution

Transform Lower

E m u l a t e i n V M , t r a n s l a t e i n s t r u c t i

  • n

s t

  • I

R

slide-20
SLIDE 20

BinRec design

Lift in VM

Input binary Recovered binary Compiler IR Machine Code

20

Symbolic execution

Transform Lower

slide-21
SLIDE 21

BinRec design

Lift in VM

Input binary Recovered binary Compiler IR Machine Code

21

Symbolic execution

Transform Compile

J u s t u s e t h e c

  • m

p i l e r

slide-22
SLIDE 22

BinRec design

Lift in VM

Input binary Recovered binary Compiler IR Machine Code

22

Symbolic execution

Transform Compile

slide-23
SLIDE 23

BinRec design

Lift in VM

Input binary Recovered binary Compiler IR Machine Code

23

Symbolic execution

Transform Compile

What about unlifted code paths? ... if (getenv(“SET_ME”)) { puts(“thanks!”); // not recovered! } ...

slide-24
SLIDE 24

BinRec design

Lift in VM

Input binary Recovered binary Compiler IR Machine Code

24

Symbolic execution

Transform Compile

What about unlifted code paths?

  • 1. do nothing (breaks conservative behavior)

... getenv(“SET_ME”); ...

slide-25
SLIDE 25

BinRec design

Lift in VM

Input binary Recovered binary Compiler IR Machine Code

25

Symbolic execution

Transform

What about unlifted code paths?

  • 2. yield error

... if (getenv(“SET_ME”)) { abort(); } ... Compile Add errors

slide-26
SLIDE 26

BinRec design

Lift in VM

Input binary Recovered binary Compiler IR Machine Code

26

Symbolic execution

Transform

What about unlifted code paths?

  • 3. fallback to old code

... if (getenv(“SET_ME”)) { goto old_code_address; } ... Compile Add errors / fallbacks

slide-27
SLIDE 27

BinRec design

Lift in VM

Input binary Recovered binary Compiler IR Machine Code

27

Symbolic execution

Transform

R e f e r e n c e s d a t a f r

  • m

i n p u t b i n a r y Compile Add errors / fallbacks

slide-28
SLIDE 28

BinRec design

Lift in VM

Input binary Recovered binary Compiler IR Machine Code

28

Symbolic execution

Transform

Compile Add errors / fallbacks Link data sections

slide-29
SLIDE 29

BinRec design

Lift in VM

Input binary Recovered binary Compiler IR Machine Code

29

Symbolic execution

Transform

Compile Add errors / fallbacks Link data sections IR interacts with VM runtime

slide-30
SLIDE 30

// Lifted code emit_event(BASIC_BLOCK_START) cpu_state.pc = 0x1000 ebx = &cpu_state.registers[R_EBX] *ebx = *ebx + 1 cpu_state.icount++ cpu_state.pc = 0x1234 emit_event(BASIC_BLOCK_END)

BinRec design

Lift in VM

Input binary Recovered binary Compiler IR Machine Code

30

Symbolic execution

Transform

Compile Add errors / fallbacks Link data sections // machine code 0x1000: add ebx, 1 jmp 0x1234 IR interacts with VM runtime

slide-31
SLIDE 31

// Lifted code emit_event(BASIC_BLOCK_START) cpu_state.pc = 0x1000 ebx = &cpu_state.registers[R_EBX] *ebx = *ebx + 1 cpu_state.icount++ cpu_state.pc = 0x1234 emit_event(BASIC_BLOCK_END)

BinRec design

Lift in VM

Input binary Recovered binary Compiler IR Machine Code

31

Symbolic execution

Transform

Compile Add errors / fallbacks Link data sections events, counters // machine code 0x1000: add ebx, 1 jmp 0x1234

slide-32
SLIDE 32

// Lifted code emit_event(BASIC_BLOCK_START) cpu_state.pc = 0x1000 ebx = &cpu_state.registers[R_EBX] *ebx = *ebx + 1 cpu_state.icount++ cpu_state.pc = 0x1234 emit_event(BASIC_BLOCK_END)

BinRec design

Input binary Recovered binary Compiler IR Machine Code

32

Symbolic execution

Transform

Compile Add errors / fallbacks Link data sections // machine code 0x1000: add ebx, 1 jmp 0x1234 registers in CPU state control flow through virtual program counter

Lift in VM Strip emulation

slide-33
SLIDE 33

BinRec design

Lift in VM

Input binary Recovered binary Compiler IR Machine Code

33

Symbolic execution

Transform

Compile Add errors / fallbacks Link data sections // stripped code global ebx lifted_1000: ebx = ebx + 1 goto lifted_1234 // machine code 0x1000: add ebx, 1 jmp 0x1234

// Lifted code emit_event(BASIC_BLOCK_START) cpu_state.pc = 0x1000 ebx = &cpu_state.registers[R_EBX] *ebx = *ebx + 1 cpu_state.icount++ cpu_state.pc = 0x1234 emit_event(BASIC_BLOCK_END)

Strip emulation

slide-34
SLIDE 34

BinRec design

Lift in VM

Input binary Recovered binary Compiler IR Machine Code

34

Symbolic execution

Transform

Compile Add errors / fallbacks Link data sections

Strip emulation Pre-process Post-process

Needed to prevent over-optimization during transformations (details in paper)

slide-35
SLIDE 35

This is quite bit of code

35

slide-36
SLIDE 36

Implementation

Lift in VM

Input binary Recovered binary

36

Symbolic execution

Transform

Compile Add errors / fallbacks Link data sections

Strip emulation Pre-process Post-process

slide-37
SLIDE 37

Implementation

Input binary Recovered binary

37

Symbolic execution

Transform

Compile Add errors / fallbacks Link data sections

Strip emulation Pre-process Post-process

S2E

Lift in VM

slide-38
SLIDE 38

Implementation

Input binary Recovered binary

38

Symbolic execution

Transform

Compile Add errors / fallbacks Link data sections

Strip emulation Pre-process Post-process

S2E

Lift in VM

LLVM

slide-39
SLIDE 39

Implementation

Input binary Recovered binary

39

Symbolic execution

Transform

Compile Add errors / fallbacks Link data sections

Strip emulation Pre-process Post-process

S2E

Lift in VM

LLVM Bash + Python Binutils

slide-40
SLIDE 40

Case study

40

slide-41
SLIDE 41

Lift in VM Input binary Recovered binary

41

Symbolic execution Transform Compile

Add errors / fallbacks

Link data sections Strip emulation Pre-process Post-process

// 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; }

slide-42
SLIDE 42

Lift in VM Input binary Recovered binary

42

Symbolic execution Transform Compile

Add errors / fallbacks

Link data sections Strip emulation Pre-process Post-process

slide-43
SLIDE 43

Input binary Recovered binary

43

Symbolic execution Transform Compile

Add errors / fallbacks

Link data sections Strip emulation Pre-process Post-process

Raw code is heavily instrumented

  • event triggers
  • instruction counter
  • program counter, registers, flags, etc. stored in CPU state in memory

Lift in VM

slide-44
SLIDE 44

Input binary Recovered binary

44

Symbolic execution Transform Compile

Add errors / fallbacks

Link data sections Strip emulation Pre-process Post-process Lift in VM

cmp eax, 1 jle label

“heavily” instrumented

slide-45
SLIDE 45

Input binary Recovered binary

45

Symbolic execution Transform Compile

Add errors / fallbacks

Link data sections Pre-process Post-process Lift in VM

Raw Pruned

Strip emulation

slide-46
SLIDE 46

Input binary Recovered binary

46

Symbolic execution Transform Compile

Add errors / fallbacks

Link data sections Pre-process Post-process Lift in VM

Pruned Optimized Raw

Strip emulation

slide-47
SLIDE 47

Input binary Recovered binary

47

Symbolic execution Transform Compile

Add errors / fallbacks

Link data sections Pre-process Post-process Lift in VM Strip emulation

Cascading optimizations

slide-48
SLIDE 48

Input binary Recovered binary

48

Symbolic execution Transform

Add errors / fallbacks

Link data sections Pre-process Post-process Lift in VM Strip emulation Compile .text

Recovered code

...

slide-49
SLIDE 49

Input binary Recovered binary

49

Symbolic execution Transform

Add errors / fallbacks

Pre-process Post-process Lift in VM Strip emulation Compile .text .rodata .data

Old binary

.got .plt ... .text

Recovered code

... .text .rodata .data

Recovered binary

.got .plt .text.new

= +

... Link data sections

entry entry

slide-50
SLIDE 50

Input binary Recovered binary

50

Symbolic execution Transform

Add errors / fallbacks

Pre-process Post-process Lift in VM Strip emulation Compile .text .rodata .data

Old binary

.got .plt ... .text

Recovered code

... .text .rodata .data

Recovered binary

.got .plt .text.new

= +

... Link data sections

Remove for error, Keep for fallback

entry entry

slide-51
SLIDE 51

Input binary Recovered binary

51

Symbolic execution Transform Compile

Add errors / fallbacks

Link data sections Pre-process Post-process Lift in VM Strip emulation

Original C Recovered LLVM

slide-52
SLIDE 52

Input binary Recovered binary

52

Symbolic execution Transform Compile

Add errors / fallbacks

Link data sections Pre-process Post-process Lift in VM Strip emulation

Original LLVM Recovered LLVM

slide-53
SLIDE 53

Experiments

53

slide-54
SLIDE 54

Experiments

  • Correctness
  • Attack Surface Reduction: ROP gadgets
  • Performance

54

slide-55
SLIDE 55

Experiment: correctness

Do our transformations preserve semantics?

  • Yield errors for unknown code paths
  • Check that recovered binary has same output as input binary

55

slide-56
SLIDE 56

Experiment: correctness

Do our transformations preserve semantics?

  • Yield errors for unknown code paths
  • Check that recovered binary has same output as input binary

24 input binaries from SPEC-CPU2006 (x86)

  • 15 succeeded, 9 failed (unexpected fallback / crash)

56

slide-57
SLIDE 57

Experiment: ROP gadget reduction

Is the attack surface actually smaller?

  • 72% fewer instructions
  • 48% fewer ROP gadgets

(both numbers are geomean)

57

slide-58
SLIDE 58

Experiment: performance

  • O3 input binaries: expect similar performance
  • O0 input binaries: expect speedup
  • Disable fallback errors: maybe expect speedup

58

~44% overhead

slide-59
SLIDE 59
  • O3 input binaries: expect similar performance
  • O0 input binaries: expect speedup
  • Disable fallback errors: maybe expect speedup

Experiment: performance

59

~2% overhead

slide-60
SLIDE 60
  • O3 input binaries: expect similar performance
  • O0 input binaries: expect speedup
  • Disable fallback errors: maybe expect speedup

Experiment: performance

60

~5% performance gain

slide-61
SLIDE 61

Wish list / future work

  • Gadget-aware compiler backend
  • Improve performance
  • Do aggressive profile-guided optimization
  • Deobfuscation

61

slide-62
SLIDE 62
  • BinRec successfully transforms binaries at compiler IR level
  • … and halves the ROP attack surface in the process

Also

  • Binary lifting is hard

Conclusion

62