280 likes | 361 Views
Learn about preventing exploits using live binary rewriting, patching algorithms, and dynamic enforcement strategies. Evaluation and limitations are discussed.
E N D
Echo-3: IDS / Self Patching Hard Opening Kyle Soska Tiffany Bao Steve Matsumoto Alan Keith
Introduction • Problem: Prevent an application from being owned by an exploit • Issue: Execution monitors exist and can detect exploited states but require rollback, exploits can be replayed for DOS attack • Idea: Use binary rewriting live to prevent application from reaching exploited state while preserving normal behavior
Main Contributions • Learning algorithm to generate constraints on “normal” runs of a program • Patch generation algorithms to converge on a working patch • Patching engine to dynamically enforce generated patches • Evaluation of various generation algorithms
Key Intuition • Malicious inputs cause the program state to be different (abnormal) in some way • Out of bounds array indexes in buffer overflow • Create and enforce “normal” during key points of execution • Taint analysis may be useful, looking for things that are affected by input
System Diagram Execution Monitor Vulnerable Program Taint Trace Rollback Exploit Detected Tainted Input Suspend Patch Engine Decision Engine Resume Training Data
Recording Traces • Pin/BAP • Record standard trace and grep for information
Recording Traces • Register dump • Record each register value at every step
Patching • Use ptrace to make a custom debugger • Launch process and break on entry • Breakpoint all the patch locations • Apply constraints / rectify when breakpoints are hit
Patching EIP = 2 Vulnerable Program Custom Debugger Rule: @ EIP = 3, constraint 1 Rule: @ EIP = 5, constraint 2 Rule: @ EIP = 6, constraint 3
Patching Vulnerable Program Custom Debugger EIP = 3 Rule: @ EIP = 3, constraint 1 Rule: @ EIP = 5, constraint 2 Rule: @ EIP = 6, constraint 3
Patching Vulnerable Program Custom Debugger Rule: @ EIP = 3, constraint 1 EIP = 4 Rule: @ EIP = 5, constraint 2 Rule: @ EIP = 6, constraint 3
Patching Vulnerable Program Custom Debugger Rule: @ EIP = 3, constraint 1 Rule: @ EIP = 5, constraint 2 EIP = 5 Rule: @ EIP = 6, constraint 3
Patching Vulnerable Program Custom Debugger Rule: @ EIP = 3, constraint 1 Rule: @ EIP = 5, constraint 2 Rule: @ EIP = 6, constraint 3 EIP = 6
What to patch? • List of registers and memory addresses with corresponding rules • A rule is a list of constraints: ==, <, >, <=, >=, !=, constraint value, and rectification value • Example: Reg = eax, constraints = <, >, values = 10, 100, rectification = 50 • if(eax < 10 || eax > 100) eax = 50; Before instruction i: if not <constraint> then modify()
Generating Constraints • Trace 1: EIP = 0x12345678, eax = 10 • Trace 2: EIP = 0x12345678: eax = 15 • Trace 3: EIP = 0x12345678: eax = 20 • Dictionary keyed by EIP: • @ EIP = 0x12345678: eax = {10, 15, 20} • Constraint: 10 <= eax <= 20
Implicit Flow Case intx, y, val= TAINT_DATA inti = j = 0; char pic[20*20]; //Size error on array bounds if(x <= 20) return; if(y <=20) return; while(1) { if(i == x) break; i++; } while(1) { if(j == y) break; j++; } pic[j*20 + i] = val; //Dangerous calculation Tainted input assumes “normal values” Implicit Flow Normal constraints violated by untainted data
Decision Engine Decision Engine Constraint-based Decision Existence-based Decision Normal Constraints Patches Malicious Trace
Patching Strategy • Heuristic: • Conservative rectification: if value doesn't satisfy, rectify it to an existed value 'eax': {'<=': 3086889985L, '>=': 3086889729L}} [3086889729L, 3086889985L 3086889730L, 3086889729L, 3086889729L, 3086889729L, 3086889740L 3086889730L, 3086889985L, 3086889729L, 3086889730L 3086889985L, 3086889985L, 3086889729L, 3086889729L] 'eax': [3086889729L, 3086889986L]
Results / Evaluation • Patches were generated for all tested apps • Simple buffer overflow (2 variants) • Implicit Flow Example
Patching Results • Buffer Overflow Variant 1 • 1st successful patch in 40 seconds • 21 successful patches found • Buffer Overflow Variant 2 • 1st successful patch in 24 seconds • 33 successful patches found • Implicit Flow • 1st successful patch in 51 seconds • ?? successful patches found
Limitations • Patches that require changing multiple instructions • Exploits where no variables are abnormal, but rather a relationship between variables is • Relationship between index and buffer size • Programs that look different on every launch • Clock /Date always larger than previously observed
Conclusion • Relationships require more analysis • Analysis to determine variables would be useful • Hundreds of patches are attempted for each patch that succeeds • Determining if patches are correct is an open problem
Future Work • Does min/max always make sense? • {4, 6, 8, 10, 12, 12, 16, 19} • {7, 7, 7, 7, 7, 14, 14, 14, 14, 14} • {0x8001000,0x8001000, 0x8001000, 0x8001000, 0x8001000, 0x8001000} • Variable might be array length, or pointer