efficient protection of path sensitive control security
play

Efficient Protection of Path-Sensitive Control Security Ren Ding , - PowerPoint PPT Presentation

Efficient Protection of Path-Sensitive Control Security Ren Ding , Chenxiong Qian, Chengyu Song*, Bill Harris, Taesoo Kim, Wenke Lee Georgia Tech, UC Riverside* What is Control Flow? The order of instruction execution Only limited sets of


  1. Efficient Protection of Path-Sensitive Control Security Ren Ding , Chenxiong Qian, Chengyu Song*, Bill Harris, Taesoo Kim, Wenke Lee Georgia Tech, UC Riverside*

  2. What is Control Flow?  The order of instruction execution  Only limited sets of valid transitions 2

  3. What is Control Hijacking? 3

  4. Control Flow Attacks Still Exist... ATTACK Year DEFENSE Stack smashing Reported Software Flaws - Buffer Errors 1996 Ret2libc 1997 800 Format string 1998 Stack guard canaries Heap overflow Integer overflow 700 2000 Stack cookies W^X 2001 Shadow stack 600 ASLR Info leak to bypass ASLR 2002 500 2003 ProPolice PointGuard 2005 CFI 400 Softbound 2009 CETS 2010 300 Cfimon 2011 Control-flow locking Kbouncer 2013 200 Modular CFI 2014 History-hiding ROP ROPecker Hardware-assisted CFI 100 CPI Opaque CFI 2015 Control-flow bending Per-Input CFI Missing the pointer 0 Context-Sensitive CFI Control Jujutsu 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 COOP Griffin 2017 4 FlowGuard

  5. Control Flow Integrity (CFI)  Lightweight  Runtime Enforcement  Pre-computed valid sets: points-to analysis  Limitations: over-approximation for soundness! 5

  6. Motivating Example 1 void dispatch() { 2 void (*handler)( struct request *) = 0;  Parse request 3 struct request req;  Assign “handler” fptr 4 5 while (1) { o If request from admin: 6 parse_request(&req); 7 handler() = priv — 8 if (req.auth_user == ADMIN) { o else: 9 handler = priv; handler() = unpriv 10 } else { — 11 handler = unpriv;  Strip request args 12 // NOTE. buffer overflow 13 strip_args(req.args);  Handle request 14 } 15 16 handler(&req); 17 } 18 } 6

  7. Motivating Example 1 void dispatch() { high 2 void (*handler)( struct request *) = 0; 3 struct request req; 4 Shellcode 5 while (1) { req dispatch () 6 parse_request(&req); handler 7 libc.so 8 if (req.auth_user == ADMIN) { ret addr 9 handler = priv; 10 } else { 11 handler = unpriv; priv() … 12 // NOTE. buffer overflow … strip_args () 13 strip_args(req.args); 14 } unpriv() 15 low 16 handler(&req); 17 } 18 } 7

  8. Limitation of Traditional CFI • Computes valid transfer sets at 1 void dispatch() { 2 void (*handler)( struct request *) = 0; each location (lack dynamic info) 3 struct request req; 4 5 while (1) { 6 parse_request(&req); parse_request() 7 8 if (req.auth_user == ADMIN) { 9 handler = priv; if admin: priv() else: unpriv() 10 } else { 11 handler = unpriv; 12 // NOTE. buffer overflow 13 strip_args(req.args); handler() 14 } 15 16 handler(&req); 17 } priv() & unpriv() 18 } 8

  9. Per-Input CFI: Most Precise Known CFI • Relies on static analysis for soundness • Instrumentation required • Enable valid target based on execution history for addresses that are taken 9

  10. Limitation of Per-Input CFI • Once transfer targets enabled, 1 void dispatch() { 2 void (*handler)( struct request *) = 0; cannot be eliminated 3 struct request req; 4 5 while (1) { 6 parse_request(&req); parse_request() 7 8 if (req.auth_user == ADMIN) { 9 handler = priv; if admin: priv() else: unpriv() 10 } else { 11 handler = unpriv; 12 // NOTE. buffer overflow 13 strip_args(req.args); handler() 14 } 15 16 handler(&req); 17 } priv() & unpriv() priv() 18 } 10

  11. PITTYPAT: Path-Sensitive CFI • At each control transfer, verify 1 void dispatch() { 2 void (*handler)( struct request *) = 0; based on points-to analysis of 3 struct request req; whole execution path 4 5 while (1) { 6 parse_request(&req); parse_request() 7 8 if (req.auth_user == ADMIN) { 9 handler = priv; 10 } else { if admin: priv() else: unpriv() 11 handler = unpriv; 12 // NOTE. buffer overflow 13 strip_args(req.args); 14 } handler() 15 16 handler(&req); 17 } unpriv() priv() 18 } 11

  12. Assumptions  Current approach only examines control security  Non-control data is out of scope  Not a memory safety solution 12

  13. Challenges  Collecting executed path information and share for analysis efficiently  Trace information cannot be tampered  Compute points-to relations online both efficiently and precisely 13

  14. Our Solution Per Challenge  Intel Processor Trace (PT)  Incremental Online Points-to Analysis 14

  15. Intel Processor Trace  Low-overhead commodity hardware  Compressed packets to save bandwidth  CR3 filtering  Trace information shared & protected efficiently 15

  16. Incremental Points-to Analysis  Input: LLVM IR of target program o Metadata of mapping between IR and binary o Runtime execution trace o  Output: points-to relations on a single execution path 16

  17. Things Differentiate Our Analysis  Traditional static points-to analysis reasons about all paths for soundness  Instead, we only reasons about points-to relation on one single path  Maintain shadow callstack of instructions executed  Most precise enforcement based on control data only 17

  18. System Overview  Monitor Module: Kernel-space driver for PT o Shares taken branch information o  Analyzer Module: User-space o Updates points-to relation based on trace o 18

  19. Challenging Language Features • Signal handling • Setjmp/Longjmp • Exception Handling 19

  20. Signal Handling ; Function Attrs: nounwind uwtable define void @SIGKILL_handler(i32 %signo) #0 { entry: ... if.then: ; preds = %entry ... if.else: ; preds = %entry ... if.end: ; preds = %if.else, %if.then ret void } ; Function Attrs: nounwind uwtable define i32 @main() #0 { entry: %call1 = call void (i32)* @signal(i32 9, void (i32)* @SIGKILL_handler) #3 ret i32 0 } 20

  21. Setjmp/Longjmp ; Function Attrs: nounwind uwtable define void @hello() #0 { entry: ... call void @longjmp(%struct.__jmp_buf_tag* getelementptr inbounds ([1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* @resume_here, i32 0, i32 0), i32 1) #4 ... } ; Function Attrs: nounwind uwtable define i32 @main() #0 { entry: ... %call1 = call i32 @_setjmp(%struct.__jmp_buf_tag* getelementptr inbounds ([1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* @resume_here, i32 0, i32 0)) #5 ... 21

  22. Exception Handling ; Function Attrs: norecurse uwtable define i32 @main() #4 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { entry: ... %call = invoke i32 @_Z3foov() to label %invoke.cont unwind label %lpad invoke.cont: ; preds = %entry br label %try.cont lpad: ; preds = %entry %0 = landingpad { i8*, i32 } catch i8* bitcast (i8** @_ZTIi to i8*) catch i8* bitcast (i8** @_ZTIc to i8*) catch i8* null ... 22

  23. Optimizations on Analysis  Only analyzing about calling context  Maintains current executing IR block along with execution To avoid decoding of PT traces and translation from binary address o to IR  Only analyze control-relevant functions and instructions 23

  24. Evaluation  Are benign applications satisfying path-sensitive CFI less susceptible to control hijacking attacks?  Do malicious applications that satisfy weaker CFI mechanisms fail to satisfy current solution?  Can we achieve path-sensitive CFI efficiently? 24

  25. Forward Edge Points-to Set Size 25

  26. RIPE  Contains various vulnerabilities that can be exploited to hijack control flow  Passed all 264 benchmark suites that compiled in the testing environment 26

  27. Performance Overhead 50% pi-CFI PittyPat 40% 30% 20% 12.73% 10% 3.3% 0% 27

  28. Limitations  Non-control data corruption can not be detected  Not reasoning about field sensitiveness for points-to analysis  Performance might not be ideal as a CFI solution 28

  29. Conclusion  Define path-sensitive CFI  Deploy practical mechanism for enforcement  Strictly stronger security guarantees  Acceptable runtime overhead in security critical settings 29

Recommend


More recommend