Hacking Blind Andrea Bittau, Adam Belay, Ali Mashtizadeh, David Maziéres, Dan Boneh Buffer Overflows • Attacker sends data bigger than the buffer, the excess data overwrites memory beyond the buffer • Stack buffer overflows are the easiest attack to succeed with because return addresses are implicitly close in memory • Code Injection Attack - the attacker includes malicious code as a part of the payload then simply sets the return address to the code that was injected as part of the payload • Modern OS’s though mark data memory pages as nonexecutable (NX on X86) Address Space Layout Randomization • Randomizes the location of code and data memory segments in the process address space • Makes it hard to predict the location of code or even the stack in advance • On 32 bit platforms usually only 16 bits for randomization • Easy to Brute force attack it • 64-bit systems have too many random bits to effectively brute force • Canaries – A secret value is determined in advance and placed before each saved frame pointer and return address • When a function is returned the canaries are checked, if it has changed an attacked has been detected and the program terminates • Canaries are guessed one byte at a time • If canaries rerandom after every crash then ROP attacks are impossible Return-Oriented Programming (ROP) • Developed to defeat NX memory • Relies on collecting gadgets • Gadgets are machine instruction sequences already on the machine • Return into Library – A high level library function such as system() is set as the return address • 64 bit systems arguments are passed in registers so gadgets are need to populate registers • To defeat NX the attacker must know of where gadgets reside in the program executable • To defeat ASLR the attacker must derandomize the location at which the executable’s text segment is actually loaded into memory • The first requirement generally means you need to have a binary available for 64 bit • If Position Independent Executables (PIE) is enabled on a linux device the entire address space is randomized • Registers rdi and rsi control the first 2 arguments of to systems calls • Register rax controls controls the system call number • Registers can be controlled by using pop gadgets and placing the value to load on the stack Blind Remote Oriented Programming (BROP) • We assume a stack vulnerability and knowledge of how to trigger it • A server application that restarts after a crash • Phases of a BROP attack – Stack Reading: read the stack to leak canaries and a return address to defeat ASLR – Blind ROP: Find enough gadgets to invoke write and control its arguments you can now transfer the binary – Build the exploit: Dump enough of the binary to find enough gadgets to build a shellcode, and launch the exploit Finding Gadgets • Remotely scan the applications text segment bye overwriting the saved return address • The program will either crash or continue running, if it continues running you have found a gadget • A stop gadget is a gadget which suspends program execution but keeps the connection running – like sleep or an infinite loop • Stop gadgets are placed after the adress you are scanning, 2 are needed to keep pop from crashing • Probe – the address being scanned • Stop – The address of a stop gadget that will not crash • Trap – The address of non-executable memory that will cause a crash • The idea is to vary the position of stops and traps on the stack to deduce what the gadget being probed is – Probe, stop, trap, trap ….. Will find gadgets that do not pop the stack like ret or xor – Probe, trap, stop, trap, trap…. Will find gadgets that pop exactly one thing off the stack like pop rax; ret or pop rdi; ret Finding the PLT • Each entry is 16 bytes apart • Most PLT entries will not cause a crash since they are system calls • The PLT is found by scanning from the programs origin • The PLT can be verified by setting a prode stop trap and also by using offsets of six bytes to use the PLT slowpath • To control the third argument one needs to find a call to strcmp which sets rdx to the length of the string compared • To identify PLT entries we control the first two arguments using the gadgets we found earlier and we see how the function responds – – – – Strcmp(bad, bad): Crash Strcmp(bad, readable): Crash Strcmp(readable, bad): Crash Strcmp(readable, readable): No Crash • Now that we can control the first three arguments finding write is trivial because we just scan through the PLT entries and force a write to the socket, if a write occurs the location has been found Summary • Find where the executable is loaded. Either 0x400000 for non-PIE executables or stack read a saved return address • Find a stop gadget. Like sleep or read. The attacker also finds the PLT at this point • Find the BROP gadget. • Find strcmp in the PLT. • Find write in the PLT. Dump the binary to find more gadgets • Build a shell code and exploit the server • If there is no BROP gadget or PLT the attack instead goes: – Find all pop x; ret gadgets – Find a syscall gadget – Identify the pop gadgets