CS 161 Computer Security Finding bugs Analysis Techniques
CS 161 Computer Security Finding bugs: Analysis Techniques & Tools Symbolic Execution & Constraint Solving Cho, Chia Yuan
Lab • Q 1: Manual reasoning on code – Mergesort implementation published in Wikibooks • Q 2: Constraint Solving – ‘Solve’ for collisions in ELFHash function • Q 3: Whitebox & blackbox fuzzing – Use a dynamic symbolic execution tool to find bugs automatically • Start early!
Big Picture Attacks & Defenses Mobile Security (Android) Web Security Network Security Crypto Symbolic Execution & Constraint Solving Program Analysis & Verification Why?
Can we build a machine that can automatically reason and prove mathematical facts about programs? A little history …
1967
1967
1976 “From one simple view, it is an enhanced testing technique. Instead of executing a program on a set of sample inputs, a program is "symbolically" executed for a set of classes of inputs. ”
Why now?
Advances in SAT Solvers Source: Sanjit Seshia
Advances in SAT Solvers Source: Sanjit Seshia
Significance
How do we know our program is “correct”? • • • In general, we don’t know. Test it Precision Let users test it for us Fuzz it Try to prove it’s correct Coverage Static analysis Symbolic Execution & Constraint Solving
Dynamic Sym Exec is Directed Testing • Path-by-path exploration (len == input + 3) len = input + 3; && !(len < 10) if len < 10 T && !(len%2==0) s = len F if len % 2 == 0 T F s = len + 2 s = len buf=malloc (s); read(fd, buf, len);
Dynamic Sym Exec is Directed Testing • Path-by-path exploration (len == input + 3) len = input + 3; && !(len < 10) if len < 10 T && (len%2==0) s = len Can we combine all paths into 1 single formula? Þ Bounded Model Checking F if len % 2 == 0 T F s = len + 2 s = len buf=malloc (s); read(fd, buf, len); How do we construct the formula & use a solver?
Q 2 Goal: ‘Solve’ for Hash Collisions
Constructing Logic Formulas from Code • Convert statements into Static Single Assignment (SSA) form • Encode SSA into target solver input format
Static Single Assignment Equations • Unroll loops to form loop-free program – for(i=0; i<2; i++){a=a+1; } Ø a=a+1; • Rename LHS of each assignment into a new local variable Ø a 1=a+1; a 2=a+1; • Whenever a variable is read (e. g. , at RHS), replace it with last assigned variable name Ø a 1=a 0+1; a 2=a 1+1;
Conditional (if) statements • Dynamic Symbolic Execution: – 2 separate path formulas • Bounded Model Checking: – Merge both branches into 1 formula
Conditional (if) statements
Example SSA int example 1(int x) { int ret; Is this program correct? if (x > 0) ret = x; else ret = -x; assert(ret >= 0); return ret; } ret 1 = x 0 ret 2 = -x 0 ret 3 = (x 0>0 ? ret 1 : ret 2) Q: Is !(ret 3 >= 0) satisfiable?
Constructing Logic Formulas from Code • Convert statements into Static Single Assignment (SSA) form = Bit-vector Equations in quantifier-free 1 st order logic • Encode SSA into target solver input format – Bit-vector arithmetic logic – “SMT” Solver – SMT-LIB 1. 0 standard
Example SMT-LIB : extrafuns(x 0 Bit. Vec[32]) : extrafuns(ret 1 Bit. Vec[32]) : extrafuns(ret 2 Bit. Vec[32]) : extrafuns(ret 3 Bit. Vec[32]) : extrapreds(branchcond 1) ret 1 = x 0 : assumption (= ret 1 x 0) ret 2 = -x 0 : assumption (= ret 2 (bvneg x 0) : assumption (iff branchcond 1 (bvsgt x 0 bv 0[32]) ret 3 = (x 0>0 ? ret 1 : ret 2) : assumption (= ret 3 (ite branchcond 1 ret 2) Is !(ret 3 >= 0) satisfiable? (not (bvsge ret 3 bv 0[32]) : formula true SSA
Querying the Solver $. /z 3 example 1. smt –m 2147483648 0 x 80000000 ret 3 -> bv 2147483648[32] ret 1 -> bv 2147483648[32] branchcond 1 -> false ret 2 -> bv 2147483648[32] x 0 -> bv 2147483648[32] sat int example 1(int x) { … • 32 bits Two’s Complement system – Positive range: [0. . 2 N-1 – 1] – Or: [0 x 00. . 0 x 7 FFFFFFF] – 0 x 80000000 is a negative signed 32 -bit value: -2147483648
Example SSA int example 1(int x) { int ret; if (x > 0) ret = x; else ret = -x; ret 1 = x 0 assert(ret >= 0); return ret; } ret 2 = -x 0 ret 3 = (x 0>0 ? ret 1 : ret 2) Q: Is !(ret 3 >= 0) satisfiable? Assertion violated if x = -2147483648
Slightly Modified Example SSA int example 1(char x) { int ret; if (x > 0) ret = x; else ret = -x; assert(ret >= 0); return ret; } ret 1 = x 0 ret 2 = -x 0 ret 3 = (x 0>0 ? ret 1 : ret 2) Q: Is !(ret 3 >= 0) satisfiable?
Example : extrafuns(x 0 Bit. Vec[32]) : extrafuns(ret 1 Bit. Vec[32]) : extrafuns(ret 2 Bit. Vec[32]) : extrafuns(ret 3 Bit. Vec[32]) : extrapreds(branchcond 1) ret 1 = x 0 : assumption (= ret 1 (sign_extend[24] x 0)) ret 2 = -x 0 : assumption (= ret 2 (bvneg (sign_extend[24] x 0)) : assumption (iff branchcond 1 (bvsgt x 0 bv 0[32]) ret 3 = (x 0>0 ? ret 1 : ret 2) : assumption (= ret 3 (ite branchcond 1 ret 2) Is !(ret 3 >= 0) satisfiable? (not (bvsge ret 3 bv 0[32]) : formula true SSA
Querying the Solver $. /z 3 example 1. smt –m int example 1(char x) { int ret; unsat if (x > 0) ret = x; else ret = -x; No satisfying assignment exists ==> Assertion holds for all possible inputs! assert(ret >= 0); return ret; }
SMT-LIB “Cheat” Sheet: Bit-vectors • Declare 32 -bit “variable” ‘a’: • : extrafuns( a Bit. Vec[32] ) n-bits Sign Extension to ‘a’: sign_extend[n] a • 32 -bit constant ‘ 1234’ • bv 1234[32] • Unary functions: • ~a • -a bvnot (a) bvneg (a) • Binary functions: • bvand bvor bvxor bvadd bvshl bvlshr • & | ^ + << >> Binary predicates: bvsgt bvsge bvfoo (a b) > >=
SMT-LIB “Cheat” Sheet: Booleans • Declare a predicate ‘C’: • : extrapreds( C ) • Unary connectives: • !C not (C) • Binary connectives: • Implies and or xor iff • => && || + foo (C D) ite (C a b) • Ternary connectives: • C? a: b where a, b can be bit-vectors
Exercise: C Operator Precedence a = (b >> c) + d; b = -(a ^ ~c); 1. SSA equations? 2. SMT-LIB formula?
Exercise: C Operator Precedence int a, b; char d; a = (b >> 3) + d; b = -(a ^ ~d); SSA a 1 = (b 0 >> 3) + d 0; b 1 = -(a 1 ^ ~d 0); SMT-LIB : extrafuns(a 1 : extrafuns(b 0 : extrafuns(b 1 : extrafuns(d 0 : assumption(= Bit. Vec[32]) Bit. Vec[8]) a 1 (bvadd (bvlshr b 0 bv 3[32]) (sign_extend[24] d 0)) b 1 (bvneg (bvxor (bvnot (sign_extend[24] d 0) a 1 )))
Additional References • An enjoyable read on verification history: – Vijay D’Silva, Tales from Verification History • More about “constraint solvers”: – Daniel Kroening & Ofer Strichman, Decision Procedures: An Algorithmic Point of View
- Slides: 34