Driller: Augmenting Fuzzing through Symbolic Execution Nick Stephens - - PowerPoint PPT Presentation

driller augmenting fuzzing through symbolic execution
SMART_READER_LITE
LIVE PREVIEW

Driller: Augmenting Fuzzing through Symbolic Execution Nick Stephens - - PowerPoint PPT Presentation

Driller: Augmenting Fuzzing through Symbolic Execution Nick Stephens , John Grosen, Christopher Salls, Andrew Dutcher, Ruoyu Wang, Jacopo Corbetta, Yan Shoshitaishvili, Christopher Kruegel, Giovanni Vigna Motivation - Large number of memory


slide-1
SLIDE 1

Driller: Augmenting Fuzzing through Symbolic Execution

Nick Stephens, John Grosen, Christopher Salls, Andrew Dutcher, Ruoyu Wang, Jacopo Corbetta, Yan Shoshitaishvili, Christopher Kruegel, Giovanni Vigna

slide-2
SLIDE 2

Motivation

  • Large number of memory corruption bugs
  • Problems with testcase generation techniques
  • Fuzzing
  • Symbolic Execution
slide-3
SLIDE 3

Fuzzing

slide-4
SLIDE 4

x = int(input()) if x > 10: if x < 100: print "You win!" else: print "You lose!" else: print "You lose!"

Let's fuzz it! 1 ⇒ "You lose!" 593 ⇒ "You lose!" 183 ⇒ "You lose!" 4 ⇒ "You lose!" 498 ⇒ "You lose!"

4

48 ⇒ "You win!"

slide-5
SLIDE 5

Catching Bugs

  • Monitors program for crashes
slide-6
SLIDE 6

x = int(input()) if x > 10: if x^2 == 152399025: print "You win!" else: print "You lose!" else: print "You lose!"

Let's fuzz it! 1 ⇒ "You lose!" 593 ⇒ "You lose!" 183 ⇒ "You lose!" 4 ⇒ "You lose!" 498 ⇒ "You lose!" 42 ⇒ "You lose!" 3 ⇒ "You lose!"

6

………. 57 ⇒ "You lose!"

slide-7
SLIDE 7

Symbolic Execution

slide-8
SLIDE 8

x = input() if x >= 10: if x % 1337 == 0: print "You win!" else: print "You lose!" else: print "You lose!"

??? x < 10 x >= 10 x >= 10

x % 1337 != 0

x >= 10

x % 1337 == 0

slide-9
SLIDE 9

x = input() if x >= 10: if x % 1337 == 0: print "You win!" else: print "You lose!" else: print "You lose!"

??? x < 10 x >= 10 x >= 10

x % 1337 != 0

x >= 10

x % 1337 == 0

1337

slide-10
SLIDE 10

Catching Bugs

  • Checks each state for safety violations
  • symbolic program counter
  • writes/reads from symbolic address
slide-11
SLIDE 11

x = input() def recurse(x, depth): if depth == 2000 return 0 else { r = 0; if x[depth] == “B”: r = 1 return r + recurse(x[depth], depth) if recurse(x, 0) == 1: print “You win!”

??? x[d] == “B” x[d] != “B”

slide-12
SLIDE 12

Different Approaches

Fuzzing

  • Good at finding solutions

for general conditions

  • Bad at finding solutions for

specific conditions

Symbolic Execution

  • Good at finding solutions

for specific conditions

  • Spends too much time

iterating over general conditions

slide-13
SLIDE 13

Fuzzing vs. Symbolic Execution

Fuzzing Wins Symbolic Execution Wins

x = input() def recurse(x, depth): if depth == 2000 return 0 else { r = 0; if x[depth] == “B”: r = 1 return r + recurse(x [depth], depth) if recurse(x, 0) == 1: print “You win!” x = int(input()) if x >= 10: if x^2 == 152399025: print "You win!" else: print "You lose!" else: print "You lose!"

slide-14
SLIDE 14

Fuzzing

good at finding solutions for general input

Symbolic Execution

good at find solutions for specific input

slide-15
SLIDE 15

American Fuzzy Lop + angr

AFL

  • state-of-the-art

instrumented fuzzer

  • path uniqueness tracking
  • genetic mutations
  • open source

angr

  • binary analysis platform
  • implements symbolic

execution engine

  • influenced by Mayhem
  • works on binary code
  • available on github
slide-16
SLIDE 16

Combining the Two (High-level)

Test Cases

Control Flow Graph

slide-17
SLIDE 17

Combining the Two

“Y” “X” Test Cases “Cheap” fuzzing coverage

Control Flow Graph

slide-18
SLIDE 18

Combining the Two

“Y” “X” Test Cases “Cheap” fuzzing coverage Tracing via Symbolic Execution

!

Control Flow Graph

Reachable?

slide-19
SLIDE 19

Combining the Two

“Y” “X” Test Cases “Cheap” fuzzing coverage Tracing via Symbolic Execution “MAGIC” New test cases generated

Control Flow Graph

Synthesized!

slide-20
SLIDE 20

Combining the Two

“Y” “X” Test Cases “Cheap” fuzzing coverage Tracing via Symbolic Execution “MAGIC” New test cases generated “MAGICY”

Control Flow Graph

Towards completer code coverage!

slide-21
SLIDE 21

AFL’s Path Selection

  • Tracks state-transitions on each program run
  • Basic Block A -> Basic Block B
  • Path uniqueness = Set of state-trans uniqueness
  • Input generation is still primitive mutations
slide-22
SLIDE 22

Improving Path Selection with angr

Test Cases

AFL

strcmp(input, "MAGIC") input[0] == 'X' ... ... ...

slide-23
SLIDE 23

Improving Path Selection with angr

Test Cases “X”

AFL

strcmp(input, "MAGIC") input[0] == 'X' ... ... ...

slide-24
SLIDE 24

Improving Path Selection with angr

Test Cases “X” “Y”

AFL

strcmp(input, "MAGIC") input[0] == 'X' ... ... ...

slide-25
SLIDE 25

Improving Path Selection with angr

Test Cases “X” “Y”

AFL

strcmp(input, "MAGIC") input[0] == 'X' ... ... ... “Z”

slide-26
SLIDE 26

Improving Path Selection with angr

Test Cases “X” “Y”

AFL

strcmp(input, "MAGIC") input[0] == 'X' ... ... ...

slide-27
SLIDE 27

Improving Path Selection with angr

Test Cases “X” “Y”

angr

strcmp(input, "MAGIC") input[0] == 'X' ... ... ...

?

slide-28
SLIDE 28

Improving Path Selection with angr

Test Cases “X” “Y”

angr

strcmp(input, "MAGIC") input[0] == 'X' ... ... ... “MAGIC”

New state transition, synthesize!

slide-29
SLIDE 29

Improving Path Selection with angr

... ... ... ... ... ... ...

Continue following “X”’s original path until completion, deviating when possible.

angr

slide-30
SLIDE 30

State Space Reduction

  • Symbolic Execution’s state-space is reduced to

AFL’s

  • Reduces path explosion
slide-31
SLIDE 31

Binary Crashes per Technique

Symbolic Execution (angr) - 16 total Fuzzing (AFL) - 68 total

68

16 S & F Shared - 13 total

71 / 128 binaries

slide-32
SLIDE 32

Binary Crashes per Technique

Symbolic Execution (angr) - 16 Fuzzing (AFL) - 68

55

S & F Shared - 13 total Driller - 77

77

16

68

77 / 128 binaries

slide-33
SLIDE 33

symbolic execution fuzzing

Distribution of Transitions Found as Iterations of Symbolic Execution and Fuzzing

slide-34
SLIDE 34

Limitations

int main(void) { char data[100]; char *computed_hash; char hash[16]; read(0, data, sizeof data); computed_hash = hash(data); read(0, hash, sizeof hash); if (memcmp(hash, computed_hash, 16) != 0) { // `data` processed here // code susceptible to fuzzing } }

Fuzzing beyond the hash is still problematic!

slide-35
SLIDE 35

Conclusion

  • Driller is greater than the sum of its parts
  • Offers a >10% increase in crashes over pure AFL
  • Driller curbs path explosion