Size Does Matter Why Using Gadget-Chain Length to Prevent Code-reuse Attacks is Hard Enes Göktaş - Elias Athanasopoulos - Michalis Polychronakis Herbert Bos - Georgios Portokalidis presented by: Flora Karniavoura Katerina Karagiannaki Irini Stavrakantonaki
Code-reuse Attacks ● Exploits: ○ Return-to-libc ○ Return-Oriented Programming ( ROP ) ○ Jump-oriented Programming ○ Sigreturn Return Oriented Programming (SROP) ● ROP Defences: ○ Data Execution Protection (DEP) ○ Adress Space Layout Randomization ( ASLR ) ○ Stack Smashing Protection (SSP) ○ Control Flow Integrity ( CFI )
ROP & Gadgets ● Gadgets: Call-site Gadget (CG) Entry-point Gadget (EG) ● Gadget chains
ROP Defence Mechanisms ● Intel’s LBR ( L ast B ranch R ecord) registers: ○ Track indirect branches & detect attacks ○ “ too many indirect branches to short gadgets”. ● Tools using LBR: kBouncer attacks → must chain a significant number ❏ ROPecker of small gadgets ❏
Defining Thresholds Alarming gadget chain: T C or more gadgets with a length of at most T G instructions each .
Weaknesses ❖ Gadget’s #instructions > T G ? → Gadget not detected ❖ T C gadgets of at most T G instructions ? → False Positive (FP) ➔ Larger T C or smaller T G → ROP attacks difficult but more FPs. What is the right size?
kBouncer ● Detects sensitive API calls (e.g. VirtualProtect()). ● Scans LBR registers to determine call source. ○ If source == ROP gadget chain, terminate proccess. ● Identifies abnormal function returns. ○ Checks if targets of return instructions in LBR preceded by a call ! ROP attacks achieved even with gadgets following intended calls. ● Gadget-Chain length: T G = 20 , T C = 8
ROPecker ● Checks LBR registers more often ○ Sliding window of executable code, check when control flow outside the window (Permission fault) ● Gadget-chain length ○ ROPecker Gadget definition: 1. Ends with indirect branch 2. Does NOT contain direct branches 3. T G = 6, T C = 11 ! Multiple smaller gadget chains mixing long and short gadgets ● Uses multiple windows T CC = 14 . T CC : cumulative gadget length (check every 3 windows).
The Problem I ● What is the right size? Attackers bypass kBouncer, ROPecker Detectable Gadgets
The Problem II ● Evade kBouncer ROP payload of Call-Preceded Gadgets ● Evade ROPecker Uses T cc but: Sequences with direct branches Gadgets ⇒ Build short Undetectable Gadgets (UG) using direct branches.
Proof-of-Concept Attack Vulnerability & Preparation Vulnerability: a real heap-overflow in IE8 How : accessing span and width attributes of an HTML column table through JavaScript. Exploit: ● Bypasses: kBouncer, DEP, ASLR ● Controls the target address of an indirect jump instruction ● Undetectable ! ○ Short ROP payload ○ Detected only if TC,TG are restricted → Can be triggered several times! 1. Overwrite size of a string to read data beyond its boundaries 2. Overwrite Virtual Function Table (VFT) pointer within a button object 3. Control indirect jump via access to button
Proof-of-Concept Attack Preparation Bypass ASLR using the previous steps Goal: read a pointer to “shell32.dll” to locate VirtualProtect() → change memory permissions → inject executable shellcode
Proof-of-Concept Attack Collecting Gadgets - How to find usable gadgets? Disassemble the target binary multiple times until we encounter a stop condition (indirect control flow transfer, invalid or privileged instruction) ● Direct branches → Follow path ○ Gadget length : shortest number of instructions from the beginning till an indirect branch ● Conditional branches → Follow both paths ○ Gadget length : shortest path
Proof-of-Concept Attack Heuristic Breakers Remember: kBouncer Tc = 8 -> Use no more than 7 short gadgets ● Long gadgets → minimal work (i.e. set a single register) ○ Intersperse the ROP chain → kBouncer does not detect them ● Position of HB: flexibility needed depending on exploit’s semantics
Proof-of-Concept Attack Putting It All Together 1. Control of an indirect jump 2. Stack pivoting point the stack pointer (esp) to our buffer to perform ROP exchange eax and esp → terminate with ret 3. Interpose a HB gadget use it at this point to reset Tc, other entries in LBR→ detection 4. Indirect call gadget to call VirtualProtect() kBouncer check does not detect attack everything is OK → VirtualProtect returns after the “call” 5. Code following indirect call ret → transfers control to our executable shellcode
Proposed Countermeasures T C , T G Parameters (I) T G →more app execution paths as gadgets→ longer gadgets chains T C →to avoid pass control flow as attack ⇒ attacks use more gadgets 1. Per-Application: different T G , T c strictest rules→Avoids FPs gadgets larger than T G →chained together→No chains identified! 2. Per-Call: different T C / part of code executing kBouncer: great benefit (check certain API calls) avoids FPs security, stability
Proposed Countermeasures T C , T G Parameters (II) 3. Cumulative Chain-Length Calculation: ROPecker: uses T CC (for smaller gadgets-chains) Not effective in this exploit. 4. Recursive functions→large num of return s→hard to set T C a. kBouncer: i. Only checks LBR for API calls → “away” from algorithms b. ROPecker: i. Checks every transfer to new pages→more fragile
Proposed Countermeasures CFI CFI→ can prevent this exploit ● CCFIR Prevent use of unintended gadgets Low performance overhead→couple with kBouncer ● binCFI Vulnerable to attack CCFIR with kBouncer ? → Exploit used to bypass CFI ● Replace smaller gadgets → longer HB gadgets (allowable by CFI) ● As CFI does not allow transfers to new code ○ mark code as writable ○ overwrite it with our shellcode
Proposed Countermeasures CCFIR with kBouncer: Is it still vulnerable? (I) CCFIR: ● Prevents use of unintended gadgets ○ No indirect calls to API calls ( VirtualProtect() ) ○ Need to use direct calls! blocks 2 gadgets of our exploit! ● Return instructions→ not transfer control to unintended gadgets ○ use only CS gadgets ● Indirect calls / jumps → restricted ○ transfer control to EP gadgets .
Proposed Countermeasures CCFIR with kBouncer: Is it still vulnerable? (II) 2nd exploit: previous one + bypassing CCFIR ● Stack Pivoting: 5 gadgets ○ 1-3 EP gadgets: corrupt stack→take control of return instr ○ 4th: loads ebp with pointer to our sprayed buffer ○ 5th: stack pivoting gadget→copy ebp to esp ● HB gadget → prepares ebp , ebx ● Call VirtualProtect ()→gadgets used against CFI ● HB gadget → prepares eax ● Call memcpy () → gadgets used against CFI ● Last gadget’s return → control to our shellcode ○ shellcode ⇒ code area of binary ⇒ Still undetected attacks even with tweaked Tc, T G
Evaluation Gadget Availability How many gadgets of different sizes apps contain? All gadgets CP gadgets even for large gadget sizes of 60 instructions → numerous gadgets
Evaluation Per-Application Parameters Do apps benefit from using tighter parameters?
Conclusion ★ Choosing the right thresholds for ROP detection is difficult ! ★ The “ long gadgets are not usable ” assumption is broken. ★ Define parameters per-application → ease problem. We need better tools to evaluate our defenses
Recommend
More recommend