Return-to-libc Josh Cooper Portland State University Shellcode Attacker injects shellcode into stack buffer Return address changed via buffer overflow But… Non-Executable Stack Prevents program from executing instructions off of the stack Can be enforced on per page table or segment basis No more buffer overflows, right? Wrong, return-to-libc Want to execute: system(“/bin/sh”); Create pseudo stack-frame Overwrite return address with system()’s address When vulnerable function returns, we jump to system() Stack 0xFFFFFFFF 0x08048344 addr ”/bin/sh” param #1 0x080482a4 RET padding SBP stack buffer 0x080482a4 <system> 0x08048354 0x08048350 0x0804834c 0x08048348 0x00000000 Resolving Address of system() Register handler for user-signal Fork child and wait for child to signal Attach to child Single-step child until it calls system() Assumes high-order byte of system() address is different than main Resolving Address of “/bin/sh” First call to setjmp sets step=-1 Starting from system(), search lower addresses If seg fault occurs, handler sets step=+1 and does longjmp Longjmp causes execution to begin from last setjmp. Starting from system(), search higher addresses If seg fault again, abort Address of system can’t contain NULL Memory Alignment Naïve 12-byte pattern requires testing 0…11 byte alignment Uses 16-byte pattern instead – only 8 tests required: addr “/bin/sh” addr “/bin/sh” addr “/bin/sh” addr “/bin/sh” addr system() addr system() addr system() addr system() <align> + 4 <align> 0,1,2,3,8,9,10,11 4,5,6,7,12,13,14,15 Setuid Setuid program may drop privileges, so exploit may need to reacquire before invoking system(): Return to setuid Return to system Return to 0 addr ”/bin/sh” addr ”/bin/sh” addr ”/bin/sh” addr UID(0) addr UID(0) addr UID(0) addr system addr system addr setuid Kernel Patch mmap shared libraries to an address that contains 0-byte Prevent attacker from passing parameter 0x08048354 0x08048350 0x0804834c addr ”/bin/sh” 0x080082a4 padding 0x08048348 0x08048344 0x080082a4 <system> However There are techniques for making multiple function calls: esp-lifting and frame faking If exploit string can cause return-to-PLT (procedure linkage table) for strcpy (sprintf, or scanf) then it can write NULL bytes in the address of system(), and return-to-system