House of Roman

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 ์ง€์›ํ•˜๊ธฐ

Basic Information

์ด ๊ธฐ์ˆ ์€ ๊ฐ€์งœ fastbins, unsorted_bin ๊ณต๊ฒฉ ๋ฐ ์ƒ๋Œ€์  ์˜ค๋ฒ„๋ผ์ดํŠธ๋ฅผ ํ†ตํ•ด ๋ˆ„์ˆ˜ ์—†์ด RCE๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ๋งค์šฐ ํฅ๋ฏธ๋กœ์šด ๊ธฐ์ˆ ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํŒจ์น˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Code

Goal

  • ์ƒ๋Œ€ ํฌ์ธํ„ฐ๋ฅผ ์•…์šฉํ•˜์—ฌ RCE

Requirements

  • fastbin ๋ฐ unsorted bin ํฌ์ธํ„ฐ ํŽธ์ง‘
  • 12๋น„ํŠธ์˜ ๋ฌด์ž‘์œ„์„ฑ์ด ๊ฐ•์ œ๋กœ ํ•ด๊ฒฐ๋˜์–ด์•ผ ํ•จ (์ž‘๋™ ํ™•๋ฅ  0.02%)

Attack Steps

Part 1: Fastbin Chunk points to __malloc_hook

์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ฒญํฌ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค:

  • fastbin_victim (0x60, offset 0): ๋‚˜์ค‘์— ํž™ ํฌ์ธํ„ฐ๋ฅผ LibC ๊ฐ’์œผ๋กœ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ํŽธ์ง‘ํ•  UAF ์ฒญํฌ.
  • chunk2 (0x80, offset 0x70): ์ข‹์€ ์ •๋ ฌ์„ ์œ„ํ•ด
  • main_arena_use (0x80, offset 0x100)
  • relative_offset_heap (0x60, offset 0x190): โ€˜main_arena_useโ€™ ์ฒญํฌ์˜ ์ƒ๋Œ€์  ์˜คํ”„์…‹

๊ทธ๋Ÿฐ ๋‹ค์Œ free(main_arena_use)๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ด ์ฒญํฌ๊ฐ€ ์ •๋ ฌ๋˜์ง€ ์•Š์€ ๋ชฉ๋ก์— ๋ฐฐ์น˜๋˜๊ณ  fd ๋ฐ bk ํฌ์ธํ„ฐ ๋ชจ๋‘์—์„œ main_arena + 0x68์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ๋ฅผ ์–ป๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ด์ œ fake_libc_chunk(0x60)๋ผ๋Š” ์ƒˆ๋กœ์šด ์ฒญํฌ๊ฐ€ ํ• ๋‹น๋˜๋ฉฐ, ์ด๋Š” fd ๋ฐ bk์—์„œ main_arena + 0x68์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ๋ฅผ ํฌํ•จํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋‹ค์Œ relative_offset_heap๊ณผ fastbin_victim์ด ํ•ด์ œ๋ฉ๋‹ˆ๋‹ค.

/*
Current heap layout:
0x0:   fastbin_victim       - size 0x70
0x70:  alignment_filler     - size 0x90
0x100: fake_libc_chunk      - size 0x70 (contains a fd ptr to main_arena + 0x68)
0x170: leftover_main        - size 0x20
0x190: relative_offset_heap - size 0x70

bin layout:
fastbin:  fastbin_victim -> relative_offset_heap
unsorted: leftover_main
*/
  • fastbin_victim์€ relative_offset_heap์„ ๊ฐ€๋ฆฌํ‚ค๋Š” fd๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
  • relative_offset_heap์€ fake_libc_chunk๋กœ๋ถ€ํ„ฐ์˜ ๊ฑฐ๋ฆฌ ์˜คํ”„์…‹์œผ๋กœ, ์—ฌ๊ธฐ์—๋Š” main_arena + 0x68์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • fastbin_victim.fd์˜ ๋งˆ์ง€๋ง‰ ๋ฐ”์ดํŠธ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋„ fastbin_victim์ด main_arena + 0x68์„ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด์ „ ์ž‘์—…์„ ์œ„ํ•ด ๊ณต๊ฒฉ์ž๋Š” fastbin_victim์˜ fd ํฌ์ธํ„ฐ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋‹ค์Œ, main_arena + 0x68์€ ๊ทธ๋ฆฌ ํฅ๋ฏธ๋กญ์ง€ ์•Š์œผ๋ฏ€๋กœ ํฌ์ธํ„ฐ๋ฅผ **__malloc_hook**์„ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ์ˆ˜์ •ํ•ฉ์‹œ๋‹ค.

__memalign_hook์€ ์ผ๋ฐ˜์ ์œผ๋กœ 0x7f๋กœ ์‹œ์ž‘ํ•˜๊ณ  ๊ทธ ์•ž์— 0์ด ์žˆ์œผ๋ฏ€๋กœ, ์ด๋ฅผ 0x70 ํŒจ์ŠคํŠธ ๋นˆ์˜ ๊ฐ’์œผ๋กœ ์œ„์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฃผ์†Œ์˜ ๋งˆ์ง€๋ง‰ 4๋น„ํŠธ๋Š” ๋ฌด์ž‘์œ„์ด๋ฏ€๋กœ, ์šฐ๋ฆฌ๊ฐ€ ๊ด€์‹ฌ ์žˆ๋Š” ๊ณณ์„ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์˜ ๊ฐ€๋Šฅ์„ฑ์€ 2^4=16์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์—ฌ๊ธฐ์„œ BF ๊ณต๊ฒฉ์ด ์ˆ˜ํ–‰๋˜์–ด ์ฒญํฌ๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋๋‚ฉ๋‹ˆ๋‹ค: 0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23).

(๋‚˜๋จธ์ง€ ๋ฐ”์ดํŠธ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์ •๋ณด๋Š” how2heap ์˜ˆ์ œ์—์„œ ํ™•์ธํ•˜์„ธ์š”). BF๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š์œผ๋ฉด ํ”„๋กœ๊ทธ๋žจ์ด ์ถฉ๋Œํ•˜๋ฏ€๋กœ, ์ž‘๋™ํ•  ๋•Œ๊นŒ์ง€ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜์„ธ์š”.

๊ทธ๋Ÿฐ ๋‹ค์Œ, 2๊ฐœ์˜ malloc์ด ์ˆ˜ํ–‰๋˜์–ด 2๊ฐœ์˜ ์ดˆ๊ธฐ ํŒจ์ŠคํŠธ ๋นˆ ์ฒญํฌ๊ฐ€ ์ œ๊ฑฐ๋˜๊ณ , ์„ธ ๋ฒˆ์งธ malloc์ด ํ• ๋‹น๋˜์–ด **__malloc_hook:**์—์„œ ์ฒญํฌ๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค.

malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);

Part 2: Unsorted_bin ๊ณต๊ฒฉ

์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

Unsorted Bin Attack

๊ธฐ๋ณธ์ ์œผ๋กœ ์ด๋Š” chunk->bk์— ์ง€์ •๋œ ์œ„์น˜์— main_arena + 0x68์„ ์“ธ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ๊ณต๊ฒฉ์„ ์œ„ํ•ด ์šฐ๋ฆฌ๋Š” __malloc_hook์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ, ์ด๋ฅผ ๋ฎ์–ด์“ด ํ›„ ์ƒ๋Œ€์  ๋ฎ์–ด์“ฐ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ one_gadget์„ ๊ฐ€๋ฆฌํ‚ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด ์šฐ๋ฆฌ๋Š” ์ฒญํฌ๋ฅผ ๊ฐ€์ ธ์™€ unsorted bin์— ๋„ฃ๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค:

uint8_t* unsorted_bin_ptr = malloc(0x80);
malloc(0x30); // Don't want to consolidate

puts("Put chunk into unsorted_bin\n");
// Free the chunk to create the UAF
free(unsorted_bin_ptr);

์ด ์ฒญํฌ์—์„œ UAF๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ unsorted_bin_ptr->bk๋ฅผ __malloc_hook์˜ ์ฃผ์†Œ๋กœ ํฌ์ธํŒ…ํ•ฉ๋‹ˆ๋‹ค(์šฐ๋ฆฌ๋Š” ์ด์ „์— ์ด๋ฅผ ๋ฌด์ž‘์œ„๋กœ ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค).

Caution

์ด ๊ณต๊ฒฉ์€ ์ •๋ ฌ๋˜์ง€ ์•Š์€ ๋นˆ์„ ์†์ƒ์‹œํ‚ต๋‹ˆ๋‹ค(๋”ฐ๋ผ์„œ ์ž‘์€ ๊ฒƒ๊ณผ ํฐ ๊ฒƒ๋„). ๋”ฐ๋ผ์„œ ์ด์ œ ๋น ๋ฅธ ๋นˆ์—์„œ ํ• ๋‹น๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๋” ๋ณต์žกํ•œ ํ”„๋กœ๊ทธ๋žจ์€ ๋‹ค๋ฅธ ํ• ๋‹น์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์ถฉ๋Œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค), ์ด๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ฐ™์€ ํฌ๊ธฐ๋กœ ํ• ๋‹นํ•ด์•ผ ํ•˜๋ฉฐ, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ํ”„๋กœ๊ทธ๋žจ์ด ์ถฉ๋Œํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ __malloc_hook์— main_arena + 0x68์˜ ์“ฐ๊ธฐ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด unsorted_bin_ptr->bk์— __malloc_hook์„ ์„ค์ •ํ•œ ํ›„, ์šฐ๋ฆฌ๋Š” ๋‹จ์ˆœํžˆ **malloc(0x80)**์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

3๋‹จ๊ณ„: __malloc_hook์„ system์œผ๋กœ ์„ค์ •

1๋‹จ๊ณ„์—์„œ ์šฐ๋ฆฌ๋Š” __malloc_hook์„ ํฌํ•จํ•˜๋Š” ์ฒญํฌ๋ฅผ ์ œ์–ดํ•˜๊ฒŒ ๋˜์—ˆ๊ณ (๋ณ€์ˆ˜ malloc_hook_chunk์—์„œ) 2๋‹จ๊ณ„์—์„œ๋Š” ์—ฌ๊ธฐ์—์„œ main_arena + 0x68์„ ์“ธ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์ด์ œ ์šฐ๋ฆฌ๋Š” malloc_hook_chunk์—์„œ ๋ถ€๋ถ„ ๋ฎ์–ด์“ฐ๊ธฐ๋ฅผ ์•…์šฉํ•˜์—ฌ ์šฐ๋ฆฌ๊ฐ€ ์“ด libc ์ฃผ์†Œ(main_arena + 0x68)๋ฅผ one_gadget ์ฃผ์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ 12๋น„ํŠธ์˜ ๋ฌด์ž‘์œ„์„ฑ์„ ๋ฌด์ž‘์œ„๋กœ ์‹œ๋„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์ž์„ธํ•œ ์ •๋ณด๋Š” how2heap ์˜ˆ์ œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค).

๋งˆ์ง€๋ง‰์œผ๋กœ, ์˜ฌ๋ฐ”๋ฅธ ์ฃผ์†Œ๊ฐ€ ๋ฎ์–ด์“ฐ์—ฌ์ง€๋ฉด, malloc์„ ํ˜ธ์ถœํ•˜๊ณ  one_gadget์„ ํŠธ๋ฆฌ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

References

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 ์ง€์›ํ•˜๊ธฐ