CS457 – Introduction to Information Systems Security Software 4 Elias Athanasopoulos
Defending ROP Randomization - Address Space Layout Randomization (ASLR) - Fine-grained Randomization (Smashing the gadgets, Binary Stirring) Control Flow Integrity (CFI) Run-time Detection - Based on H/W features (kBouncer) CS-457Elias Athanasopoulos2
Control-flow Graph CS-457Elias Athanasopoulos3 Direct call of sort() Indirect call of lt()/gt() All ret instructions are indirect branches! Can you spot other indirect branches?
Enforcing CFI (1) Things we don’t care about CS-457Elias Athanasopoulos4 Direct call of sort() Direct calls: cannot controlled by attacker (fixed targets) Do nothing!
Enforcing CFI (2) Forward Edges CS-457Elias Athanasopoulos5 Indirect call of lt()/gt() R: target Legitimate targets: lt(),gt() CFI: make sure only legitimate targets are exercised Attack: redirect R to a Gadget R: target Legitimate targets: lt(),gt() CFI: make sure only legitimate targets are exercised Attack: redirect R to a Gadget Attach label to indirect call: l7 Check label on function entry points Result: R is coupled only with legitimate targets, lt(),gt() - The call in sort() can only reach lt(),gt() - lt(),gt() can only be reached by the call in sort() Result: R is coupled only with legitimate targets, lt(),gt() - The call in sort() can only reach lt(),gt() - lt(),gt() can only be reached by the call in sort()
Implementation Example CS-457Elias Athanasopoulos6
Enforcing CFI (3) Backward Edges CS-457Elias Athanasopoulos7 All ret instructions are indirect branches! Call site (instruction after a call) (1) Add labels to call sites (2) check if we return from the correct returns (1) Add labels to call sites (2) check if we return from the correct returns Call site (instruction after a call)
Ideal CFI CS-457Elias Athanasopoulos8 Two problems: 1)CFG discovery (especially in legacy apps) 2)Performance in checks Two problems: 1)CFG discovery (especially in legacy apps) 2)Performance in checks
Coarse-grained (loose) CFI CS-457Elias Athanasopoulos9 Two labels only: 1)One for ensuring an indirect call enters a function entry point 2)One for ensuring a ret returns to a call site Two labels only: 1)One for ensuring an indirect call enters a function entry point 2)One for ensuring a ret returns to a call site
Gadgets under coarse-grained CFI CS-457Elias Athanasopoulos10
Linking Gadgets under CFI CS-457Elias Athanasopoulos11
Exploitation under CFI CS-457Elias Athanasopoulos12
CS-457Elias Athanasopoulos13
Last Branch Record (LBR) 16 pairs of H/W registers Used for debugging They store the last occurred branches Can be configured to store only indirect branches CS-457Elias Athanasopoulos14
kBouncer CS-457Elias Athanasopoulos15
Normal vs ROP CS-457Elias Athanasopoulos16
kBouncer Checks call-ret pairing - Coarse-grained CFI Heuristics - Up to 20 instructions is considered a gadget - 6 gadgets in a row is considered an attack CS-457Elias Athanasopoulos17
kBouncer Heuristics CS-457Elias Athanasopoulos18
Bypassing kBouncer CS-457Elias Athanasopoulos19
kBouncer bypass PoC CS-457Elias Athanasopoulos20
Other Software Vulnerabilities Use-after-free and dangling pointers Integer overflows CS-457Elias Athanasopoulos21
Use-after-free CS-457Elias Athanasopoulos22 P1 P2 Object A t0: P1 and P2 point to A t1: P1 is freed Free space NULL P2 still points to, it is a dangling pointer New Object t2: attacker allocates space New Object t3: P2 now points to a new Object! New Object 1) New object is of different type 2) P2->foo() can execute attacker’s code in the new object 1) New object is of different type 2) P2->foo() can execute attacker’s code in the new object
Integer Overflows off_t j, pg_start = /* from user space */; size_t i, page_count =... ; int num_entries =... ; if (pg_start + page_count > num_entries) return –EINVAL;... for (i = 0, j = pg_start; i<page_count; i++,j++) /* write to some address with offset j */; CS-457Elias Athanasopoulos23
Integer Overflows (fix) off_t j, pg_start = /* from user space */; size_t i, page_count =... ; int num_entries =... ; if ((pg_start + page_count > num_entries) || (pg_start + page_count < pg_start)) return –EINVAL;... for (i = 0, j = pg_start; i<page_count; i++,j++) /* write to some address with offset j */; CS-457Elias Athanasopoulos24