๋ฌธ์ : DreamHack โ Snaky ๋ถ๋ฅ: reversing ๋์ด๋: ๐ฅ Gold 4 FLAG:
DH{zzzzzz222222277779999zzzzzzzssssssss999777777777222222222222zzzzz999zzz999777ssss99999999999777777sssssssz}
๋ฌธ์ ์ค๋ช ์ ํํ ํํ๋ค.
x64 ๋ฆฌ๋ ์ค ํ๊ฒฝ์์ ์คํํ ์ ์๋ ELF ํ์ผ์ด ์ฒจ๋ถํ์ผ๋ก ์ฃผ์ด์ง๋๋ค. ํด๋น ELF ํ์ผ์ ์ด์ฉ์๋ก๋ถํฐ ๋ฌธ์์ด์ ์ ๋ ฅ๋ฐ์ ๊ฒ์ฆ์ ์ํํ ํ ์ ๋ต์ด๋ฉด
good :)์, ํ๋ฆฌ๋ฉดwrong :(์ ์ถ๋ ฅํ๋ ํ๋ก๊ทธ๋จ์ ๋๋ค. ์ ๋ต์ด ๋๋ ๋ฌธ์์ด์ด ํ๋๊ทธ์ด๋ฉฐ, ํ๋๊ทธ ํ์์DH{...}์ ๋๋ค.
๋ฌธ์ ํ์ด์ง์ ์ ๋ฐ์ดํธ ๊ธฐ๋ก์ด ํ๋ ๋ถ์ด ์๋ค.
2025.03.05:
good :)์ ์ถ๋ ฅํ๋ ์ ๋ ฅ ๊ฐ์ด ์ฌ๋ฌ ๊ฐ์๋ ๋ฌธ์ ๋ฅผ ์์ ํ์์ต๋๋ค.
์ด ํ ์ค์ด ๋์ค์ ํ์ด๊ฐ ๋ง์๋ค๋ ํ์ธ์ด ๋๋ค. ๋ต์ด ์ ํํ ํ๋์ฌ์ผ ํ๋ค๋ ๋ป์ด๋๊น.
๋ฌธ์ ๊ฐ์
| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| ๋ฌธ์ ๋ช | Snaky (id 1774) |
| ๋์ด๋ | ๐ฅ Gold 4 |
| ๋ถ๋ฅ | reversing |
| ์ ๊ณต ํ์ผ | chall (ELF 64-bit, non-PIE, stripped, 30,184๋ฐ์ดํธ) |
| ์ํฌํธ | __isoc99_scanf ยท puts ยท setvbuf โ ๊ทธ๊ฒ ์ ๋ถ๋ค |
| ํต์ฌ | .data ์ ์จ์ 25ร25ร25 3D ๋ฏธ๋ก + ์๊ธฐ ๋ชธ์ ๋ฐ์ ์ ์๋ ์ ์ฝ |
| ๋ต | 106๊ฑธ์, ๋จ์๊ฒฝ๋ก ์ ํํ 1๊ฐ |
ํ์ด๋ ์น์ ํฌ๊ธฐ๋ฅผ ๋ณธ ์๊ฐ ๋ฐฉํฅ์ด ์กํ๋ค. ๋ก์ง์ 1.5KB ์ธ๋ฐ ๋ฐ์ดํฐ๊ฐ 15KB ๋ค. ๋ต์ด ์ฝ๋๊ฐ ์๋๋ผ ๋ฐ์ดํฐ์ ์๋ค๋ ๋ป์ด๋ค.
๊ทธ๋ค์์ ๊ทธ ๋ฐ์ดํฐ๊ฐ ์ด๋ค ๋ชจ์์ธ์ง ์์๋ด๋ ์ผ์ด์๊ณ , ์ธ๋ฑ์ค ๊ณ์ฐ์ ํ๋๊ฐ ๊ทธ๊ฑธ ๋ค ๋งํด ์คฌ๋ค.
๐ฌ ์ ์ฐฐ โ ์น์ ํฌ๊ธฐ๊ฐ ๋จผ์ ๋งํ๋ค
file extracted/chall; readelf -SW extracted/chall | grep -E "\.text|\.rodata|\.data|\.bss"
.text ๊ฐ 0x60c = 1,548๋ฐ์ดํธ. .data ๊ฐ 0x3d29 = 15,657๋ฐ์ดํธ.
๋ฆฌ๋ฒ์ฑ ๋ฌธ์ ์์ ์ด ๋น์จ์ ๊ฐํ ์ ํธ๋ค. ๊ฒ์ฆ ๋ก์ง์ด 1.5KB ์์ ๋ค์ด๊ฐ๋ค๋ฉด ๋ณต์กํ ์ํธ ๋ฃจํด์ ์๋๊ณ , ๋์ 15KB์ง๋ฆฌ ํ๋ฅผ ์ฐธ์กฐํ๋ค๋ ๋ป์ด๋ค.
non-PIE ๋ผ๋ ๊ฒ๋ ๋ฐ๊ฐ๋ค. ์ฃผ์๊ฐ ์คํ๋ง๋ค ๊ณ ์ ์ด๋ผ ๋์ค์ gdb ๋ก ํ์ธํ ๋ 0x404060 ๊ฐ์ ๊ฐ์ ๊ทธ๋๋ก ์ธ ์ ์๋ค.
์ํฌํธ๊ฐ ์ธ ๊ฐ๋ฟ์ด๋ค
nm -D extracted/chall; strings -a extracted/chall | grep -E "%255s|good|wrong"
scanf("%255s", buf) ๋ก ํ ์ค ๋ฐ๊ณ , puts ๋ก ๋ ์ค ํ๋๋ฅผ ์ฐ๋๋ค. ์ํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ํ์ผ ์
์ถ๋ ฅ๋ ์๋ค.
๊ทธ๋ฌ๋๊น ์ด ํ๋ก๊ทธ๋จ์ ์ ๋ ฅ ๋ฌธ์์ด ํ๋๋ฅผ ํ์ ๋์กฐํ๋ ๊ฒ์ด ์ ๋ถ๋ค.
๐งฉ ๋ฐฐ๊ฒฝ โ stripped ๋ฐ์ด๋๋ฆฌ๋ฅผ ์ฝ๋ ์์
์ฌ๋ณผ์ด ์์ผ๋ ํจ์ ์ด๋ฆ์ด ํ๋๋ ์๋ค. ๊ทธ๋๋ ์์๋ฅผ ์ ํด ๋๋ฉด ํค๋งฌ ์ผ์ด ์ ๋ค.
์ํธ๋ฆฌ์์ main ์ ์ฐพ๋๋ค. _start ๊ฐ __libc_start_main ์ ๋๊ธฐ๋ ์ฒซ ์ธ์๊ฐ main ์ด๋ค. ์ฌ๊ธฐ์๋ mov rdi,0x4016a3 ์ด๋ผ main ์ 0x4016a3.
ํธ์ถ ๊ทธ๋ํ๋ฅผ ์์์ ์๋๋ก ํ๋๋ค. main โ 0x401482(์ง์ง ๋ก์ง) โ 0x401348(๊ฒ์ฆ) โ ๊ทธ ์๋๋ก 0x40127a, 0x4011eb, 0x401196.
๋ฆฌํ ํจ์๋ถํฐ ์ด๋ฆ์ ๋ถ์ธ๋ค. ๊ฐ์ฅ ์์ ํจ์๊ฐ ๋๊ฐ ๊ฐ์ฅ ๋จ์ํ๊ณ , ๊ฑฐ๊ธฐ์ ์๋ฃ๊ตฌ์กฐ๊ฐ ๋๋ฌ๋๋ค. ์ด ๋ฌธ์ ์์๋ 0x401196 ๊ณผ 0x4011eb ์ด ๊ทธ ์๋ฆฌ์๋ค.
์๋์์๋ ์ฝ์ด๋ธ ์ด๋ฆ์ผ๋ก ๋ถ๋ฅด๊ฒ ๋ค. ์ค์ ๋ฐ์ด๋๋ฆฌ์๋ ์ฃผ์๋ฐ์ ์๋ค.
| ์ฃผ์ | ๋ถ์ธ ์ด๋ฆ | ํ๋ ์ผ |
|---|---|---|
0x401196 | mark(x,y,z) | ๊ฒฉ์์ ๊ทธ ์นธ์ 1 ๋ก ๋ง๋ ๋ค |
0x4011eb | can_move(x,y,z) | ๋ฒ์ ์์ด๊ณ ๊ฐ์ด 1 ์ด ์๋๋ฉด 1 ์ ๋๋ ค์ค๋ค |
0x40127a | check_chars(s) | ์ ๋ ฅ์ด ํ์ฉ๋ ๊ธ์๋ก๋ง ๋์ด ์๋์ง ๋ณธ๋ค |
0x401348 | check(s) | ์ค์ ๊ฒ์ฆ โ ์๋์์ ์์ธํ |
๐ฃ ํต์ฌ โ ๊ฒฉ์, ์ฌ์ฏ ๋ฐฉํฅ, ๊ทธ๋ฆฌ๊ณ ๋ฑ
์ ๋ ฅ์ ์ธ ์ ์๋ ๊ธ์๋ ์ฌ์ฏ ๊ฐ๋ค
check_chars ๋ ๋ฌธ์ ํ๋๋ฅผ ์ฌ์ฏ ๊ฐ๊ณผ ์ฐจ๋ก๋ก ๋น๊ตํ๋ค. ๊ฐ์ ํจํด์ด ์ฌ์ฏ ๋ฒ ๋ฐ๋ณต๋๋ ํ์ ์ค๋ง ๋ฝ์ ๋ณธ๋ค.
# annot_charset.sed
s|cmp al,0x4b|& <-- 'K'|
s|cmp al,0x39|& <-- '9'|
s|cmp al,0x7a|& <-- 'z'|
s|cmp al,0x37|& <-- '7'|
s|cmp al,0x32|& <-- '2'|
s|cmp al,0x73|& <-- 's' ์ฌ์ฏ ๊ธ์๋ง ํ์ฉํ๋ค|
s|test al,al|& <-- NUL ์ด๋ฉด ๊ฒ์ฌ ๋|
s|cmp DWORD PTR \[rbp-0x4\],0xff|& <-- ์ต๋ 256๊ธ์|objdump -d -M intel --no-show-raw-insn --start-address=0x40127a --stop-address=0x401348 extracted/chall | sed -f annot_charset.sed | grep -E "cmp|test|jle"
0x4b 0x39 0x7a 0x37 0x32 0x73 โ K 9 z 7 2 s. ์ฌ์ฏ ๊ฐ๋ค.
ํ๋๊ทธ ์ํ๋ฒณ์ด ์ฌ์ฏ ๊ธ์๋ก ์ ํ๋๋ค๋ ๊ฑด ๊ทธ ์์ฒด๋ก ์๋ฏธ๊ฐ ์๋ค. ์์์ ๋ฌธ์์ด์ ๋งํ๋ ๊ฒ ์๋๋ผ ์ฌ์ฏ ๊ฐ์ง ์ค ํ๋๋ฅผ ๊ณ ๋ฅด๋ ์ ํ์ ๋ฐ๋ณตํ๋ ๋ฌธ์ ๋ผ๋ ๋ป์ด๋ค.
์ธ๋ฑ์ค ๊ณ์ฐ์์ด ์๋ฃ๊ตฌ์กฐ๋ฅผ ๋๋ฌ๋ธ๋ค
can_move ๋ฅผ ๋ณด๋ฉด ๋ฒ์ ๊ฒ์ฌ์ ์ฃผ์ ๊ณ์ฐ์ด ํ์๋ฆฌ์ ์๋ค.
# annot_index.sed โ ์ฃผ์๋ก ์ค์ ์ง์ ํด์ผ ๊ฐ์ ๋ช
๋ น์ด ์ฌ๋ฌ ๋ฒ ๋์ฌ ๋ ์ ํท๊ฐ๋ฆฐ๋ค
s|^ 401202:.*|& <-- x <= 24|
s|^ 40120e:.*|& <-- y <= 24|
s|^ 40121a:.*|& <-- z <= 24|
s|^ 401238:.*|& <-- rsi = z * 625|
s|^ 401242:.*|& <-- rax = 4y|
s|^ 401246:.*|& <-- rax = 5y|
s|^ 401249:.*|& <-- rdx = 20y|
s|^ 401251:.*|& <-- rax = 25y|
s|^ 401254:.*|& <-- rax = 25y + 625z|
s|^ 401257:.*|& <-- rdx = x + 25y + 625z|
s|^ 40125b:.*|& <-- ๊ฒฉ์ ์์ 0x404060|
s|^ 401262:.*|& <-- rax = ๊ฒฉ์ + ์คํ์
|
s|^ 401268:.*|& <-- ๊ฐ์ด 1 ์ด๋ฉด ๋ชป ๊ฐ๋ค|objdump -d -M intel --no-show-raw-insn --start-address=0x4011eb --stop-address=0x40127a extracted/chall | sed -f annot_index.sed
์ปดํ์ผ๋ฌ๊ฐ ๊ณฑ์ ์ ์ํํธ์ ๋ง์ ์ผ๋ก ์ชผ๊ฐ ๋์ ์ฒ์์ ๋์ ์ ๋ค์ด์จ๋ค. ์์๋๋ก ๋ฐ๋ผ๊ฐ๋ฉด ์ด๋ ๋ค.
rsi = z * 0x271 ; 0x271 = 625
rax = y
rax = y << 2 ; 4y
rax = 4y + y ; 5y
rdx = rax * 4 ; 20y
rax = 5y + 20y ; 25y
rax = 25y + 625z
rdx = rax + x ; x + 25y + 625z
rax = 0x404060 + rdx25 = 5ยฒ, 625 = 25ยฒ. ๊ทธ๋ฆฌ๊ณ ๋ฒ์ ๊ฒ์ฌ๊ฐ ์ธ ์ขํ ๋ชจ๋ 0..24.
25ร25ร25 = 15,625๋ฐ์ดํธ 3์ฐจ์ ๋ฐฐ์ด์ด๋ค. .data ํฌ๊ธฐ 15,657 ์์ ์์ 32๋ฐ์ดํธ๋ฅผ ๋นผ๋ฉด ์ ํํ 15,625๋ค. ๋ฑ ๋ง๋๋ค.
๊ฐ์ด 1 ์ด๋ฉด ๋ชป ๊ฐ๋ ์นธ. 0 ์ด๋ฉด ํต๋ก.
์ฌ์ฏ ๊ธ์๊ฐ ์ฌ์ฏ ๋ฐฉํฅ์ด๋ค
check ์ ์ด๋ ์ฒ๋ฆฌ ๋ถ๋ถ์ ๋ณธ๋ค.
# annot_walk.sed
s|^ 401372:.*|& <-- ์์ x = 24|
s|^ 401379:.*|& <-- ์์ y = 12|
s|^ 401380:.*|& <-- ์์ z = 12|
s|^ 401394:.*|& <-- mark(24,12,12)|
s|^ 4013e4:.*|& <-- 'K' : x + 1|
s|^ 4013ea:.*|& <-- '9' : x - 1|
s|^ 4013f0:.*|& <-- 'z' : y + 1|
s|^ 4013f6:.*|& <-- '7' : y - 1|
s|^ 4013fc:.*|& <-- '2' : z + 1|
s|^ 401402:.*|& <-- 's' : z - 1|
s|^ 40140f:.*|& <-- ๋ชฉํ ํ์ ์ด ๋จผ์ ๋ค : x == 0|
s|^ 401415:.*|& <-- y == 12|
s|^ 40141b:.*|& <-- z == 12 โ good :)|
s|^ 401435:.*|& <-- ๊ทธ ๋ค์์ ์ด๋ ๊ฐ๋ฅ ํ์ |
s|^ 401452:.*|& <-- ๋ง์ง๋ง์ ์ด ์นธ์ ์น ํ๋ค (๋ฑ ๋ชธํต)|objdump -d -M intel --no-show-raw-insn --start-address=0x401372 --stop-address=0x40140f extracted/chall | sed -f annot_walk.sed
| ๊ธ์ | ์ด๋ |
|---|---|
K | x + 1 |
9 | x โ 1 |
z | y + 1 |
7 | y โ 1 |
2 | z + 1 |
s | z โ 1 |
์์์ (24, 12, 12), ์ฆ ํ๋ธ์ ํ์ชฝ ๋ฉด ํ๊ฐ์ด๋ฐ๋ค.
์์๊ฐ ์ค์ํ๋ค โ ๋ชฉํ ํ์ ์ด ์ด๋ ๊ฐ๋ฅ ํ์ ๋ณด๋ค ๋จผ์
ํ ๊ฑธ์๋ง๋ค ํ๋ ์ผ์ ์์๊ฐ ์ด ๋ฌธ์ ์ ๋ง์ง๋ง ์กฐ๊ฐ์ด๋ค.
objdump -d -M intel --no-show-raw-insn --start-address=0x40140f --stop-address=0x401460 extracted/chall | sed -f annot_walk.sed
C ๋ก ์ฎ๊ธฐ๋ฉด ์ด๋ ๋ค.
int check(char *s)
{
if (!check_chars(s)) return 0; // K 9 z 7 2 s ๋ง ํ์ฉ
int x = 24, y = 12, z = 12;
mark(x, y, z); // ์์ ์นธ๋ ๋ชธํต์ด๋ค
for (char *p = s; *p && p < s + 0x100; p++) {
switch (*p) {
case 'K': x++; break; case '9': x--; break;
case 'z': y++; break; case '7': y--; break;
case '2': z++; break; case 's': z--; break;
default: return 0;
}
if (x == 0 && y == 12 && z == 12) return 1; // โ ๋์ฐฉ์ด๋ฉด ๊ทธ ์๋ฆฌ์์ ์ฑ๊ณต
if (!can_move(x, y, z)) return 0; // โก ๋ฒฝ์ด๊ฑฐ๋ ์ด๋ฏธ ๋ฐ์ ์นธ์ด๋ฉด ์คํจ
mark(x, y, z); // โข ์ง๋์จ ์นธ์ ๋ฒฝ์ผ๋ก ๋ง๋ ๋ค
}
return 0;
}์ธ ์ค์ ์์๊ฐ ๊ฐ๊ฐ ๋ป์ด ์๋ค.
โ ์ด โก๋ณด๋ค ๋จผ์ ๋ผ์ ๋ชฉํ ์นธ์ ๋ฒฝ์ด์ด๋ ์๊ด์๋ค. ๋์ฐฉ ํ์ ์ด ์ด๋ ๊ฐ๋ฅ ํ์ ์ ์์ง๋ฅธ๋ค.
โข ๋๋ฌธ์ ์ง๋์จ ์นธ์ด ๋ฒฝ์ด ๋๋ค. ๋๋์๊ฐ ์๋, ์๊ธฐ ๊ฒฝ๋ก์ ๊ต์ฐจํ ์๋ ์๋ค. ๋ฑ์ด ์๊ธฐ ๋ชธ์ ๋จน์ผ๋ฉด ์ฃฝ๋ ๊ฒ๊ณผ ๊ฐ๋ค. ๋ฌธ์ ์ด๋ฆ์ด ์ฌ๊ธฐ์ ๋์๋ค.
๊ทธ๋ฌ๋ ๋ต์ ๋จ์๊ฒฝ๋ก์ฌ์ผ ํ๋ค. ๊ฐ์ ์นธ์ ๋ ๋ฒ ๋ฐ๋ ์๊ฐ ์คํจ๋ค.
๐ ์ฝ์ง
โถ๐ณ๏ธ ์ฝ์ง 1 โ 15,657 ๊ณผ 15,625 ์ 32๋ฐ์ดํธ ์ฐจ์ด
์ธ๋ฑ์ค ๊ณ์ฐ์์์ 25ร25ร25 = 15,625 ๋ฅผ ์ฝ๊ณ ๋์ .data ํฌ๊ธฐ์ ๋ง์ถฐ ๋ดค๋๋ฐ 15,657 ์ด์๋ค. 32๋ฐ์ดํธ๊ฐ ๋จ๋๋ค.
๊ณ์ฐ์์ ์๋ชป ์ฝ์๋ ์ถ์ด ์ํํธ ์์๋ฅผ ๋ ๋ฒ ๋ค์ ๋ฐ๋ผ๊ฐ๋ค. ๋ต์ ๋ ๋จ์ํ๋ค โ ๊ฒฉ์๊ฐ .data ์ ์์์ด ์๋์๋ค.
readelf -SW extracted/chall | grep '\.data'.data ๋ ๊ฐ์์ฃผ์ 0x404040 ์์ ์์ํ๋๋ฐ, ๋์ค์ด์
๋ธ์ด ๊ฐ๋ฆฌํค๋ ๊ฒฉ์๋ 0x404060 ์ด๋ค. ์ฐจ์ด๊ฐ ์ ํํ 0x20 = 32๋ฐ์ดํธ. ์์ 32๋ฐ์ดํธ๋ ๋ค๋ฅธ ์ ์ญ ๋ณ์ ์๋ฆฌ๋ค.
๊ทธ๋์ ํ์ผ์์ ๊ฒฉ์๋ฅผ ๋ฐ ๋ ์คํ์ ์ ์ด๋ ๊ฒ ์ก์์ผ ํ๋ค.
GRID_VA, DATA_VA, DATA_OFF = 0x404060, 0x404040, 0x3040
off = DATA_OFF + (GRID_VA - DATA_VA) # 0x3060์น์ ํฌ๊ธฐ๊ฐ ๋ฑ ๋ง์ง ์๋๋ค๊ณ ํด์์ด ํ๋ฆฐ ๊ฒ ์๋๋ค. ์น์ ์ ์ฌ๋ฌ ๋ณ์๋ฅผ ๋ด๋ ๊ทธ๋ฆ์ด๊ณ , ์ฐ๋ฆฌ๊ฐ ์ฐพ๋ ๋ฐฐ์ด์ ๊ทธ ์์ ํ ์กฐ๊ฐ์ผ ๋ฟ์ด๋ค. ์ฐจ์ด๊ฐ 32์ฒ๋ผ ์๊ณ ๊น๋ํ ๊ฐ์ด๋ฉด ์คํ๋ ค "๋ค๋ฅธ ์ ์ญ์ด ์์ ์๋ค"๋ ์ ํธ๋ก ์ฝ๋ ๊ฒ ๋ง๋ค.
โถ๐ณ๏ธ ์ฝ์ง 2 โ sed ์ฃผ์์ด ์๋ฑํ ์ค์ ๋ถ์๋ค
๋์ค์ด์
๋ธ์ <-- ์ฃผ์์ ์น์ผ๋ ค๊ณ sed ์คํฌ๋ฆฝํธ๋ฅผ ์ผ๋๋ฐ, ์ฒ์ ๊ฒ์ ์ธ ์ค์ด ์์ ์ ๋ถ๊ณ ํ ์ค์ ์๋ชป๋ ๊ณณ์ ์ธ ๋ฒ ๋ถ์๋ค.
์์ธ์ด ๋์ด์๋ค.
์ฒซ์งธ, BRE ์์ \+ ๋ ๋ฆฌํฐ๋ด ํ๋ฌ์ค๊ฐ ์๋๋ค. GNU sed ์ ๊ธฐ๋ณธ ์ ๊ท์์์ \+ ๋ "ํ๋ ์ด์"์ด๋ผ๋ ์๋์๋ค. ๊ทธ๋์ ์ด๋ฐ ํจํด์ด ์๋ฌด๊ฒ๋ ๋ชป ์ก์๋ค.
s|lea rdx,\[rax\*4\+0x0\]|& <-- rdx = 20y|[+] ์ฒ๋ผ ๋ฌธ์ ํด๋์ค๋ก ๊ฐ์ธ๋ฉด ๋ฆฌํฐ๋ด์ด ๋๋ค.
๋์งธ, ๊ฐ์ ๋ช
๋ น์ด ์ฌ๋ฌ ๋ฒ ๋์จ๋ค. add rax,rdx ๊ฐ ํ ํจ์ ์์ ์ธ ๋ฒ ์๋๋ฐ(5y ๋ง๋ค ๋, 25y ๋ง๋ค ๋, ๊ฒฉ์ ์ฃผ์ ๋ํ ๋) ๋ช
๋ น๋ง์ผ๋ก ํจํด์ ์ฐ๋ฉด ์
๋ค ๊ฐ์ ์ฃผ์์ ๋ฌ์ ๋ฒ๋ฆฐ๋ค. ์ค์ ๋ก "rax = 5y" ๊ฐ ์ธ ๊ตฐ๋ฐ์ ์ฐํ๋ค.
์ฃผ์๋ก ์ค์ ์ง์ ํ๋ ๋ ๋ค ํด๊ฒฐ๋๋ค.
s|^ 401246:.*|& <-- rax = 5y|
s|^ 401251:.*|& <-- rax = 25y|
s|^ 401262:.*|& <-- rax = ๊ฒฉ์ + ์คํ์
|์ฃผ์์ ๋จ ๋ค์๋ grep '<--' ๋ก ๋ช ์ค์ ๋ถ์๋์ง ์ธ์ด ๋ณธ๋ค. ์๋ํ ๊ฐ์์ ๋ค๋ฅด๋ฉด ํจํด์ด ํ๋ฆฐ ๊ฒ์ด๋ค. ์ฃผ์์ด ํ๋ฆฐ ์๋ฆฌ์ ๋ถ์ ์บก์ณ๋ ๊ธ์ ์ฝ๋ ์ฌ๋์ ์๋ชป๋ ๋ฐฉํฅ์ผ๋ก ๋๊ณ ๊ฐ๋ค.
๐งช ๋ฐํ์์ผ๋ก ํ์ธ
์ ์ ๋ถ์์ ์ฌ๊ธฐ๊น์ง๊ณ , ์ฝ์ ๊ฒ ๋ง๋์ง ์คํ ์ค์ ํ์ธํ๋ค. non-PIE ๋ผ ์ฃผ์๋ฅผ ๊ทธ๋๋ก ์ธ ์ ์์ด ๋ฐฐ์น ์คํฌ๋ฆฝํธ ํ๋๋ฉด ๋๋ค.
# runtime_check.gdb
set pagination off
set confirm off
# 0x401394 = check() ์์ ์ฒซ mark(x,y,z) ํธ์ถ ์ง์
break *0x401394
# 0x401452 = ๊ฑธ์๋ง๋ค ๋๋ mark(x,y,z) ํธ์ถ ์ง์
break *0x401452
run
printf "\n[1] ์์ ์ขํ (mark ์ธ์: rdi=x, rsi=y, rdx=z)\n"
printf " x=%d y=%d z=%d\n", $edi, $esi, $edx
printf " ๊ฒฉ์ ์ฃผ์ 0x404060, ์ธ๋ฑ์ค x+25*y+625*z\n"
printf " ์์ ์นธ ๊ฐ = %d (0 ์ด๋ฉด ํต๋ก)\n", *(unsigned char *)(0x404060 + $edi + 25*$esi + 625*$edx)
continue
printf "\n[2] ์ฒซ ๊ฑธ์ ๋ค โ ์
๋ ฅ ์ฒซ ๊ธ์๋ 'z' ์ด๋ฏ๋ก y ๊ฐ 1 ๋์ด์ผ ํ๋ค\n"
printf " x=%d y=%d z=%d\n", $edi, $esi, $edx
printf " ์ด ์นธ์ ๊ฐ = %d (์์ง 0 ์ด๋ผ ํต๊ณผ)\n", *(unsigned char *)(0x404060 + $edi + 25*$esi + 625*$edx)
# ๋ค์ ๊ฑธ์์ mark ํธ์ถ๊น์ง ์งํ โ ๊ทธ ์ฌ์ด์ ์ ์นธ์ด ์น ํด์ก์ด์ผ ํ๋ค
continue
printf "\n[3] ํ ๊ฑธ์ ๋ ๊ฐ ๋ค โ ๋ฐฉ๊ธ ์ง๋์จ ์นธ์ ํ์ธํ๋ค\n"
printf " (24,13,12) ๊ฐ = %d (1 ์ด๋ฉด ๋ค์ ๋ชป ๋ฐ๋๋ค)\n", *(unsigned char *)(0x404060 + 24 + 25*13 + 625*12)
printf "\n[4] ํต๋ก ์นธ ์๋ฅผ ์คํ ์ค ๋ฉ๋ชจ๋ฆฌ์์ ์ง์ ์ผ๋ค\n"
set $n = 0
set $i = 0
while $i < 15625
if *(unsigned char *)(0x404060 + $i) == 0
set $n = $n + 1
end
set $i = $i + 1
end
printf " ๊ฐ์ด 0 ์ธ ์นธ = %d ๊ฐ (์๋ 107 ์นธ, ์ง๋์จ 2์นธ์ด ์ด๋ฏธ ์น ํด์ก๋ค)\n", $n
quitprintf 'zzzzzz222222277779999zzzzzzzssssssss999777777777222222222222zzzzz999zzz999777ssss99999999999777777sssssssz\n' | gdb -q -batch -x runtime_check.gdb extracted/chall
[1] ์์ ์ขํ๊ฐ (24,12,12) ๋ก ํ์ธ๋๋ค. [2] ์ฒซ ๊ธ์ z ์ y ๊ฐ 12 โ 13 ์ผ๋ก ๋์๋ค. [3] ๋ฐฉ๊ธ ์ง๋์จ ์นธ์ ๊ฐ์ด 1 ๋ก ๋ฐ๋์ด ์๋ค. ๋ชธํต์ด ๋จ๋๋ค๋ ๊ฒ ์คํ ์ค์๋ ๊ทธ๋๋ก๋ค.
[4] ๋ ๊ฒฉ์๋ฅผ ๋ฉ๋ชจ๋ฆฌ์์ ์ง์ ํ์ ๊ฒ์ด๋ค. ๊ฐ์ด 0 ์ธ ์นธ์ด 105๊ฐ. ์ด๋ ์ด๋ฏธ ๋ ์นธ(์์๊ณผ ์ฒซ ๊ฑธ์)์ ์น ํ์ผ๋ ์๋๋ 107์นธ์ด๋ค.
15,625์นธ ์ค ํต๋ก๊ฐ 107์นธ๋ฟ์ด๋ผ๋ ๊ฒ ์ฌ๊ธฐ์ ์ฒ์ ๋๋ฌ๋๋ค.
๐ฏ ๊ฒฉ์๋ฅผ ๊บผ๋ด ๋ณด๋ ์ธ๊ธธ์ด์๋ค
ํ์ผ์์ ๊ฒฉ์๋ฅผ ๊ทธ๋๋ก ๋ ์ ๊ตฌ์กฐ๋ฅผ ๋ณธ๋ค. .data ๋ ํ์ผ ์คํ์
0x3040, ๊ฐ์์ฃผ์ 0x404040 ์ด๋ฏ๋ก ๊ฒฉ์(0x404060)๋ ํ์ผ์์ 0x3060 ์ด๋ค.
ํต๋ก ์นธ๋ง๋ค ์ด์ํ ํต๋ก๊ฐ ๋ช ๊ฐ์ธ์ง ์ธ๋ฉด ๋ฏธ๋ก์ ์ฑ์ง์ด ํ ๋ฒ์ ๋์จ๋ค. 1์ด๋ฉด ๋์ , 2๋ฉด ์ธ๊ธธ ์ค๊ฐ, 3 ์ด์์ด๋ฉด ๊ฐ๋ฆผ๊ธธ์ด๋ค.
#!/usr/bin/env python3
"""๊ฒฉ์๊ฐ ์ ๋ต์ ํ๋๋ง ๊ฐ๋์ง ๊ตฌ์กฐ๋ก ํ์ธํ๋ค."""
import collections
from solve import MOVES, START, GOAL, load_grid, bfs
g = load_grid("extracted/chall")
opens = {(x, y, z)
for z in range(25) for y in range(25) for x in range(25)
if g[x + 25 * y + 625 * z] == 0}
deg = collections.Counter(
sum(1 for d in MOVES.values() if (x + d[0], y + d[1], z + d[2]) in opens)
for (x, y, z) in opens
)
print(f"ํต๋ก ์นธ : {len(opens)} / 15625")
print(f"์ด์ ํต๋ก ์ ๋ถํฌ : {dict(sorted(deg.items()))}")
print(f" ๋์ (1๊ฐ) : {deg[1]}")
print(f" ์ธ๊ธธ(2๊ฐ) : {deg[2]}")
print(f" ๊ฐ๋ฆผ๊ธธ(3๊ฐ+) : {sum(v for k, v in deg.items() if k >= 3)}")
print()
ends = sorted(p for p in opens
if sum(1 for d in MOVES.values() if (p[0] + d[0], p[1] + d[1], p[2] + d[2]) in opens) == 1)
print(f"๋์ ์ขํ : {ends}")
print(f"์์ {START} / ๋ชฉํ {GOAL} ์ ์ผ์น? {set(ends) == {START, GOAL}}")
print()
path = bfs(g)
pts, cur = [START], START
for ch in path:
d = MOVES[ch]
cur = (cur[0] + d[0], cur[1] + d[1], cur[2] + d[2])
pts.append(cur)
print(f"BFS ๊ฒฝ๋ก ๊ฑธ์ : {len(path)}")
print(f"๊ฒฝ๋ก๊ฐ ๋ฐ๋ ์นธ : {len(set(pts))}")
print(f"ํต๋ก ์ ์ฒด์ ๊ฐ๋ : {set(pts) == opens} โ ๊ฐ์ผ๋ฉด ๊ณ๊ฐ์ง๊ฐ ํ๋๋ ์๋ค๋ ๋ป")python3 analyze_grid.py
์ฝ์ ๊ฒ์ด ์ธ ๊ฐ์ง๋ค.
๊ฐ๋ฆผ๊ธธ์ด 0๊ฐ๋ค. ํต๋ก 107์นธ์ด ์ ๋ถ ์ด์ 2๊ฐ(๋์ ๋ง 1๊ฐ)๋ผ ๋ถ๊ธฐ๊ฐ ์๋ค. ํ๋๋ก ์ด์ด์ง ๊ด์ด๋ค.
๋์ ๋ ๊ณณ์ด ์์๊ณผ ๋ชฉํ์ ์ ํํ ์ผ์นํ๋ค. ์ฆ ์ด ๊ด์ ์ ๋์ด ๋ฌธ์ ์ ์ถ๋ฐ์ ๊ณผ ๋์ฐฉ์ ์ด๋ค.
BFS ๊ฒฝ๋ก๊ฐ ํต๋ก ์ ์ฒด์ ๊ฐ๋ค. 106๊ฑธ์์ด ๋ฐ๋ 107์นธ์ด ์ด๋ฆฐ ์นธ ์ ๋ถ๋ค. ๊ณ๊ฐ์ง๋, ๋ง๋ค๋ฅธ ๊ธธ๋ ์๋ค.
๊ทธ๋์ ๋ต์ด ํ๋๋ฟ์ด๋ค. ๋ฌธ์ ํ์ด์ง์ "์ ๋ต์ด ์ฌ๋ฌ ๊ฐ์๋ ๊ฒ์ ์์ ํ๋ค"๋ ๊ธฐ๋ก๊ณผ ๋ง์๋จ์ด์ง๋ค.
๋์ผ๋ก๋ ํ์ธํด ๋๋ ค๊ณ ๊ฒฉ์๋ฅผ z ํ๋ณ๋ก ํผ์ณ ๊ทธ๋ ธ๋ค. ์์ผ๋ก ๊ทธ๋ฆฐ ๋์์ด ์๋๋ผ ์ถ์ถํ ๋ฐ์ดํฐ๋ฅผ ๊ทธ๋๋ก ๋ ๋ํ ๊ฒ์ด๋ค.

z ํ์ ์ค๊ฐ๋ฉฐ ์ด์ด์ง๋ ๊ฒ ๋ณด์ธ๋ค. ํ ํ๋์ ์ ํ๋๋ง ์ฐํ z ๋ค(1318, 2022)์ ๊ฒฝ๋ก๊ฐ ๊ทธ ์ธต์ ๊ดํตํด ์ง๋๊ฐ๊ธฐ๋ง ํ๋ ๊ตฌ๊ฐ์ด๋ค.
๐ Full Exploit
BFS ๋ก ์ต๋จ๊ฒฝ๋ก๋ฅผ ์ฐพ๋๋ค. ๋ฑ ์ ์ฝ("๊ฐ์ ์นธ์ ๋ ๋ฒ ๋ฐ์ผ๋ฉด ์คํจ")์ ๋ฐ๋ก ์ฒ๋ฆฌํ ํ์๊ฐ ์๋ค โ BFS ๊ฐ ์ฐพ๋ ์ต๋จ๊ฒฝ๋ก๋ ์ ์ด์ ๊ฐ์ ์นธ์ ๋ ๋ฒ ์ง๋์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
๋ชฉํ ํ์ ์ด ์ด๋ ๊ฐ๋ฅ ํ์ ๋ณด๋ค ๋จผ์ ๋ผ๋ ์ ๋ง ์ฝ๋์ ๋ฐ์ํ๋ฉด ๋๋ค.
#!/usr/bin/env python3
"""Snaky (DreamHack, Gold 4 / reversing) โ solver
๋ฐ์ด๋๋ฆฌ๊ฐ ํ๋ ์ผ:
.data 0x404060 ์ 25x25x25 ๋ฐ์ดํธ ๋ฐฐ์ด์ด ์๋ค. ์ธ๋ฑ์ค๋ x + 25*y + 625*z.
๊ฐ 1 = ๋งํ ์นธ. ์์ (24,12,12) ์์ ์ถ๋ฐํด ์
๋ ฅ ๋ฌธ์์ด์ ํ ๊ธ์์ฉ ๋ฐฉํฅ์ผ๋ก ์ฝ๋๋ค.
K: x+1 9: x-1 z: y+1 7: y-1 2: z+1 s: z-1
๊ฐ ๊ฑธ์๋ง๋ค
โ (0,12,12) ์ ๋๋ฌํ์ผ๋ฉด ๊ทธ ์๋ฆฌ์์ ์ฑ๊ณต(good :)
โก 0..24 ๋ฒ์๋ฅผ ๋ฒ์ด๋๊ฑฐ๋ ๊ฐ์ด 1 ์ธ ์นธ์ด๋ฉด ์คํจ
โข ์๋๋ฉด ๊ทธ ์นธ์ 1 ๋ก ์น ํ๊ณ ๊ณ์ โ ์ง๋์จ ์นธ์ ๋ฒฝ์ผ๋ก ๋ง๋ ๋ค(๋ฑ)
โข ๋๋ฌธ์ ๊ฒฝ๋ก๋ ์๊ธฐ ์์ ๊ณผ ๋ง๋ ์ ์๋ค. ๊ทธ๋์ ๋จ์๊ฒฝ๋ก๋ง ๋ต์ด ๋๋ค.
BFS ์ต๋จ๊ฒฝ๋ก๋ ์ ์ด์ ๊ฐ์ ์นธ์ ๋ ๋ฒ ๋ฐ์ง ์์ผ๋ฏ๋ก ์ด ์ ์ฝ์ ์๋์ผ๋ก ๋ง์กฑํ๋ค.
flag = DH{<์ฐพ์ ๊ฒฝ๋ก ๋ฌธ์์ด>}
"""
import argparse
import collections
import sys
N = 25
START = (24, 12, 12)
GOAL = (0, 12, 12)
# ๋ฌธ์ โ (dx, dy, dz). ๋์ค์ด์
๋ธ 0x4013a6~0x401406 ๊ทธ๋๋ก.
MOVES = {
"K": (1, 0, 0),
"9": (-1, 0, 0),
"z": (0, 1, 0),
"7": (0, -1, 0),
"2": (0, 0, 1),
"s": (0, 0, -1),
}
GRID_VA, DATA_VA, DATA_OFF = 0x404060, 0x404040, 0x3040
def load_grid(path: str) -> bytes:
"""ELF ์์ 25^3 ๊ฒฉ์๋ฅผ ๊ทธ๋๋ก ๋ ์จ๋ค (์น์
ํค๋ ์์ด ๊ณ ์ ์คํ์
)."""
blob = open(path, "rb").read()
off = DATA_OFF + (GRID_VA - DATA_VA)
g = blob[off:off + N * N * N]
if len(g) != N * N * N:
sys.exit(f"๊ฒฉ์๋ฅผ ๋ชป ์ฝ์๋ค: {len(g)} ๋ฐ์ดํธ")
return g
def blocked(g: bytes, x: int, y: int, z: int) -> bool:
"""can_move() ์ ๊ฐ์ ํ์ โ ๋ฒ์ ๋ฐ์ด๊ฑฐ๋ ๊ฐ์ด 1 ์ด๋ฉด ๋ชป ๊ฐ๋ค."""
if not (0 <= x <= 24 and 0 <= y <= 24 and 0 <= z <= 24):
return True
return g[x + 25 * y + 625 * z] == 1
def bfs(g: bytes) -> str | None:
"""START โ GOAL ์ต๋จ ๊ฒฝ๋ก๋ฅผ ์ด๋ ๋ฌธ์์ด๋ก ๋๋ ค์ค๋ค."""
prev: dict = {START: None}
q = collections.deque([START])
while q:
cur = q.popleft()
for ch, (dx, dy, dz) in MOVES.items():
nxt = (cur[0] + dx, cur[1] + dy, cur[2] + dz)
if nxt == GOAL: # ๋ชฉํ ํ์ ์ด ์ด๋ ๊ฐ๋ฅ ํ์ ๋ณด๋ค ๋จผ์ ๋ค
path, node = [ch], cur
while prev[node] is not None:
pch, pnode = prev[node]
path.append(pch)
node = pnode
return "".join(reversed(path))
if nxt in prev or blocked(g, *nxt):
continue
prev[nxt] = (ch, cur)
q.append(nxt)
return None
def count_simple_paths(g: bytes, limit: int = 5) -> int:
"""๋จ์๊ฒฝ๋ก๊ฐ ์ ๋ง ํ๋๋ฟ์ธ์ง ์ผ๋ค (์ด๋ฆฐ ์นธ์ด 107๊ฐ๋ผ ์์ ํ์์ด ๋๋ค)."""
found = 0
seen = {START}
def dfs(cur):
nonlocal found
if found >= limit:
return
for ch, (dx, dy, dz) in MOVES.items():
nxt = (cur[0] + dx, cur[1] + dy, cur[2] + dz)
if nxt == GOAL:
found += 1
if found >= limit:
return
continue
if nxt in seen or blocked(g, *nxt):
continue
seen.add(nxt)
dfs(nxt)
seen.discard(nxt)
dfs(START)
return found
def simulate(g: bytes, s: str) -> bool:
"""๋ฐ์ด๋๋ฆฌ์ check() ๋ฅผ ๊ทธ๋๋ก ํ๋ด๋ด ๊ฒ์ฆํ๋ค."""
if any(c not in MOVES for c in s):
return False
grid = bytearray(g)
x, y, z = START
grid[x + 25 * y + 625 * z] = 1
for c in s:
dx, dy, dz = MOVES[c]
x, y, z = x + dx, y + dy, z + dz
if (x, y, z) == GOAL:
return True
if not (0 <= x <= 24 and 0 <= y <= 24 and 0 <= z <= 24):
return False
if grid[x + 25 * y + 625 * z] == 1:
return False
grid[x + 25 * y + 625 * z] = 1
return False
def main() -> int:
ap = argparse.ArgumentParser()
ap.add_argument("binary", nargs="?", default="extracted/chall")
ap.add_argument("--count-paths", action="store_true", help="๋จ์๊ฒฝ๋ก ๊ฐ์๋ ์ผ๋ค")
a = ap.parse_args()
g = load_grid(a.binary)
opens = sum(1 for b in g if b == 0)
print(f"[*] ๊ฒฉ์ 25x25x25 = {len(g)} ์นธ, ํต๋ก {opens} ์นธ / ๋ฒฝ {len(g) - opens} ์นธ")
print(f"[*] ์์ {START} โ ๋ชฉํ {GOAL}")
path = bfs(g)
if path is None:
print("[-] ๊ฒฝ๋ก ์์")
return 1
print(f"[+] ๊ฒฝ๋ก ๊ธธ์ด {len(path)}")
print(f"[+] ๊ฒฝ๋ก {path}")
print(f"[+] ์์ฒด ๊ฒ์ฆ(check ์ฌํ) : {'ํต๊ณผ' if simulate(g, path) else '์คํจ'}")
if a.count_paths:
n = count_simple_paths(g)
print(f"[*] ๋จ์๊ฒฝ๋ก ๊ฐ์ : {'5๊ฐ ์ด์' if n >= 5 else n}๊ฐ")
print(f"[+] FLAG: DH{{{path}}}")
return 0
if __name__ == "__main__":
sys.exit(main())python3 solve.py --count-paths
--count-paths ๋ DFS ๋ก ๋จ์๊ฒฝ๋ก๋ฅผ ์ ๋ถ ์ธ๋ ์ต์
์ด๋ค. ํต๋ก๊ฐ 107์นธ๋ฟ์ด๋ผ ์์ ํ์์ด ์์๊ฐ์ ๋๋๋ค. ๊ฒฐ๊ณผ๋ 1๊ฐ โ ๊ตฌ์กฐ ๋ถ์๊ณผ ์ผ์นํ๋ค.
์ค์ ๋ฐ์ด๋๋ฆฌ๋ก ํ์ธ
๊ณ์ฐ์ด ๋ง์๋ ํ๋ก๊ทธ๋จ์ด good :) ์ ๋ฑ๋์ง๋ ๋ณ๊ฐ๋ค. ๋์กฐ๊ตฐ์ ๊ฐ์ด ๋ฃ์ด ๋๋ฆฐ๋ค.
#!/usr/bin/env python3
"""์ฐพ์ ๊ฒฝ๋ก๋ฅผ ์ค์ ๋ฐ์ด๋๋ฆฌ์ ๋จน์ฌ good :) ์ด ๋์ค๋์ง ํ์ธํ๋ค."""
import subprocess
BIN = "./extracted/chall"
ANSWER = ("zzzzzz222222277779999zzzzzzzssssssss999777777777222222222222"
"zzzzz999zzz999777ssss99999999999777777sssssssz")
def run(s: str) -> str:
p = subprocess.run([BIN], input=s + "\n", capture_output=True, text=True, timeout=20)
return p.stdout.strip()
cases = [
("์ ๋ต ๊ฒฝ๋ก", ANSWER),
("๋ง์ง๋ง ๊ธ์๋ง ๋ฐ๊ฟ", ANSWER[:-1] + "7"),
("ํ ๊ฑธ์ ์งง๊ฒ", ANSWER[:-1]),
("์ญ์", ANSWER[::-1]),
]
for label, s in cases:
out = run(s)
print(f"{label:20s} len={len(s):3d} โ {out}")
print()
print(f"FLAG: DH{{{ANSWER}}}")python3 verify.py
์ ๋ต๋ง good :), ๋๋จธ์ง ์
์ ์ ๋ถ wrong :(.
์ญ์์ด ์คํจํ๋ ๊ฒ ์ฌ๋ฐ๋ค. ํต๋ก๋ ๋์นญ์ธ๋ฐ ์์๊ณผ ๋ชฉํ๊ฐ ์ ํด์ ธ ์์ผ๋ ๋ฐฉํฅ์ ๋ค์ง์ผ๋ฉด ์ฒซ ๊ฑธ์๋ถํฐ ๋ฒฝ์ด๋ค.
DH{zzzzzz222222277779999zzzzzzzssssssss999777777777222222222222zzzzz999zzz999777ssss99999999999777777sssssssz}๐งช ์ฌํ
reproduce.sh ํ๋๋ก ๊ฒฉ์ ์ถ์ถ๋ถํฐ ์ค์ ๋ฐ์ด๋๋ฆฌ ํ์ธ๊น์ง ๋๋ค. ์ธ๋ถ ์๋ฒ๊ฐ ํ์ ์๋ ์คํ๋ผ์ธ ๋ฌธ์ ๋ผ ์ธ์๋ ์๋ค.
./reproduce.shํ์ํ ๊ฑด python3, objdump, ๊ทธ๋ฆฌ๊ณ x86-64 ๋ฆฌ๋
์ค๋ฟ์ด๋ค. ๋ฐ์ด๋๋ฆฌ๊ฐ ๋์ ๋งํฌ๋ผ glibc ๊ฐ ์์ผ๋ฉด ๊ทธ๋๋ก ๋๋ค.
ํ์ ์ ์ด๋ ๊ฒ ์ฝ๋๋ค.
| ํ๋ฉด | ๋ป | ๋์ฒ |
|---|---|---|
๊ฒฉ์๋ฅผ ๋ชป ์ฝ์๋ค | ํ์ผ ์คํ์ ์ด ์ ๋ง์ | readelf -SW ๋ก .data ์คํ์
์ ๋ค์ ํ์ธ |
ํต๋ก 107 ์นธ ์ด ์๋ | ๋ค๋ฅธ ๋ฒ์ ์ ๋ฐฐํฌ๋ณธ | 2025.03.05 ์ดํ ๋ฐฐํฌ๋ณธ์ธ์ง ํ์ธ |
๋จ์๊ฒฝ๋ก ๊ฐ์ : 5๊ฐ ์ด์ | ๋ฏธ๋ก์ ๊ฐ๋ฆผ๊ธธ์ด ์๊น | ์์ ๊ฐ์ โ ์ ๋ฐฐํฌ๋ณธ์ผ ๊ฐ๋ฅ์ฑ |
์์ฒด ๊ฒ์ฆ : ์คํจ | ์ด๋ํ๋ ์์ ํด์์ด ํ๋ฆผ | simulate() ๋ฅผ ๋์ค์ด์
๋ธ๊ณผ ๋ค์ ๋์กฐ |
wrong :( | ๋ฐ์ด๋๋ฆฌ์ ์คํ ๊ถํ์ด ์๊ฑฐ๋ ๋ค๋ฅธ ํ์ผ | chmod +x extracted/chall |
๋ง์ง๋ง ์ค์ ์ค์ ๋ก ๋ฐ์๋ค. ๋ฐฐํฌ zip ์ด ์คํ ๋นํธ๋ฅผ ๋ณด์กดํ์ง ์์์ chmod ์์ด๋ ์์ ์คํ์ด ์ ๋๋ค.
๐ ๊ฒฐ๋ก
์น์ ํฌ๊ธฐ๋ ๊ณต์ง๋ก ์ป๋ ๋จ์๋ค.
readelf -S ํ ๋ฒ์ด๋ฉด ๋ก์งํ์ธ์ง ๋ฐ์ดํฐํ์ธ์ง ๊ฐ๋ฆฐ๋ค. .text ๊ฐ ์๊ณ .data ๊ฐ ํฌ๋ฉด ๋ต์ ํ ์์ ์๊ณ , ํ ์ผ์ ๊ทธ ํ์ ๋ชจ์์ ์์๋ด๋ ๊ฒ์ด๋ค. ์ด ๋ฌธ์ ๋ ๊ทธ ํ๋จ๋ง์ผ๋ก ๋ฐฉํฅ์ด ์กํ๋ค.
๊ณฑ์ ์์๊ฐ ์๋ฃ๊ตฌ์กฐ๋ฅผ ๋งํ๋ค.
imul rsi,rax,0x271 ์์ 625 ๋ฅผ, ๊ทธ ์์์ 25 ๋ฅผ ์ฝ๋ ์๊ฐ 3์ฐจ์ ๋ฐฐ์ด์ด ํ์ ๋๋ค. ์ปดํ์ผ๋ฌ๊ฐ ๊ณฑ์
์ ์ํํธ์ ๋ง์
์ผ๋ก ์ชผ๊ฐ ๋์ ํ๋์ ์ ๋ณด์ผ ๋ฟ์ด๋ค. ์์๋ฅผ ์ธ์๋ถํดํด ๋ณด๋ ์ต๊ด์ด ์ฌ๊ธฐ์ ๊ฐ์ ํ๋ค.
์ฐ์ฐ ์์๊น์ง ์ฝ์ด์ผ ์ ํํ ๋ชจ๋ธ์ด ๋๋ค.
๋ชฉํ ํ์ ์ด ์ด๋ ๊ฐ๋ฅ ํ์ ๋ณด๋ค ๋จผ์ ์ค๋ ๊ฒ, ๊ทธ๋ฆฌ๊ณ ์น ํ๊ธฐ๊ฐ ๋งจ ๋ง์ง๋ง์ธ ๊ฒ โ ๋ ์ค ํ๋๋ง ์๋ชป ์ฎ๊ฒจ๋ ์๋ฎฌ๋ ์ดํฐ๊ฐ ์๋ณธ๊ณผ ์ด๊ธ๋๋ค. ๋์ค์ด์ ๋ธ์์ ๋ถ๊ธฐ์ ์์น๋ ์กฐ๊ฑด ์์ฒด๋งํผ ์ค์ํ๋ค.
ํผ ๋ค์ ๊ตฌ์กฐ๋ฅผ ํ ๋ฒ ๋ ํ์ธํ๋ฉด ๋ต์ด ๋ง์๋ค๋ ๊ฑธ ์ค์ค๋ก ์ ์ ์๋ค.
๊ฒฝ๋ก๋ฅผ ์ฐพ๊ณ ๋๋ผ ์๋ ์์์ง๋ง, ํต๋ก์ ์ฐจ์ ๋ถํฌ๋ฅผ ์ธ ๋ณด๋ ๊ฐ๋ฆผ๊ธธ์ด 0๊ฐ์๋ค. ๊ทธ๋์ ๋ต์ด ํ๋๋ฟ์ด๋ผ๋ ๊ฒ ํ์ ๊ฒฐ๊ณผ๊ฐ ์๋๋ผ ๊ตฌ์กฐ๋ก ์ค๋ช ๋๋ค. ๋ฌธ์ ํ์ด์ง์ ์์ ๊ธฐ๋ก๊ณผ๋ ๋ง๋ฌผ๋ฆฐ๋ค. ์ด๋ฐ ํ์ธ์ ๋ช ์ค์ด๋ฉด ๋๊ณ , ํ๋ฆฐ ๋ต์ ๋ถ๋ค๊ณ ์๋ ์๊ฐ์ ์ค์ฌ ์ค๋ค.
๋ฐฉ์ด ์ชฝ์์ ๋ณด๋ฉด, ๊ฒ์ฆ ๋ก์ง์ ๋ฐ์ดํฐ ํ๋ก ์ฎ๊ธฐ๋ ๊ฑด ๋๋ ํ๊ฐ ์๋๋ค. ํ๊ฐ ํฌ๋ฉด ์คํ๋ ค ๋์ ๋๊ณ , ์ธ๋ฑ์ค ๊ณ์ฐ์ ํ ์ค์ด ๊ตฌ์กฐ๋ฅผ ํต์งธ๋ก ์๋ ค ์ค๋ค. ๊ฐ์ ์งํค๊ณ ์ถ์ผ๋ฉด ํ๋ฅผ ์จ๊ธธ ๊ฒ ์๋๋ผ ์ ์ด์ ํด๋ผ์ด์ธํธ์ ๋์ง ์์์ผ ํ๋ค.
Comments
๋๊ธ
๋๊ธ์ ๋จ๊ธฐ๋ ค๋ฉด ๋ก๊ทธ์ธ์ด ํ์ํด์. (๋ค์ด๋ฒ ยท ๊ตฌ๊ธ ๊ณ์ )
๋๊ธ ๋ถ๋ฌ์ค๋ ์คโฆ