Systems and Internet Infrastructure Security Laboratory (SIIS) Page 1
CMPSC 497: Symbolic Execution
Trent Jaeger Systems and Internet Infrastructure Security (SIIS) Lab Computer Science and Engineering Department Pennsylvania State University
CMPSC 497: Symbolic Execution Trent Jaeger Systems and Internet - - PowerPoint PPT Presentation
CMPSC 497: Symbolic Execution Trent Jaeger Systems and Internet Infrastructure Security (SIIS) Lab Computer Science and Engineering Department Pennsylvania State University Systems and Internet Infrastructure Security Laboratory (SIIS) Page
Systems and Internet Infrastructure Security Laboratory (SIIS) Page 1
Trent Jaeger Systems and Internet Infrastructure Security (SIIS) Lab Computer Science and Engineering Department Pennsylvania State University
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
2
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
3
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
4
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
5
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
values
symbolic variables at any particular point in your program
6
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
that input to reach particular points in the program
7
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
int main(void) { unsigned int i, t, a[4] = { 1, 3, 5, 2 }; if (i >= 4) exit(0); char *p = (char *)a + i * 4; *p = *p − 1 t = a[*p]; t = t / a[i]; if (t == 2) assert(i == 1); else assert(i == 3); return 0; }
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
int main(void) { unsigned int i, t, a[4] = { 1, 3, 5, 2 }; if (i >= 4) exit(0); char *p = (char *)a + i * 4; *p = *p − 1 t = a[*p]; t = t / a[i]; if (t == 2) assert(i == 1); else assert(i == 3); return 0; }
make_symbolic(&i);
Marks the 4 bytes associated with 32-bit variable ‘i’ as symbolic
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
example.c EXE compiler Inserts checks around every assignment, expression & branch, to determine if its operands are concrete or symbolic example.out Executable
unsigned int a[4] = {1,3,5,2} if (i >= 4)
int main(void) { unsigned int i, t, a[4] = { 1, 3, 5, 2 }; make_symbolic(&i); if (i >= 4) exit(0); char *p = (char *)a + i * 4; *p = *p − 1 t = a[*p]; t = t / a[i]; if (t == 2) assert(i == 1); else assert(i == 3); return 0; }
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
example.c EXE compiler Inserts checks around every assignment, expression & branch, to determine if its operands are concrete or symbolic example.out Executable
int main(void) { unsigned int i, t, a[4] = { 1, 3, 5, 2 }; make_symbolic(&i); if (i >= 4) exit(0); char *p = (char *)a + i * 4; *p = *p − 1 t = a[*p]; t = t / a[i]; if (t == 2) assert(i == 1); else assert(i == 3); return 0; }
If any operand is symbolic, the operation is not performed, but is added as a constraint for the current path
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
example.c EXE compiler example.out Executable
int main(void) { unsigned int i, t, a[4] = { 1, 3, 5, 2 }; make_symbolic(&i); if (i >= 4) exit(0); char *p = (char *)a + i * 4; *p = *p − 1 t = a[*p]; t = t / a[i]; if (t == 2) assert(i == 1); else assert(i == 3); return 0; }
Inserts code to fork program execution when it reaches a symbolic branch point, so that it can explore each possibility
if (i >= 4)
(i ≥ 4) (i < 4)
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
example.c EXE compiler example.out Executable
int main(void) { unsigned int i, t, a[4] = { 1, 3, 5, 2 }; make_symbolic(&i); if (i >= 4) exit(0); char *p = (char *)a + i * 4; *p = *p − 1 t = a[*p]; t = t / a[i]; if (t == 2) assert(i == 1); else assert(i == 3); return 0; }
Inserts code to fork program execution when it reaches a symbolic branch point, so that it can explore each possibility For each branch constraint, queries constraint solver for existence
executing path
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
example.c EXE compiler example.out Executable
int main(void) { unsigned int i, t, a[4] = { 1, 3, 5, 2 }; make_symbolic(&i); if (i >= 4) exit(0); char *p = (char *)a + i * 4; *p = *p − 1 t = a[*p]; t = t / a[i]; if (t == 2) assert(i == 1); else assert(i == 3); return 0; }
Inserts code for checking if a symbolic expression could have any possible value that could cause errors
t = t / a[i]
Division by Zero?
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
example.c EXE compiler example.out Executable
int main(void) { unsigned int i, t, a[4] = { 1, 3, 5, 2 }; make_symbolic(&i); if (i >= 4) exit(0); char *p = (char *)a + i * 4; *p = *p − 1 t = a[*p]; t = t / a[i]; if (t == 2) assert(i == 1); else assert(i == 3); return 0; }
Inserts code for checking if a symbolic expression could have any possible value that could cause errors If the check passes – the path has been verified as safe under all possible input values (relative to those checks)
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
int main(void) { unsigned int i, t, a[4] = { 1, 3, 5, 2 }; if (i >= 4) exit(0); char *p = (char *)a + i * 4; *p = *p − 1 t = a[*p]; t = t / a[i]; if (t == 2) assert(i == 1); else assert(i == 3); return 0; }
make_symbolic(&i); e.g. i = 8 4 ≤ i
EXE generates a test case
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
int main(void) { unsigned int i, t, a[4] = { 1, 3, 5, 2 }; if (i >= 4) exit(0); char *p = (char *)a + i * 4; *p = *p − 1 t = a[*p]; t = t / a[i]; if (t == 2) assert(i == 1); else assert(i == 3); return 0; }
make_symbolic(&i);
e.g. i = 2 p → a[2] = 5 a[2] = 5 – 1 = 4 t = a[4] EXE generates a test case Out of bounds 0 ≤ i ≤ 4
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
int main(void) { unsigned int i, t, a[4] = { 1, 3, 5, 2 }; if (i >= 4) exit(0); char *p = (char *)a + i * 4; *p = *p − 1 t = a[*p]; t = t / a[i]; if (t == 2) assert(i == 1); else assert(i == 3); return 0; }
make_symbolic(&i);
e.g. i = 0 p → a[0] = 1 a[0] = 1 – 1 = 0 t = a[0] EXE generates a test case Division by 0 0≤ i ≤ 4 , i ≠ 2 t = t / 0
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
int main(void) { unsigned int i, t, a[4] = { 1, 3, 5, 2 }; if (i >= 4) exit(0); char *p = (char *)a + i * 4; *p = *p − 1 t = a[*p]; t = t / a[i]; if (t == 2) assert(i == 1); else assert(i == 3); return 0; }
make_symbolic(&i);
i = 1 p → a[1] a[1] = 2 t = a[2] EXE determines neither ‘assert’ fails 0≤ i ≤ 4 , i ≠ 2 , i ≠ 0 t = 2 i = 3 p → a[3] a[3] = 1 t = a[1] t ≠ 2 2 valid test cases
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
test3.out test3.forks test3.err # concrete byte values: 0 # i[0], 0 # i[1], 0 # i[2], 0 # i[3] ERROR: simple.c:16 Division/modulo by zero! # take these choices to follow path 0 # false branch (line 5) 0 # false (implicit: pointer overflow check on line 9) 1 # true (implicit: div−by−0 check on line 16)
i = 0
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
constraints collected on symbolic inputs
22
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
particular statement in the program may require some assistance (e.g., from static analysis)
advancements in this area have improved effectiveness in practice
23
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
24
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
to gather information resulting from such interactions
modeled by the symbolic executor
modeled by the executor
25
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
26
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
0% 20% 40% 60% 80% 100% 1 12 23 34 45 56 67 78 89
GNU COREUTILS
16 at 100% Apps sorted by KLEE coverage Coverage (ELOC %)
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
30
continue to run program concretely
(e.g., system call) and then run concretely on that
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
31
statement if the control flow is complex?
statement
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
32
tainted by interesting inputs
what values interesting inputs may be assigned at such statements
may be difficult or slow for the symbolic execution to reach these security-sensitive statements
from the statements receiving the interesting inputs to the security-sensitive statement
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
33
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
34
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
35
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!"
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
36
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!"
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
37
x = input() if x >= 10: if x % 1337 == 0: print "You win!" else: print "You lose!" else: print "You lose!"
x % 1337 != 0
x % 1337 == 0
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
38
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
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
39
for general conditions
specific conditions
for specific conditions
iterating over general conditions
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
40
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!"
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
41
Test Cases
Control Flow Graph
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
42
“Y” “X” Test Cases “Cheap” fuzzing coverage
Control Flow Graph
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
43
“Y” “X” Test Cases “Cheap” fuzzing coverage Tracing via Symbolic Execution
!
Control Flow Graph
Reachable?
“Y” “X” Test Cases “Cheap” fuzzing coverage Tracing via Symbolic Execution
!
Control Flow Graph
Reachable?
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
44
“Y” “X” Test Cases “Cheap” fuzzing coverage Tracing via Symbolic Execution “MAGIC” New test cases generated
Control Flow Graph
Synthesized!
“Y” “X” Test Cases “Cheap” fuzzing coverage Tracing via Symbolic Execution “MAGIC” New test cases generated
Control Flow Graph
Synthesized!
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
45
“Y” “X” Test Cases “Cheap” fuzzing coverage Tracing via Symbolic Execution “MAGIC” New test cases generated “MAGICY”
Control Flow Graph
Towards completer code coverage!
“Y” “X” Test Cases “Cheap” fuzzing coverage Tracing via Symbolic Execution “MAGIC” New test cases generated “MAGICY”
Control Flow Graph
Towards completer code coverage!
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
46
“Y” “X” Test Cases “Cheap” fuzzing coverage Tracing via Symbolic Execution “MAGIC” New test cases generated “MAGICY”
Control Flow Graph
Towards completer code coverage!
“Y” “X” Test Cases “Cheap” fuzzing coverage Tracing via Symbolic Execution “MAGIC” New test cases generated “MAGICY”
Control Flow Graph
Towards completer code coverage!
Systems and Internet Infrastructure Security Laboratory (SIIS) Page
47
values to reach a specific program statement