[C2C CTF 2023] ready, set, jump!
Solution
This is a binary, so open it in ghidra decompiler and look for the main function.
You can identify a buffer overflow on line 41 where the program reads an unbounded user input into an array on the stack.
If you dig through the other functions in the binary, you will notice a flag
function that conveniently prints the flag.
All you have to do is create a buffer overflow attack to jump to the function. Notice that in flag
, there is a check right before the call to printf
, so we should be careful to jump to the correct instruction.
Notice that instructions 0x40084f
and 0x400852
correspond to the if
instruction on line 5 of the pseudocode. They compare two values and jump if they’re equal to address 0x400862
, we will need this address later.
Coming back to the main
function, we need to find where return address is stored, so we can overwrite it. Remember, that the x86 calling convention stipulates that the return address is held right above the stack base pointer. If we look at the stack layout, ghidra will tell us that local_48
(the buffer we’re overflowing), is 0x48
(72 in base 10) bytes below the stack base pointer.
So we will need to write 72 random bytes, followed by the instruction address we got earlier.
To craft the input:
- Connect to the remote.
- Send 1 to it to start writing the buffer.
- Send 72 bytes of character
a
, followed by the instruction address0x400862
in little endian format. Follow that with 4 more bytes of 0 to support 64-bit machines (I think…). - Send 2 to make the program return from
main
, triggering our attack.
#!/usr/bin/python3
from pwn import *
conn = remote('redacted', 4949)
a = conn.recvline()
print(a)
conn.sendline(b'1')
conn.sendline(b'a'*72 + b'\x62\x08\x40\x00' + b'\x00'*4)
conn.sendline(b'2')
conn.interactive()
Flag
Let the python script run, you get the flag
FLAG{juMp_iN2_fl4Gz_jurerire}