๋ฌธ์ : DreamHack โ rev-basic-8 (Reversing Basic Challenge #8) ๋ถ๋ฅ: Reversing ๋์ด๋: ๐ฅ Bronze 4 FLAG:
DH{Did_y0u_brute_force?}
๋ฌธ์ ๊ฐ์
| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| ๋ฌธ์ ๋ช | rev-basic-8 |
| ๋์ด๋ | ๐ฅ Bronze 4 |
| ๋ถ๋ฅ | Reversing |
| ์ ๊ณต ํ์ผ | chall8.exe (PE32+ x86-64, Windows ์ฝ์) |
| ํต์ฌ ๊ธฐ๋ฒ | ์ ๋ ฅ ๋ฐ์ดํธ ร 0xfb (mod 256)๋ฅผ ํ์ ๋น๊ต โ ๊ณฑ์ ์ ๋ชจ๋๋ฌ ์ญ์์ผ๋ก ์ญ์ฐ |
rev-basic ์๋ฆฌ์ฆ ์ฌ๋ ๋ฒ์งธ. ์ด๋ฒ์๋ ๋ฌธ์์ด์ ์
๋ ฅ๋ฐ์ Correct / Wrong์ ์ถ๋ ฅํ๋ ๋จ์ํ ์ฝ์ ํ๋ก๊ทธ๋จ์ด๋ค. ์์ ๋ฌธ์ ๋ค(strcmp, ๊ธ์๋ณ cmp, ์ ์ ๋ฐฐ์ด, XOR, ๋๋ธ ์ค์, ์ธ์ ํฉ, AES S-box)๊ณผ ๊ฒฐ์ด ๋น์ทํ๋ฐ, ์ด๋ฒ์ ๊ฒ์ฆ์ ์ฐ๋ ์ฐ์ฐ์ด ๊ณฑ์
์ด๋ค. ์์ ํ๋๋ง ๊ณฑํ๊ณ ํ์ ๋ฐ์ดํธ๋ง ๋จ๊ธฐ๋ ์ฐ์ฐ์ด๋ผ, ๊ทธ ์์์ ๋ชจ๋๋ฌ ์ญ์๋ง ๊ตฌํ๋ฉด ๊ณง๋ฐ๋ก ์ญ์ฐ์ด ๋๋๋ค.
file chall8.exe
strings -a chall8.exe | grep -E "Input|Correct|Wrong"
์ด์ ๋ฌธ์ ๋ค๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ์ฌ๋ณผ์ stripped ์ํ๋ค. Input : ์ ์ถ๋ ฅํ๊ณ ์
๋ ฅ์ ๋ฐ์ ๋ค Correct๋ Wrong ์ค ํ๋๋ฅผ ์ฐ๋ ๊ตฌ์กฐ๋ผ๋ ๊ฒ๋ง ๋ฌธ์์ด๋ก ๋จผ์ ํ์ธํ๋ค.
๐ฌ ์ ์ฐฐ โ check ํจ์ ์ฐพ๊ธฐ
์ฌ๋ณผ์ด ์์ผ๋ PE ํค๋์ AddressOfEntryPoint๋ถํฐ ๋ฐ๋ผ๊ฐ๋ค.
objdump -f chall8.exe | grep "start address"์ํธ๋ฆฌ๋ 0x140001584. ๊ฑฐ๊ธฐ์๋ถํฐ ๋ช ๋จ๊ณ ๋ด๋ ค๊ฐ๋ฉด main ๊ฒฉ์ธ ํจ์(0x140001120)๊ฐ ๋์ค๋๋ฐ, ์คํ ๋ฒํผ๋ฅผ 0์ผ๋ก ์ฑ์ฐ๊ณ "Input : "์ ์ถ๋ ฅํ ๋ค์ scanf("%256s", buf)๋ก ์
๋ ฅ์ ๋ฐ๊ณ , ๊ทธ ๋ฒํผ ํฌ์ธํฐ๋ฅผ ์ธ์๋ก 0x140001000์ ํจ์๋ฅผ ํธ์ถํ๋ค. ๋ฐํ๊ฐ์ด 0์ด ์๋๋ฉด Correct, 0์ด๋ฉด Wrong์ ์ถ๋ ฅํ๊ณ ์ข
๋ฃํ๋ค. ์ด 0x140001000 ํจ์๊ฐ ๊ฒ์ฆ ๋ก์ง ์ ์ฒด๋ค.
objdump -M intel -d --start-address=0x140001000 --stop-address=0x140001060 chall8.exe
๋ฃจํ ํ๋์ ๊ณฑ์ ํ ๋ฒ, ๋น๊ต ํ ๋ฒ. ํต์ฌ๋ง ๋จ๊ธฐ๋ฉด ์ด๋ ๊ฒ ์ฝํ๋ค.
; rcx = ์
๋ ฅ ๋ฒํผ, (%rsp) = ์นด์ดํฐ i, ์์๊ฐ 0
loop:
cmp rax, 0x15 ; i >= 21 ์ด๋ฉด
jae correct ; โ ๋ฃจํ ์ข
๋ฃ, return 1
movzx eax, BYTE PTR [rcx+rax*1] ; al = buf[i]
imul eax, eax, 0xfb ; eax = al * 0xfb (251)
and eax, 0xff ; ํ์ 1๋ฐ์ดํธ๋ง ๋จ๊น (mod 256)
movzx ecx, BYTE PTR [rdx+rcx*1] ; cl = table[i] (VA 0x140003000)
cmp eax, ecx
jne wrong ; ๋ค๋ฅด๋ฉด return 0
inc i; jmp loop
correct:
mov eax, 0x1
retC๋ก ์ฎ๊ธฐ๋ฉด ํ ์ค์ด๋ค.
for (int i = 0; i < 21; i++)
if ((buf[i] * 0xfb) & 0xff != TABLE[i])
return 0; // Wrong
return 1; // Correct0x15(21)๊น์ง ๋๋๋ฐ scanf("%256s", ...)๋ก ๋ฐ์ ๋ฌธ์์ด์ ์ค์ ๊ธ์ ์๋ ๊ทธ๋ณด๋ค ์ ์ ๊ฒ์ด๋ค โ ๋ง์ง๋ง ํ ์นธ์ ๋ค์์ ๋ณด๋ฏ NUL ์ข
๊ฒฐ์ ๊ฒ์ฆ์ด๋ค.
๐ฃ ํต์ฌ โ 0xfb ๊ณฑ์ ์ ๊ฑฐ๊พธ๋ก
๋น๊ต ๋์ ํ
์ด๋ธ์ .data ์น์
, VA 0x140003000์ 21๋ฐ์ดํธ๋ก ๋ฐํ ์๋ค.
objdump -s -j .data chall8.exe | sed -n '1,6p'
ac f3 0c 25 a3 10 b7 25 16 c6 b7 bc 07 25 02 d5 c6 11 07 c5 00 โ 21๋ฐ์ดํธ, ๋ง์ง๋ง์ด 00์ด๋ค.
๊ฒ์ฆ์์ (buf[i] * 0xfb) & 0xff == table[i]. & 0xff๋ ๊ฒฐ๊ตญ mod 256๊ณผ ๊ฐ์ผ๋ ์ ์๋ก ๊ด์ ์์ ๋ณด๋ฉด buf[i] * 251 โก table[i] (mod 256)์ด๋ค. 251์ ํ์๋ผ 256๊ณผ ์๋ก์(gcd(251, 256) = 1)์ด๊ณ , ๊ทธ๋์ mod 256์์ ๊ณฑ์
์ ์ญ์์ด ์กด์ฌํ๋ค. ์ญ์์ inv๋ผ ํ๋ฉด ์๋ณ์ ๊ณฑํด์ buf[i] โก table[i] * inv (mod 256)๋ก ๋ฐ๋ก ๋์ด๊ฐ๋ค.
โถ๐ ์ฝ์ง โ XOR์ธ ์ค ์์๋ค๊ฐ, ๊ทธ๋ฆฌ๊ณ 21๋ฒ์งธ ๋ฐ์ดํธ์ ์ ์ฒด
imul eax,eax,0xfb ํ ์ค๋ง ํ์์ ๋ ์๊ฐ์ ์ผ๋ก xor๋ฅ ์์ ์ฐ์ฐ์ธ ์ค ์๊ณ ๊ทธ๋ฅ table[i] ^ 0xfb๋ฅผ ์๋ํ๋ค. ๋น์ฐํ ์ ๋ง๋๋ค โ ๋ช
๋ น์ด๊ฐ ๋ถ๋ช
ํ imul์ด๊ณ ๋ค์ and eax,0xff๋ก ํ์ ๋ฐ์ดํธ๋ง ์๋ฅด๋ ๊ฑธ ๋ณด๊ณ ์์ผ "๊ณฑ์
ํ mod"๋ผ๋ ๊ฑธ ๋ค์ ํ์ธํ๋ค.
๋ ๋ฒ์งธ๋ก ๊ฑธ๋ฆฐ ๊ฑด ๋ฃจํ ์ํ์ด 0x15(21)์ธ๋ฐ scanf๋ก ๋ฐ๋ ์
๋ ฅ์ด 21๊ธ์์ผ ๋ฆฌ๊ฐ ์์ด ๋ณด์ธ๋ค๋ ์ . ํ
์ด๋ธ ๋ง์ง๋ง ๋ฐ์ดํธ๊ฐ 0x00์ธ ๊ฑธ ๋ณด๊ณ ๊ฐ์ด ์๋ค โ table[20] = 0์ด๋ฉด buf[20] * 251 โก 0 (mod 256)์ ๋ง์กฑํ๋ ๊ฐ์ฅ ์์ฐ์ค๋ฌ์ด ๊ฐ์ buf[20] = 0์ด๋ค. scanf("%256s", ...)์ ์ฝ์ ๋ฌธ์์ด ๋ค์ ํญ์ NUL์ ๋ถ์ด๋ฏ๋ก, 20๋ฒ์งธ ์ธ๋ฑ์ค(0-based)๋ ์ค์ ์
๋ ฅ ๊ธ์๊ฐ ์๋๋ผ ๋ฌธ์์ด ์ข
๊ฒฐ์ ์์ฒด๊ฐ ๊ฒ์ฌ๋นํ๋ ์๋ฆฌ๋ค. ์ฆ ์ง์ง ์
๋ ฅ์ 20๊ธ์, ๊ฒ์ฆ ๋ฃจํ์ 21๋ฒ์งธ ์นธ์ "์ ํํ 20๊ธ์์์ ๋๋๋ผ"๋ ๊ธธ์ด ์ฒดํฌ๋ฅผ ๊ฒธํ๋ค.
๊ณฑ์
์ญ์์ ๊ตฌํ๋ ๋ฐฉ๋ฒ์ ํ์ฅ ์ ํด๋ฆฌ๋ ์๊ณ ๋ฆฌ์ฆ์ธ๋ฐ, ํ์ด์ฌ pow(a, -1, m)์ด ๊ทธ๋๋ก ๊ณ์ฐํด์ค๋ค.

๐ฏ ์ญ์ฐ โ solve.py
ํ
์ด๋ธ์ ๋ฐ์ด๋๋ฆฌ์์ ๊ทธ๋๋ก ์ฎ๊ฒจ ์ ๊ณ , pow(0xfb, -1, 256)์ผ๋ก ์ญ์์ ๊ตฌํด ๊ณฑํ๊ธฐ๋ง ํ๋ฉด ๋๋ค.
#!/usr/bin/env python3
"""rev-basic-8: check()๊ฐ buf[i]*0xfb & 0xff == table[i] ๋ฅผ 21๋ฐ์ดํธ(0..20) ๊ฒ์ฆํ๋ค.
0xfb(=251)๋ mod 256์์ ํ์๋ผ ์ญ์์ด ์กด์ฌํ๋ฏ๋ก ๊ณฑ์
์ ๊ทธ๋๋ก ์ญ์ฐํ๋ค.
"""
TABLE = bytes.fromhex("acf30c25a310b72516c6b7bc072502d5c61107c500")
MUL = 0xfb
INV = pow(MUL, -1, 256) # 51
flag_bytes = bytes((b * INV) & 0xff for b in TABLE)
print("inverse of 0xfb mod 256 :", INV)
print("recovered bytes :", flag_bytes)
print("flag :", "DH{" + flag_bytes.rstrip(b"\x00").decode() + "}")
๋ณต์๋ ๋ฐ์ดํธ๋ Did_y0u_brute_force?\x00. ์์ ์ง์ํ ๋๋ก ๋ง์ง๋ง ๋ฐ์ดํธ๊ฐ NUL์ด๊ณ , ์ค์ ๋ก ํ์ดํํ ์
๋ ฅ์ 20๊ธ์ Did_y0u_brute_force?๋ค. ์ด๋ฆ ๊ทธ ์์ฒด๊ฐ ๋๋ฆฌ๋ ๋ฌธ๊ตฌ์ธ ๊ฒ ์ฌ๋ฐ๋ค โ 21๋ฐ์ดํธ์ง๋ฆฌ ์ข์ ํ์ ๊ณต๊ฐ์ด๋ผ ๋ธ๋ฃจํธํฌ์ค๋ ์ฌ์ค ๊ฐ๋ฅํ ๋ฒ์์ง๋ง, ์ญ์ ํ ๋ฒ์ด๋ฉด ์ฆ์ ๋๋๋ค.
๐ ๊ฒ์ฆ โ wine์ผ๋ก Correct ํ์ธ
ํ์ดํ(echo | wine chall8.exe)๋ ํ๊ฒฝ์ ๋ฐ๋ผ ์ค๋์ํ ์ ์์ด ์ฐ์ง ์๋๋ค. subprocess๋ก ์
๋ ฅ์ ์ง์ ๋ฃ๊ณ ์ถ๋ ฅ์ ๋ฐ๋๋ค.
#!/usr/bin/env python3
"""๋ณต์ํ ์
๋ ฅ์ chall8.exe์ ์ค์ ๋ก ๋จน์ฌ Correct ํ์ธ (wine, subprocess)"""
import subprocess, os
flag_input = "Did_y0u_brute_force?"
env = dict(os.environ)
env["WINEPREFIX"] = os.path.expanduser("~/.wine_revbasic8")
env["WINEDEBUG"] = "-all"
res = subprocess.run(["wine", "chall8.exe"], input=flag_input + "\n",
capture_output=True, text=True, env=env, timeout=120)
print("Input :", flag_input)
print("Output:", (res.stdout + res.stderr).strip())
Input : Correct. ๋ฐ์ด๋๋ฆฌ๊ฐ ์ง์ ๋ต์ ์ธ์ ํ๋ค. ์ด ๊ฐ์ ๋๋ฆผํต ์ ์ถ์ฐฝ์ DH{}๋ก ๊ฐ์ธ ๋ฃ์ผ๋ ์ ๋ต ์ฒ๋ฆฌ๋๊ณ VM ํฌ๋ ๋ง๋ ๊ทธ๋๋ก ์ ์ง๋๋ค(์ด ๋ฌธ์ ๋ ์๋ฒ ์์ด ํ์ผ๋ง ๋ฐ๋ ์ ํ์ด๋ผ ํฌ๋ ๋ง์ ์ ์ด์ ์ฐ์ง ์๋๋ค). ์ต์ข
ํ๋๊ทธ๋ DH{Did_y0u_brute_force?}.
๐ ๊ฒฐ๋ก
์์๋ฅผ ๊ณฑํ๋ ๋ณํ๋ ๊ทธ ์์๊ฐ ๋ชจ๋๋ฌ ํ์์ ๊ฐ์ญ์ด๋ฉด XOR์ด๋ ์นํํ์ ๋๊ฐ์ด ๋ซ๋ฆฐ๋ค.
์ด๋ฒ ๋ฌธ์ ๊ฐ ์ค์ ๋ก ํ ์ผ์ ์ธ ๊ฐ์ง๋ฟ์ด๋ค. (1) ๊ฒ์ฆ ํจ์๊ฐ (buf[i] * 0xfb) & 0xff == table[i] ํํ์ 21ํ ๋ฃจํ์์ ์ฝ๊ณ , (2) 0xfb๊ฐ mod 256์์ ์๋ก์๋ผ ์ญ์์ด ์กด์ฌํ๋ค๋ ๊ฑธ ํ์ธํ๊ณ , (3) pow(0xfb, -1, 256)์ผ๋ก ์ญ์์ ๊ตฌํด ํ
์ด๋ธ์ ๊ทธ๋๋ก ๊ณฑํ๋ค. 21๋ฒ์งธ ๋น๊ต๊ฐ ์ฌ์ค์ ๊ธธ์ด ์ฒดํฌ(NUL ์ข
๊ฒฐ์)๋ผ๋ ๊ฑธ ์์์ฑ๋ ๊ฒ ์ ๋๊ฐ ์ ์ผํ ์ฝ์ง์ด์๋ค.
- ๊ณฑ์
์ธ์ฝ๋ฉ์ ๋๋์
์ด ์๋๋ผ ์ญ์ ๊ณฑ์
์ผ๋ก ํ๋ฆฐ๋ค. ๋ชจ๋๋ฌ ์ฐ์ ์์ ๋๋์
์ ์ ์๋์ง ์์ง๋ง, ๋ฒ๊ณผ ์๋ก์์ธ ๊ณฑ์๋ ํญ์ ์ญ์์ ๊ฐ๋๋ค.
& 0xff๋ก ์๋ผ๋ด๋ ์ฐ์ฐ์ ๋ณด๋ฉด mod 256 ๊ณฑ์ ์์ ์์ฌํ๋ ๊ฒ ๋จผ์ ๋ค. - ์ง์ ์์๋ฅผ ๊ณฑํ๋ค๋ฉด ์ด ํธ๋ฆญ์ด ์ ํตํ์ ๊ฒ์ด๋ค. ์ง์๋ 256๊ณผ ๊ณต์ฝ์ 2๋ฅผ ๊ฐ์ง๋ฏ๋ก ์ญ์์ด ์๊ณ , ์ฌ๋ฌ ์ ๋ ฅ์ด ๊ฐ์ ์ถ๋ ฅ์ ๋ชฐ๋ฆฌ๋ ๋ค๋์ผ ํจ์๊ฐ ๋๋ค โ ๊ทธ๋ฌ๋ฉด ์ญ์ฐ์ด ์๋๋ผ ํ๋ณด ์งํฉ์ ์ขํ๋ ๋ฌธ์ ๋ก ๋ฐ๋๋ค. ์ด๋ฒ์ 0xfb๊ฐ ํ์์๋ ๊ฒ ๊ฒ์ฆ์ ์ ํํ ํ ๋ฒ์ ๋ค์ง์ ์ ์์๋ ์ด์ ๋ค.
- ๊ธธ์ด ๊ฒ์ฌ๋ฅผ ์ข ๊ฒฐ์ ๋น๊ต๋ก ์จ๊ฒจ๋ ์ ์ ๋ถ์ ์์์ ํฐ ์๋ฏธ๊ฐ ์๋ค. ํ ์ด๋ธ ๋ง์ง๋ง ๋ฐ์ดํธ๋ฅผ ๋ณด๋ ์๊ฐ ๋ฐ๋ก ๋๋ฌ๋๋ค.
์๋ฆฌ์ฆ๋ฅผ ๊ดํตํ๋ ๋ฐฉ๋ฒ์ ๋๊ฐ๋ค โ ๊ฒ์ฆ ํจ์๊ฐ ์ ๋ ฅ์ ๋ฌด์จ ์ฐ์ฐ์ ํ๋์ง ์ฝ๊ณ , ๊ทธ ์ฐ์ฐ์ ์ญํจ์๋ฅผ ์ฐพ์ ๊ฑฐ๊พธ๋ก ๋๋ฆฐ๋ค. ์ด๋ฒ์ ๊ทธ ์ญํจ์๊ฐ ๋ชจ๋๋ฌ ๊ณฑ์ ์ ์ญ์์ด์์ ๋ฟ์ด๋ค.
Comments
๋๊ธ
๋๊ธ์ ๋จ๊ธฐ๋ ค๋ฉด ๋ก๊ทธ์ธ์ด ํ์ํด์. (๋ค์ด๋ฒ ยท ๊ตฌ๊ธ ๊ณ์ )
๋๊ธ ๋ถ๋ฌ์ค๋ ์คโฆ