[๐ฅ ๋ธ๋ก ์ฆ 4] ์ํธํ๋ ์ด๋ฏธ์ง๋ฅผ ๋์ด๋ฆฌ๋ค โ DreamHack Recover ํ์ด โ ZINO2026-07-13ยท1๋ถ ์ฝ๊ธฐยท
chall ๋ฐ์ด๋๋ฆฌ๊ฐ flag.png๋ฅผ ๋ฐ์ดํธ๋ง๋ค ์ํธํํด encrypted ํ์ผ๋ก ์ ์ฅํ๋ค. ์ํธํ๋ 4๋ฐ์ดํธ ํค deadbeef๋ก XORํ ๋ค 0x13์ ๋ํ๋ ๋จ์ ๊ฐ์ญ ์ฐ์ฐ์ด๋ผ, ์์๋ฅผ ๋ฐ๋๋ก ๋๋๋ฆฌ๋ฉด ์๋ณธ์ด ๋ณต๊ตฌ๋๋ค. ๋ณต๊ตฌ๋ณธ์ ์ฒซ 8๋ฐ์ดํธ๊ฐ PNG ์๊ทธ๋์ฒ์ ์ผ์นํ๋ ๊ฑธ ํ์ธํ๊ณ , ๋์ด๋ฆฐ ์ด๋ฏธ์ง ์ ํ๋๊ทธ๋ฅผ ์ฝ์๋ค.
๋ฌธ์ : DreamHack โ Recover
๋ถ๋ฅ: Reversing
๋์ด๋: ๐ฅ ๋ธ๋ก ์ฆ 4
FLAG: DH{9a89d702b9}
๋ฌธ์ ์ค๋ช
์ ์งง๊ณ ๋ถ๋ช
ํ๋ค.
chall ๋ฐ์ด๋๋ฆฌ์ encrypted ํ์ผ์ด ์ฃผ์ด์ง๋๋ค. chall์ ํ๋๊ทธ๊ฐ ๋ด๊ธด flag.png ํ์ผ์ ์ํธํํด encrypted ํ์ผ๋ก ์ ์ฅํฉ๋๋ค. flag.png๋ฅผ ๋ณต๊ตฌํด ํ๋๊ทธ๋ฅผ ์ป์ผ์ธ์!
์ฆ ํ๋๊ทธ๋ ์ด๋ฏธ์ง(flag.png) ์์ ๊ทธ๋ ค์ ธ ์๊ณ , ์ฐ๋ฆฌ์๊ฒ ๊ทธ๊ฑธ ์ํธํํ encrypted๋ง ์๋ค. chall์ด ์ด๋ป๊ฒ ์ํธํํ๋์ง ์ฝ์ด์ ๊ทธ ๊ณผ์ ์ ๊ฑฐ๊พธ๋ก ๋๋ฆฌ๋ฉด ์๋ณธ ์ด๋ฏธ์ง๊ฐ ๋์จ๋ค.
Recover โ ๋ฐ์ดํธ ์ํธํ๋ฅผ ์ญ์ฐํด flag.png ๋ฅผ ๋์ด๋ฆฐ๋ค
๋ฌธ์ ๊ฐ์
| ํญ๋ชฉ | ๋ด์ฉ |
|---|
| ๋ฌธ์ ๋ช
| Recover |
| ๋์ด๋ | ๐ฅ ๋ธ๋ก ์ฆ 4 |
| ๋ถ๋ฅ | Reversing (x86-64 ELF) |
| ์ ๊ณต ํ์ผ | chall (PIE, stripped) + encrypted (908,999 ๋ฐ์ดํธ) |
| ๋ชฉํ | ์ํธํ๋ฅผ ์ญ์ฐํด flag.png ๋ณต๊ตฌ |
| ํต์ฌ ๊ธฐ๋ฒ | ๋ฐ์ดํธ๋ณ ๊ฐ์ญ ์ํธํ(XOR + ๋ง์
) ์ญ์ฐ์ฐ |
์ํธํ๊ฐ ํค ์๋ XOR + ๋ง์
์ด๋ผ, ๋ ์ฐ์ฐ ๋ชจ๋ ๋๋๋ฆด ์ ์์ด ๋ณตํธ๊ฐ ๊ณง๋ฐ๋ก ๊ฐ๋ฅํ๋ค.
๋ฐฐ๊ฒฝ โ ๋ฐ์ดํธ ์ํธํ์ PNG ์๊ทธ๋์ฒ
ํ์ผ์ ๋ฐ์ดํธ ๋จ์๋ก ๋ณํํ๋ ๋จ์ ์ํธํ๋ ๋๊ฐ XORยท๋ง์
ยท์นํ ๊ฐ์ ๊ฐ์ญ ์ฐ์ฐ์ ์กฐํฉ์ด๋ค.
- XOR์ ๊ฐ์ ํค๋ก ํ ๋ฒ ๋ XORํ๋ฉด ์๋ ๊ฐ์ผ๋ก ๋์์จ๋ค.
- ๋ง์
(
)์ ๋บ์
()์ผ๋ก ๋๋๋ฆฐ๋ค. 8๋นํธ ์์์ ๋์น๋ฉด() ๊ฐ์ ๋ชจ๋๋ฌ ๊ณต๊ฐ์์ ๋นผ๋ฉด ๋๋ค.
์ด ๊ธ์ด ๋์์ด ๋๋์?
+ k
- k
& 0xff
์ด๋ฐ ์ฐ์ฐ๋ค์ ์์๋๋ก ๊ฑธ์์ผ๋ฉด, ์ญ์์ผ๋ก ๊ฐ ์ญ์ฐ์ฐ์ ๊ฑธ์ด ์๋ณธ์ ๋ณต๊ตฌํ๋ค. ๋ณต๊ตฌ๊ฐ ์ ๋๋ก ๋๋์ง ํ์ธํ๋ ์ข์ ๋ฐฉ๋ฒ์ ํ์ผ ์๊ทธ๋์ฒ(magic bytes)๋ค. PNG๋ ํญ์ 89 50 4E 47 0D 0A 1A 0A๋ก ์์ํ๋ฏ๋ก, ๋ณต๊ตฌ๋ณธ์ ์ฒซ 8๋ฐ์ดํธ๊ฐ ์ด์ ๊ฐ์ผ๋ฉด ์ฑ๊ณต์ด๋ค.
๐ฌ ์ ์ฐฐ โ encrypted๋ PNG๊ฐ ์๋๋ค
encrypted๋ฅผ ๋ณด๋ฉด PNG ์๊ทธ๋์ฒ๊ฐ ์๋๋ผ ๋ค์์ธ ๋ฐ์ดํฐ๊ณ , chall์ ๋ฌธ์์ด์ flag.pngยทencrypted์ fopen/fread/fwrite๊ฐ ๋ณด์ธ๋ค.
file encrypted # data (PNG ์๋)
xxd encrypted | head -3
strings chall | grep -E "flag.png|encrypted|fopen|fread|fwrite"
encrypted๋ data(PNG ์๊ทธ๋์ฒ ์๋), chall ๋ฌธ์์ด์ flag.pngยทencryptedยทfopen/fread/fwrite
chall์ด flag.png๋ฅผ ์ฝ์ด(fread) ๋ญ๊ฐ ๋ณํํ ๋ค encrypted์ ์ด๋ค(fwrite)๋ ๊ทธ๋ฆผ์ด ๊ทธ๋ ค์ง๋ค. ๊ทธ "๋ณํ"์ด ๋ฌด์์ธ์ง ๋์ค์ด์
๋ธ๋ก ํ์ธํ๋ค.
๐งช ์ํธํ ๋ก์ง ๋ถ์
main์ ํต์ฌ์ ๋ฐ์ดํธ ํ๋๋ฅผ ์ฝ์ด ๋ณํํ๊ณ ์ฐ๋ ๋ฃจํ๋ค.
main ์ํธํ ๋ฃจํ โ i%4๋ก key ์ธ๋ฑ์ฑ, byte ^= key[i%4], byte += 0x13 ํ encrypted์ ๊ธฐ๋ก
ํ ๋ฐ์ดํธ๋ฅผ ์ฝ์ ๋๋ง๋ค ๋ ๊ฐ์ง๋ฅผ ํ๋ค.
byte ^= key[i % 4] โ 4๋ฐ์ดํธ ํค๋ฅผ ๋ฐ๋ณตํด XOR (i % 4๋ก ํค ์ธ๋ฑ์ค ์ํ).
byte += 0x13 โ ์ฌ๊ธฐ์ 0x13์ ๋ํ๋ค(8๋นํธ๋ก ์๋ฆผ).
๊ทธ ๊ฒฐ๊ณผ๋ฅผ encrypted์ 1๋ฐ์ดํธ์ฉ ์ด๋ค. ํค๋ .rodata์ ๋ฐํ ์๋ค.
.rodata 0x2004์ ์ํธํ ํค de ad be ef, ์ด์ด์ flag.pngยทencrypted ๋ฌธ์์ด
0x2004์ de ad be ef โ ํค๋ 0xdeadbeef 4๋ฐ์ดํธ๋ค. ์ ๋ฆฌํ๋ฉด ์ํธํ๋ ์ด๋ ๋ค.
enc[i] = ( ( flag[i] ^ key[i % 4] ) + 0x13 ) & 0xff (key = de ad be ef)
๐ฃ ํต์ฌ โ ์์๋ฅผ ๋ฐ๋๋ก ๋๋๋ฆฐ๋ค
XOR๋ ๋ง์
๋ ๊ฐ์ญ์ด๋, ์ํธํ์ ์ญ์(๋ง์
๋๋๋ฆฌ๊ธฐ โ XOR ๋๋๋ฆฌ๊ธฐ)์ผ๋ก ํ๋ฉด ์๋ณธ ๋ฐ์ดํธ๊ฐ ๋์จ๋ค.
flag[i] = ( ( enc[i] - 0x13 ) & 0xff ) ^ key[i % 4]
- 0x13์ผ๋ก ๋ง์
์ ๋๋๋ฆฌ๊ณ (8๋นํธ ์ธ๋ํ๋ก๋ & 0xff๋ก ์ฒ๋ฆฌ), ๊ฐ์ ํค๋ก ๋ค์ XORํ๋ฉด ๋์ด๋ค.
๐ Full Exploit
encrypted ์ ์ฒด์ ์ญ์ฐ์ฐ์ ๊ฑธ์ด flag.png๋ฅผ ๋ณต๊ตฌํ๊ณ , PNG ์๊ทธ๋์ฒ๋ก ๊ฒ์ฆํ๋ค.
key = bytes.fromhex("deadbeef")
enc = open("encrypted", "rb").read()
flag = bytes(((b - 0x13) & 0xff) ^ key[i % 4] for i, b in enumerate(enc))
open("recovered.png", "wb").write(flag)
print("PNG ์๊ทธ๋์ฒ:", flag[:8].hex(),
"->", "OK" if flag[:8] == bytes.fromhex("89504e470d0a1a0a") else "FAIL")
solve.py ์คํ โ ๋ณต๊ตฌ๋ณธ ์ฒซ 8๋ฐ์ดํธ๊ฐ PNG ์๊ทธ๋์ฒ 89504e470d0a1a0a์ ์ผ์น, 908999๋ฐ์ดํธ ๋ณต๊ตฌ
์ฒซ 8๋ฐ์ดํธ๊ฐ 89504e470d0a1a0a โ ์ ์ PNG๋ก ๋ณต๊ตฌ๋๋ค. ์ด์ด ๋ณด๋ฉด ํ๋๊ทธ๊ฐ ๊ทธ๋ ค์ง ์บ๋ฒ์ค ๊ทธ๋ฆผ์ด๋ค.
๋ณต๊ตฌ๋ flag.png โ ์ด์ ค ์ ์บ๋ฒ์ค์ ํ๋ ๊ธ์จ๋ก ํ๋๊ทธ๊ฐ ์ ํ ์์
์ด๋ฏธ์ง ์ ์บ๋ฒ์ค์ ํ๋๊ทธ DH{9a89d702b9}๊ฐ ๋๋ ทํ๊ฒ ์ ํ ์๋ค.
๐ ๊ฒฐ๋ก
์ํธํ ๋ก์ง์ ์ฝ์ ์ ์์ผ๋ฉด ๊ทธ๋๋ก ๋๋๋ฆฐ๋ค.
์ด ๋ฌธ์ ์ ์ํธํ๋ ํค ์๋ XOR๊ณผ ๋ง์
๋ฟ์ด๋ผ ๋ ์ฐ์ฐ ๋ชจ๋ ์ญํจ์๊ฐ ์๋ค. ๋์นญํค ์ํธ๋ ๋จ์ ์ธ์ฝ๋ฉ์ด๋ , ๋ณํ ๊ณผ์ ์ ์ ์ ์ผ๋ก ์ฝ์ด๋ผ ์ ์์ผ๋ฉด ์ญ์์ผ๋ก ์ญ์ฐ์ฐ์ ์ ์ฉํด ์๋ณธ์ ๋ณต๊ตฌํ ์ ์๋ค. ๋ฆฌ๋ฒ์ฑ์์ "ํ์ผ์ ์ํธํํด ์ ์ฅํ๋" ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋ง๋๋ฉด, ๊ทธ ๋ณํ ๋ฃจํ๋ง ์ ํํ ํ์
ํ๋ฉด ๋ณตํธ๊ธฐ๋ ๋ช ์ค์ด๋ฉด ๋ง๋ค์ด์ง๋ค.
๋ณต๊ตฌ๋ ์๊ทธ๋์ฒ๋ก ๊ฒ์ฆํ๋ค.
๋ฐ์ดํธ๋ฅผ ๋๋๋ ธ์ ๋ ๊ทธ๊ฒ ์ ๋ง ์๋ณธ์ธ์ง ํ์ธํ๋ ๊ฐ์ฅ ํ์คํ ๋ฐฉ๋ฒ์ ํ์ผ ํฌ๋งท์ ๋งค์ง ๋ฐ์ดํธ๋ค. PNG์ 89 50 4E 47 โฆ์ฒ๋ผ ์๋ ค์ง ์๊ทธ๋์ฒ๊ฐ ๋ง์ผ๋ฉด ํคยท์ฐ์ฐยท์์๊ฐ ์ ๋ถ ๋ง์๋ค๋ ๋ป์ด๋ค. ์๊ทธ๋์ฒ๊ฐ ์ด๊ธ๋๋ฉด ํค๋ ์ฐ์ฐ ์์๋ฅผ ์๋ชป ์ก์ ๊ฒ์ด๋, ๋ณต๊ตฌ ํ์ดํ๋ผ์ธ์ ๋๋ฒ๊น
ํ๋ ์ข์ ์ด์ ํ๊ฐ ๋๋ค.
Comments
๋๊ธ
๋๊ธ์ ๋จ๊ธฐ๋ ค๋ฉด ๋ก๊ทธ์ธ์ด ํ์ํด์. (๋ค์ด๋ฒ ยท ๊ตฌ๊ธ ๊ณ์ )
๋๊ธ ๋ถ๋ฌ์ค๋ ์คโฆ