Unsorted Bin Attack
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
๊ธฐ๋ณธ ์ ๋ณด
์์ธํ ๋ด์ฉ์ unsorted bin์ด ๋ฌด์์ธ์ง ์ด ํ์ด์ง๋ฅผ ํ์ธํ์ธ์:
Unsorted ๋ฆฌ์คํธ๋ ์ฒญํฌ์ bk ์ฃผ์์ unsorted_chunks (av)์ ์ฃผ์๋ฅผ ์ธ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ๊ณต๊ฒฉ์๊ฐ unsorted bin ์์ ์ฒญํฌ์์ bk ํฌ์ธํฐ์ ์ฃผ์๋ฅผ ์์ ํ ์ ์๋ค๋ฉด, ๊ทธ๋ ๊ทธ ์ฃผ์๋ฅผ ์์์ ์ฃผ์์ ์ธ ์ ์๊ฒ ๋์ด Glibc ์ฃผ์๋ฅผ leak ํ๊ฑฐ๋ ์ผ๋ถ ๋ฐฉ์ด๋ฅผ ์ฐํํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
์์ฝํ์๋ฉด, ์ด ๊ณต๊ฒฉ์ ์์์ ์ฃผ์์ ํฐ ์ซ์ ํ๋๋ฅผ ์ค์ ํ ์ ์๊ฒ ํฉ๋๋ค. ์ด ํฐ ์ซ์๋ ํ ์ฃผ์๋ Glibc ์ฃผ์์ผ ์ ์์ต๋๋ค. ์ ํต์ ์ธ ๋ชฉํ๋ ๋ ํฐ ์ฌ์ด์ฆ์ fast bin์ ๋ง๋ค๊ธฐ ์ํด global_max_fast ์์ต๋๋ค(์ฆ unsorted bin attack์์ fast bin attack์ผ๋ก ์ ํํ ์ ์๊ฒ ํด์ค).
- Modern note (glibc โฅ 2.39):
global_max_fastbecame an 8โbit global. Blindly writing a pointer there via an unsorted-bin write will clobber adjacent libc data and will not reliably raise the fastbin limit anymore. Prefer other targets or other primitives when running against glibc 2.39+. See โModern constraintsโ below and consider combining with other techniques like a large bin attack or a fast bin attack once you have a stable primitive.
Tip
T> aking a look to the example provided in https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle and using 0x4000 and 0x5000 instead of 0x400 and 0x500 as chunk sizes (to avoid Tcache) itโs possible to see that nowadays the error
malloc(): unsorted double linked list corruptedis triggered.Therefore, this unsorted bin attack now (among other checks) also requires to be able to fix the doubled linked list so this is bypassed
victim->bk->fd == victimor notvictim->fd == av (arena), which means that the address where we want to write must have the address of the fake chunk in itsfdposition and that the fake chunkfdis pointing to the arena.
Caution
์ด ๊ณต๊ฒฉ์ unsorted bin(๋ฐ๋ผ์ small, large๋ ํฌํจ)์ ์์์ํต๋๋ค. ๋ฐ๋ผ์ ์ด์ ์ฐ๋ฆฌ๋ fast bin์์์ ํ ๋น๋ง ์ฌ์ฉํ ์ ์์ต๋๋ค(๋ ๋ณต์กํ ํ๋ก๊ทธ๋จ์ ๋ค๋ฅธ ํ ๋น์ ํ์ฌ ์ถฉ๋ํ ์ ์์). ๊ทธ๋ฆฌ๊ณ ์ด๋ฅผ ํธ๋ฆฌ๊ฑฐํ๋ ค๋ฉด ๊ฐ์ ํฌ๊ธฐ๋ฅผ ํ ๋นํด์ผ ํ๋ฉฐ, ๊ทธ๋ ์ง ์์ผ๋ฉด ํ๋ก๊ทธ๋จ์ด ํฌ๋์ํฉ๋๋ค.
global_max_fast๋ฅผ ๋ฎ์ด์ฐ๋ฉด ์ด ๊ฒฝ์ฐ ๋์์ด ๋ ์ ์์ผ๋ฉฐ, fast bin์ด ์ต์คํ๋ก์์ด ์๋ฃ๋ ๋๊น์ง ๋ค๋ฅธ ๋ชจ๋ ํ ๋น์ ์ฒ๋ฆฌํ ์ ์๋ค๊ณ ๊ฐ์ ํ๋ ์ ๋ต์ด ๊ฐ๋ฅํฉ๋๋ค.
guyinatuxedo์ ์ฝ๋๋ ์ด๋ฅผ ๋งค์ฐ ์ ์ค๋ช
ํฉ๋๋ค. ๋ค๋ง malloc๋ค์ Tcache์ ๋น ์ง์ง ์๋๋ก ์ถฉ๋ถํ ํฐ ๋ฉ๋ชจ๋ฆฌ๋ก ๋ฐ๊พธ๋ฉด ์์ ์ธ๊ธํ ์ค๋ฅ์ธ malloc(): unsorted double linked list corrupted ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
์ค์ ์ฐ๊ธฐ๊ฐ ์ผ์ด๋๋ ๋ฐฉ์
- Unsorted-bin ์ฐ๊ธฐ๋
free์์, ํด์ ๋ ์ฒญํฌ๊ฐ unsorted ๋ฆฌ์คํธ์ ํค๋์ ์ฝ์ ๋ ๋ ๋ฐ์ํฉ๋๋ค. - ์ฝ์
๋์, allocator๋
bck = unsorted_chunks(av); fwd = bck->fd; victim->bk = bck; victim->fd = fwd; fwd->bk = victim; bck->fd = victim;๋ฅผ ์ํํฉ๋๋ค. - ๋ง์ฝ
free(victim)์ ํธ์ถํ๊ธฐ ์ ์victim->bk๋ฅผ(mchunkptr)(TARGET - 0x10)์ผ๋ก ์ค์ ํ ์ ์๋ค๋ฉด, ๋ง์ง๋ง ๋ฌธ์ฅ์ด ์ฐ๊ธฐ๋ฅผ ์ํํฉ๋๋ค:*(TARGET) = victim. - ์ดํ allocator๊ฐ unsorted bin์ ์ฒ๋ฆฌํ ๋, ์ ํฉ์ฑ ๊ฒ์ฌ๋ก ์ธ๋งํฌํ๊ธฐ ์ ์
bck->fd == victim๊ณผvictim->fd == unsorted_chunks(av)๊ฐ์ ๊ฒ๋ค์ ํ์ธํฉ๋๋ค. ์ฝ์ ์ ์ด๋ฏธbck->fd(์ฐ๋ฆฌ์TARGET)์victim์ ์ผ๊ธฐ ๋๋ฌธ์, ์ด ์ฐ๊ธฐ๊ฐ ์ฑ๊ณตํ๋ค๋ฉด ์ด๋ฌํ ๊ฒ์ฌ๋ ๋ง์กฑ๋ ์ ์์ต๋๋ค.
ํ๋์ ์ ์ฝ (glibc โฅ 2.33)
ํ์ฌ glibc์์ unsortedโbin ์ฐ๊ธฐ๋ฅผ ์ ๋ขฐ์ฑ ์๊ฒ ์ฌ์ฉํ๋ ค๋ฉด:
- Tcache ๊ฐ์ญ: tcache์ ํด๋นํ๋ ์ฌ์ด์ฆ์ ๊ฒฝ์ฐ free๋ tcache๋ก ๋ถ๊ธฐ๋์ด unsorted bin์ ๊ฑด๋๋ฆฌ์ง ์์ต๋๋ค. ๋ฐ๋ผ์
- ์์ฒญ์ MAX_TCACHE_SIZE๋ณด๋ค ํฌ๊ฒ ํ๊ฑฐ๋(๊ธฐ๋ณธ์ ์ผ๋ก 64โbit์์ โฅ 0x410), ๋๋
- ํด๋น tcache bin์ ์ฑ์์(7๊ฐ ํญ๋ชฉ) ์ถ๊ฐ free๊ฐ ๊ธ๋ก๋ฒ bin์ ๋๋ฌํ๋๋ก ํ๊ฑฐ๋, ๋๋
- ํ๊ฒฝ์ ์ ์ดํ ์ ์๋ค๋ฉด tcache๋ฅผ ๋นํ์ฑํ(์: GLIBC_TUNABLES glibc.malloc.tcache_count=0)ํฉ๋๋ค.
- Unsorted ๋ฆฌ์คํธ์ ์ ํฉ์ฑ ๊ฒ์ฌ: ๋ค์ allocator ๊ฒฝ๋ก์์ unsorted bin์ ๊ฒ์ฌํ ๋ glibc๋(๋จ์ํ) ๋ค์์ ํ์ธํฉ๋๋ค:
bck->fd == victim๋ฐvictim->fd == unsorted_chunks(av); ๊ทธ๋ ์ง ์์ผ๋ฉดmalloc(): unsorted double linked list corrupted๋ก abortํฉ๋๋ค.
- ์ด๋ ํ๊ฒ ์ฃผ์๊ฐ ๋ ๋ฒ์ ์ฐ๊ธฐ๋ฅผ ๊ฒฌ๋์ผ ํจ์ ์๋ฏธํฉ๋๋ค: ๋จผ์ free ์์
*(TARGET) = victim; ๋์ค์ ์ฒญํฌ๊ฐ ์ ๊ฑฐ๋ ๋*(TARGET) = unsorted_chunks(av)(allocator๊ฐbck->fd๋ฅผ ๋ค์ bin ํค๋๋ก ๋ฎ์ด์). ๋จ์ํ ํฐ ๋น์(้้ถ) ๊ฐ์ ๊ฐ์ ํ๋ ๊ฒ์ด ์ ์ฉํ ํ๊ฒ์ ์ ํํ์ธ์. - ํ๋ ์ต์คํ๋ก์์์์ ์ ํ์ ์ธ ์์ ์ ํ๊ฒ
- โํฐโ ๊ฐ์ ํ๋๊ทธ/ํ๊ณ๋ก ์ทจ๊ธํ๋ ์ ํ๋ฆฌ์ผ์ด์ ๋๋ ์ ์ญ ์ํ.
- ๊ฐ์ ํ๋ฆฌ๋ฏธํฐ๋ธ(์: ์ดํ์ [fast bin attack](Fast Bin Attack)์ ์ํด ์ค์ ํ๊ฑฐ๋ ํ์ writeโwhatโwhere๋ก ํผ๋ฒํ๊ธฐ ์ํ ์ค๋น).
- ์๋ก์ด glibc์์
__malloc_hook/__free_hook๋ 2.34์์ ์ ๊ฑฐ๋์์ต๋๋ค โ ์ด๋ค์ ๋ชฉํ๋ก ์ผ์ง ๋ง์ญ์์ค. glibc โฅ 2.39์์๋global_max_fast์ญ์ ํผํ์ญ์์ค(๋ค์ ๋ ธํธ ์ฐธ์กฐ).
global_max_fast์ ๊ดํ์ฌ ์ต๊ทผ glibc์์๋- glibc 2.39+์์๋
global_max_fast๊ฐ 8โbit ์ ์ญ์ด ๋์์ต๋๋ค. ์ ํต์ ์ธ ๋ฐฉ์๋๋ก ํ ํฌ์ธํฐ๋ฅผ ์ฌ๊ธฐ์ ์ฐ๋ ํธ๋ฆญ์ ๋ ์ด์ ๊น๋ํ๊ฒ ๋์ํ์ง ์์ผ๋ฉฐ ์ธ์ ํ allocator ์ํ๋ฅผ ์์์ํฌ ๊ฐ๋ฅ์ฑ์ด ๋์ต๋๋ค. ๋ค๋ฅธ ์ ๋ต์ ์ ํํ์ธ์.
- glibc 2.39+์์๋
์ต์ ์ต์คํ๋ก์ ๋ ์ํผ (modern glibc)
๋ชฉํ: ํฌ๋์ ์์ด unsortedโbin ์ฝ์ ํ๋ฆฌ๋ฏธํฐ๋ธ๋ฅผ ์ฌ์ฉํด ํ ํฌ์ธํฐ ํ๋๋ฅผ ์์ ์ฃผ์์ ๋จ์ผ ์์ ์ฐ๊ธฐ๋ก ๋ฌ์ฑํฉ๋๋ค.
- Layout/grooming
- tcache๋ฅผ ์ฐํํ ๋งํผ ํฐ ์ฌ์ด์ฆ๋ก A, B, C ํ ๋น(์: 0x5000). C๋ top chunk์์ ํตํฉ(consolidation)์ ๋ฐฉ์งํฉ๋๋ค.
- ์์(Corruption)
- A์์ B์ ์ฒญํฌ ํค๋๋ก ์ค๋ฒํ๋ก์ฐํ์ฌ
B->bk = (mchunkptr)(TARGET - 0x10)์ ์ค์ ํฉ๋๋ค.
- A์์ B์ ์ฒญํฌ ํค๋๋ก ์ค๋ฒํ๋ก์ฐํ์ฌ
- ํธ๋ฆฌ๊ฑฐ(Trigger)
free(B). ์ฝ์ ์ allocator๊ฐbck->fd = B๋ฅผ ์คํํ๋ฏ๋ก ๊ฒฐ๊ณผ์ ์ผ๋ก*(TARGET) = B๊ฐ ๋ฉ๋๋ค.
- ์ดํ(Continuation)
- ๊ณ์ ํ ๋น์ ์งํํ๊ณ ํ๋ก๊ทธ๋จ์ด unsorted bin์ ์ฌ์ฉํ๋ค๋ฉด allocator๊ฐ ๋์ค์
*(TARGET) = unsorted_chunks(av)๋ก ๋ฎ์ด์ธ ๊ฒ์์ ์์ํ์ธ์. ๋ ๊ฐ ๋ชจ๋ ์ผ๋ฐ์ ์ผ๋ก ํฐ ๊ฐ์ด๋ฉฐ, ๋จ์ง โํฐโ ๊ฒ์ ๊ฒ์ฌํ๋ ํ๊ฒ์์๋ ์ด๊ฒ๋ง์ผ๋ก๋ ์ฌ์ด์ฆ/ํ๊ณ ์๋ฏธ๋ฅผ ๋ฐ๊ฟ ์ ์์ต๋๋ค.
- ๊ณ์ ํ ๋น์ ์งํํ๊ณ ํ๋ก๊ทธ๋จ์ด unsorted bin์ ์ฌ์ฉํ๋ค๋ฉด allocator๊ฐ ๋์ค์
Pseudocode skeleton:
// 64-bit glibc 2.35โ2.38 style layout (tcache bypass via large sizes)
void *A = malloc(0x5000);
void *B = malloc(0x5000);
void *C = malloc(0x5000); // guard
// overflow from A into Bโs metadata (prev_size/size/.../bk). You must control B->bk.
*(size_t *)((char*)B - 0x8) = (size_t)(TARGET - 0x10); // write fake bk
free(B); // triggers *(TARGET) = B (unsorted-bin insertion write)
Note
โข ๋ง์ฝ size๋ก tcache๋ฅผ ์ฐํํ ์ ์๋ค๋ฉด, ์ ํํ ํฌ๊ธฐ์ tcache bin์ (7๋ฒ frees) ์ฑ์ด ํ ์์๋ chunk๋ฅผ free ํ์ฌ free๊ฐ unsorted๋ก ๊ฐ๊ฒ ํ์ธ์. โข ๋ง์ฝ ํ๋ก๊ทธ๋จ์ด ๋ค์ allocation์์ unsorted-bin ๊ฒ์ฆ ๋๋ฌธ์ ์ฆ์ abortํ๋ค๋ฉด,
victim->fd๊ฐ ์ฌ์ ํ bin head์ ๊ฐ์์ง, ๊ทธ๋ฆฌ๊ณ ์ฒซ ๋ฒ์งธ ์ฐ๊ธฐ ์ดํ์ ๋น์ ์TARGET์ด ์ ํํvictimํฌ์ธํฐ๋ฅผ ๊ฐ์ง๊ณ ์๋์ง ๋ค์ ํ์ธํ์ธ์.
Unsorted Bin Infoleak Attack
์ฌ์ค ์ด๊ฒ์ ๋งค์ฐ ๊ธฐ๋ณธ์ ์ธ ๊ฐ๋
์
๋๋ค. unsorted bin์ ์ฒญํฌ๋ค์ ํฌ์ธํฐ๋ฅผ ๊ฐ๊ณ ์์ต๋๋ค. unsorted bin์ ์ฒซ ๋ฒ์งธ ์ฒญํฌ๋ ์ค์ ๋ก **fd**์ bk ๋งํฌ๊ฐ **main arena (Glibc)**์ ์ผ๋ถ๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์์ต๋๋ค.
๋ฐ๋ผ์, unsorted bin ์์ ์ฒญํฌ๋ฅผ ๋ฃ๊ณ ์ด๋ฅผ ์ฝ์ ์ ์๋ค๋ฉด (use after free), ๋๋ ์ ์ด๋ ํ๋์ ํฌ์ธํฐ๋ฅผ ๋ฎ์ด์ฐ์ง ์๊ณ ๋ค์ ํ ๋นํ์ฌ ์ฝ์ ์ ์๋ค๋ฉด, Glibc info leak์ ์ป์ ์ ์์ต๋๋ค.
์ ์ฌํ attack used in this writeup์์๋ 4๊ฐ ์ฒญํฌ ๊ตฌ์กฐ(A, B, C, D โ D๋ top chunk์์ consolidation์ ๋ฐฉ์งํ๊ธฐ ์ํจ)๋ฅผ ์
์ฉํ์ต๋๋ค. B์์์ null byte overflow๋ฅผ ์ด์ฉํด C๊ฐ B๊ฐ ์ฌ์ฉ๋์ง ์์ ๊ฒ์ผ๋ก ํ์ํ๊ฒ ํ์ต๋๋ค. ๋ํ B์ prev_size ๋ฐ์ดํฐ๋ฅผ ์์ ํด ํฌ๊ธฐ๊ฐ B์ ํฌ๊ธฐ ๋์ A+B๊ฐ ๋๋๋ก ํ์ต๋๋ค. ๊ทธ ๋ค์ C๋ฅผ ํด์ ํ๊ณ A+B๋ก consolidate(ํฉ์ณ์ก์ต๋๋ค)ํ์ง๋ง B๋ ์ฌ์ ํ ์ฌ์ฉ ์ค์ด์์ต๋๋ค. ํฌ๊ธฐ A์ ์ ์ฒญํฌ๋ฅผ ํ ๋นํ ๋ค, libc์์ leaked ๋ ์ฃผ์๋ค์ B์ ์จ์ ๊ฑฐ๊ธฐ์ ์ ์ถ์์ผฐ์ต๋๋ค.
์ฐธ์กฐ ๋ฐ ๊ธฐํ ์์
- https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap
- ๋ชฉํ๋ ์ ์ญ ๋ณ์๋ฅผ 4869๋ณด๋ค ํฐ ๊ฐ์ผ๋ก ๋ฎ์ด์จ flag๋ฅผ ์ป๋ ๊ฒ์ด๋ฉฐ, PIE๋ ํ์ฑํ๋์ด ์์ง ์์ต๋๋ค.
- ์์ ํฌ๊ธฐ์ ์ฒญํฌ๋ฅผ ์์ฑํ ์ ์๊ณ ์ํ๋ ํฌ๊ธฐ์ heap overflow๊ฐ ์กด์ฌํฉ๋๋ค.
- ๊ณต๊ฒฉ์ ์ธ ๊ฐ์ ์ฒญํฌ๋ฅผ ์์ฑํ๋ ๊ฒ์ผ๋ก ์์ํฉ๋๋ค: overflow๋ฅผ ์ ์ฉํ chunk0, ์ค๋ฒํ๋ก์ฐ๋ chunk1, ๊ทธ๋ฆฌ๊ณ ์ด์ ๊ฒ๋ค์ด top chunk์ consolidate๋๋ ๊ฒ์ ๋ฐฉ์งํ chunk2.
- ๊ทธ๋ค์ chunk1์ freeํ๊ณ chunk0์ ์ค๋ฒํ๋ก์ฐ์์ผ chunk1์
bkํฌ์ธํฐ๊ฐ ๊ฐ๋ฆฌํค๊ฒ ํฉ๋๋ค:bk = magic - 0x10 - ๊ทธ ํ chunk3์ chunk1๊ณผ ๊ฐ์ ํฌ๊ธฐ๋ก ํ ๋นํ๋ฉด unsorted bin attack์ด ๋ฐ์ํ๊ณ ์ ์ญ ๋ณ์์ ๊ฐ์ด ๋ณ๊ฒฝ๋์ด flag๋ฅผ ์ป์ ์ ์๊ฒ ๋ฉ๋๋ค.
- https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html
- merge ํจ์๋ ์ ๋ฌ๋ ๋ ์ธ๋ฑ์ค๊ฐ ๋์ผํ๋ฉด ํด๋น ์์ญ์ realloc์ ์ํํ ๋ค freeํ์ง๋ง, ์ฌ์ฉ ๊ฐ๋ฅํ ํด์ ๋ ์์ญ์ ๋ํ ํฌ์ธํฐ๋ฅผ ๋ฐํํ๋ฏ๋ก ์ทจ์ฝํฉ๋๋ค.
- ๋ฐ๋ผ์, 2๊ฐ์ ์ฒญํฌ๊ฐ ์์ฑ๋ฉ๋๋ค: ์์ ๊ณผ ๋ณํฉ๋ chunk0๊ณผ top chunk์์ consolidating์ ๋ง๊ธฐ ์ํ chunk1. ๊ทธ๋ฐ ๋ค์ merge ํจ์๊ฐ chunk0์ผ๋ก ๋ ๋ฒ ํธ์ถ๋์ด use after free๊ฐ ๋ฐ์ํฉ๋๋ค.
- ๊ทธํ
viewํจ์๊ฐ ์ธ๋ฑ์ค 2(์ฌ์ฉ ํ ํด์ ๋ ์ฒญํฌ์ ์ธ๋ฑ์ค)๋ก ํธ์ถ๋์ด libc address๋ฅผ leakํฉ๋๋ค. - ๋ฐ์ด๋๋ฆฌ๋ **
global_max_fast**๋ณด๋ค ํฐ ํฌ๊ธฐ๋ง mallocํ๋๋ก ๋ณดํธ๋์ด ์์ด fastbin์ด ์ฌ์ฉ๋์ง ์์ผ๋ฏ๋ก, ์ ์ญ ๋ณ์global_max_fast๋ฅผ ๋ฎ์ด์ฐ๊ธฐ ์ํด unsorted bin attack์ด ์ฌ์ฉ๋ฉ๋๋ค. - ๊ทธ๋ค์ edit ํจ์๋ฅผ ์ธ๋ฑ์ค 2(์ฌ์ฉ ํ ํด์ ํฌ์ธํฐ)๋ก ํธ์ถํด
bkํฌ์ธํฐ๋ฅผp64(global_max_fast-0x10)๋ก ๋ฎ์ด์ธ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ฉด ์ ์ฒญํฌ๋ฅผ ๋ง๋ค ๋ ์ด์ ์ ์กฐ์๋ free ์ฃผ์(0x20)๊ฐ ์ฌ์ฉ๋์ด unsorted bin attack์ triggerํ๊ณglobal_max_fast๋ฅผ ๋งค์ฐ ํฐ ๊ฐ์ผ๋ก ๋ฎ์ด์จ์ ์ด์ fast bin์ ์ฒญํฌ๋ฅผ ์์ฑํ ์ ์๊ฒ ๋ฉ๋๋ค. - ์ด์ fast bin attack์ด ์ํ๋ฉ๋๋ค:
- ์ฐ์
__free_hook์์น์์ fast ํฌ๊ธฐ 200์ ์ฒญํฌ๋ก ์์ ํ ์ ์์์ด ๋ฐ๊ฒฌ๋ฉ๋๋ค: -
gefโค p &__free_hook
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook> gefโค x/60gx 0x7ff1e9e607a8 - 0x59 0x7ff1e9e6074f: 0x0000000000000000 0x0000000000000200 0x7ff1e9e6075f: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
- ์ด ์์น์ ํฌ๊ธฐ 0x200์ fast ์ฒญํฌ๋ฅผ ์ป์ ์ ์๋ค๋ฉด, ์คํ๋ ํจ์ ํฌ์ธํฐ๋ฅผ ๋ฎ์ด์ธ ์ ์์ต๋๋ค.
- ์ด๋ฅผ ์ํด ํฌ๊ธฐ
0xfc์ ์ ์ฒญํฌ๋ฅผ ์์ฑํ๊ณ ํด๋น ํฌ์ธํฐ๋ก merged ํจ์๋ฅผ ๋ ๋ฒ ํธ์ถํ๋ฉด, fast bin์ ํฌ๊ธฐ0xfc*2 = 0x1f8์ธ ํด์ ๋ ์ฒญํฌ์ ๋ํ ํฌ์ธํฐ๋ฅผ ์ป์ ์ ์์ต๋๋ค. - ๊ทธ ๋ค์ ์ด ์ฒญํฌ์์ edit ํจ์๋ฅผ ํธ์ถํด ์ด fast bin์
fd์ฃผ์๋ฅผ ์ด์ ์ **__free_hook**์ ๊ฐ๋ฆฌํค๋๋ก ์์ ํฉ๋๋ค. - ๊ทธ ํ fast bin์์ ์ด์ ์ ์ธ๋ชจ์๋ ์ฒญํฌ๋ฅผ ๊บผ๋ด๊ธฐ ์ํด ํฌ๊ธฐ
0x1f8์ ์ฒญํฌ๋ฅผ ํ๋ ์์ฑํ๊ณ , ๋ ๋ค๋ฅธ ํฌ๊ธฐ0x1f8์ ์ฒญํฌ๋ฅผ ์์ฑํ๋ฉด fast bin์ ์ฒญํฌ๊ฐ__free_hook์์น๋ก ํ ๋น๋์ด ์ด๋ฅผsystemํจ์์ ์ฃผ์๋ก ๋ฎ์ด์๋๋ค. - ๋ง์ง๋ง์ผ๋ก ๋ฌธ์์ด
/bin/sh\x00๋ฅผ ๋ด์ ์ฒญํฌ๋ฅผ delete ํจ์๋ก freeํ๋ฉด, **__free_hook**๊ฐ ํธ์ถ๋์ด/bin/sh\x00๋ฅผ ์ธ์๋ก system์ด ์คํ๋ฉ๋๋ค. - CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html
- 1B overflow๋ฅผ ์ ์ฉํด ์ฒญํฌ๋ฅผ unsorted bin์์ consolidateํ์ฌ libc infoleak์ ์ป๊ณ , ๊ทธ ํ fast bin attack์ ์ํํด malloc hook์ one gadget ์ฃผ์๋ก ๋ฎ์ด์ฐ๋ ๋ ๋ค๋ฅธ ์์ ์ ๋๋ค
- Robot Factory. BlackHat MEA CTF 2022
- 0x100๋ณด๋ค ํฐ ํฌ๊ธฐ์ ์ฒญํฌ๋ง ํ ๋นํ ์ ์์ต๋๋ค.
- Unsorted Bin attack์ผ๋ก
global_max_fast๋ฅผ ๋ฎ์ด์๋๋ค (ASLR ๋๋ฌธ์ 1/16 ํ๋ฅ ๋ก ๋์ํฉ๋๋ค โ ์์ ํด์ผ ํ๋ ๋นํธ ์์ ๊ด๋ จ). - Fast Bin attack์ผ๋ก ์ ์ญ ์ฒญํฌ ๋ฐฐ์ด์ ์์ ํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์์์ ์ฝ๊ธฐ/์ฐ๊ธฐ primitive๋ฅผ ์ป์ด GOT์ ์์ ํ๊ณ ์ด๋ค ํจ์๋ฅผ
system์ผ๋ก ํฌ์ธํ ํ๋๋ก ์ค์ ํ ์ ์์ต๋๋ค.
์ฐธ์กฐ
- Glibc malloc unsorted-bin integrity checks (example in 2.33 source): https://elixir.bootlin.com/glibc/glibc-2.33/source/malloc/malloc.c
global_max_fastand related definitions in modern glibc (2.39): https://elixir.bootlin.com/glibc/glibc-2.39/source/malloc/malloc.c
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


