CSE 351 - Spring 2010 - Section 6

Buffer Overflow Lab Tips

Workflow

Working on the buffer overflow lab will generally follow this pattern for each level/phase.

Multiple Terminal Windows

I usually find it helpful to open multiple terminal windows when debugging a program with GDB.

hexdump

You can verify that the ASCII characters you supplied to sendstring really produce the correct hexadecimal bytes.

> hexdump -C something.bytes
00000000 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 0a |?.?..???..?5....|

Markers

If you analyze the disassembly cleverly enough, you can figure out where the buffer begins. However, I prefer trial and error since the buffer is so small.

To do this, send a recognizable pattern into the program and then try to find it in memory using gdb. I use bytes like "11 22 33 44", which translate to the hex bytes 0x11, 0x22, 0x33, 0x44, etc.

Program Counter

How can you figure out what instruction you are currently at? Sometimes gdb will not tell you after stepping, especially if you are at the beginning of a function.

(gdb) print $pc
$4 = (void (*)()) 0x8048b31 <getbuf+17>

Draw the Stack

What I found useful in doing this lab was drawing a picture of the stack, as I stepped through the assembly of the getbuf function, using "x" after stepping into the right point in the disassembly, and observing how the stack changed after each instruction.

(gdb) x/40x $esp
0xbfffb310: 0xbfffb324 0xbfffb350 0x45e1ede6 0x45e30818
0xbfffb320: 0xb7fe72d8 0x33221100 0x77665544 0xbbaa9988
0xbfffb330: 0xffeeddcc 0x33221100 0x77665544 0x08048abc
0xbfffb340: 0x1039ac00 0x00000000 0xbfffb368 0x45e7da70
0xbfffb350: 0xbffff558 0x45e7da70 0x45f9f4c0 0xdeadbeef
0xbfffb360: 0xbfffb374 0x0804b018 0xbffff558 0x08048c51
0xbfffb370: 0x08049264 0x000000f4 0x00004180 0x00000000
0xbfffb380: 0xf4f4f4f4 0xf4f4f4f4 0xf4f4f4f4 0xf4f4f4f4
0xbfffb390: 0xf4f4f4f4 0xf4f4f4f4 0xf4f4f4f4 0xf4f4f4f4
0xbfffb3a0: 0xf4f4f4f4 0xf4f4f4f4 0xf4f4f4f4 0xf4f4f4f4

You can drawing the stack in the following form to label important points, like the beginning of the buffer, the return address, etc.

0xbfffb33c0xblahblah
0xbfffb3380xblahblah
0xbfffb3340xblahblah
0xbfffb3300xblahblah
0xbfffb32c0xblahblah
0xbfffb3280xblahblah
0xbfffb3240xblahblah
0xbfffb3200xblahblah
0xbfffb31c0xblahblah
0xbfffb3180xblahblah
0xbfffb3140xblahblah
0xbfffb3100xblahblah

Function Addresses

Let's say, out of idle curiosity, you wanted to find the beginning address of a function. How would you do it?

(gdb) disas getbuf
Dump of assembler code for function getbuf:
0x08048b20 <getbuf+0>: push %ebp
0x08048b21 <getbuf+1>: mov %esp,%ebp
0x08048b23 <getbuf+3>: sub $0x28,%esp
0x08048b26 <getbuf+6>: lea -0x14(%ebp),%eax
0x08048b29 <getbuf+9>: mov %eax,(%esp)
0x08048b2c <getbuf+12>: call 0x8048990 <Gets>
0x08048b31 <getbuf+17>: mov $0x1,%eax
0x08048b36 <getbuf+22>: leave
0x08048b37 <getbuf+23>: ret
End of assembler dump.