๋ฌธ์ : DreamHack โ reverse_decoding ๋ถ๋ฅ: Misc ๋์ด๋: ๐ฅ Bronze 2 FLAG:
bisc2024{h1dd3n_1n_p14in_JS}
์ฒ ์๊ฐ ์ด๋ฉ์ผ๋ก ์ค์ํ ์ ๋ณด๋ฅผ ๋ฐ์๋๋ฐ, ํ์ผ์ด ์์๊ณผ ๋ฌ๋ฆฌ JPG ์ด๋ฏธ์ง์๊ณ ๊ทธ๋ง์ ๋ ์์๋ผ ์ด๋ฆฌ์ง ์๋๋ค. ๋ฌธ์ ์ด๋ฆ ๊ทธ๋๋ก "๊ฑฐ๊พธ๋ก ์ธ์ฝ๋ฉ๋" ํ์ผ์ด๋ค. ๋ค์ง๋ ์๊ฐ ์ ํจํ ์ด๋ฏธ์ง์ ์จ์ ์ฝ๋๊ฐ ๋์์ ํ์ด๋์จ๋ค.

๋ฌธ์ ๊ฐ์
| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| ๋ฌธ์ ๋ช | reverse_decoding |
| ๋์ด๋ | ๐ฅ Bronze 2 |
| ๋ถ๋ฅ | Misc |
| ์ ๊ณต ํ์ผ | Reverse_Decoding.jpg (์์๋ JPG) |
| ํต์ฌ ๊ธฐ๋ฒ | ์ญ์ base64 + JSFuck ๋์ฝ๋ (eval ๊ฐ๋ก์ฑ๊ธฐ) |
ํ์ผ ์ด๋ฆ Reverse_Decoding ์์ฒด๊ฐ ํํธ๋ค. "๊ฑฐ๊พธ๋ก ๋ ๊ฒ์ ๋์ฝ๋ํ๋ผ"๋ ๋ป์ด๋ค.
๐ฌ ์ ์ฐฐ โ ํ์ผ์ด ๋ค์งํ ์๋ค
file ๋ช
๋ น์ ์ด JPG๋ฅผ data(์ ์ฒด ๋ถ๋ช
)๋ก ๋ณธ๋ค. ํค๋๋ฅผ ๋ณด๋ฉด ์์ ๋ ๋ฐ์ดํธ๊ฐ ๊น๋ ค ์๊ณ ๊ทธ ๋ค๋ก ==QK... ๊ฐ์ base64์ค๋ฌ์ด ๋ฌธ์์ด์ด ์ด์ด์ง๋ค.
xxd -l 48 Reverse_Decoding.jpg
์ฌ๊ธฐ์ ๊ฒฐ์ ์ ์ธ ๋จ์๋ ๋ฌธ์์ด์ด ==๋ก ์์ํ๋ค๋ ์ ์ด๋ค. base64์์ =๋ padding์ด๋ผ ์ ์์ ์ผ๋ก๋ ๋ฌธ์์ด ๋์๋ง ์จ๋ค. ==๊ฐ ๋งจ ์์ ์๋ค๋ ๊ฑด ์ด ๋ฌธ์์ด์ด ํต์งธ๋ก ๋ค์งํ ์๋ค๋ ๋ป์ด๋ค.
์ค์ ๋ก ํ์ผ ์ ์ฒด๋ฅผ ๋ค์ง์ด ๋ณด๋ฉด ์๋ถ๋ถ์ด FF D8 FF E0 โฆ JFIF, ์ ํํ JPEG ์๊ทธ๋์ฒ๋ก ์์ํ๋ค. ์ฆ ์ด ํ์ผ์ ์ ํจํ JPEG๋ฅผ ๋ฐ์ดํธ ๋จ์๋ก ๋ค์ง์ด ์ ์ฅํ ๊ฒ์ด๋ค. ๋ค์ง์ด ์ ์ฅํ๋ฉด ์๋ ๋(๊ผฌ๋ฆฌ)์ ๋ถ์ด ์๋ base64 ๋ฐ์ดํฐ๊ฐ ํ์ผ ๋จธ๋ฆฌ๋ก ์ฌ๋ผ์จ๋ค.
๐งฉ ๋ฐฐ๊ฒฝ โ base64 ์ JSFuck
base64๋ 3๋ฐ์ดํธ(24๋นํธ)๋ฅผ 6๋นํธ์ฉ ๋ท์ผ๋ก ์ชผ๊ฐ 64๊ธ์ ์ํ๋ฒณ(A~Z a~z 0~9 + /)์ผ๋ก ํํํ๋ ์ธ์ฝ๋ฉ์ด๋ค. ๋ฐ์ด๋๋ฆฌ๋ฅผ ํ
์คํธ ์ฑ๋๋ก ์์ ํ๊ฒ ๋๋ฅด๋ ์ฉ๋์ด๋ฉฐ, ๋จ๋ ์๋ฆฌ๋ =๋ก ์ฑ์ด๋ค.

์ถ์ฒ: Wikimedia Commons (File:Base64bin2txt.png), CC0 / public domain
๋์ฝ๋ํด์ ๋์ค๋ ๊ฑด JSFuck์ด๋ค. JSFuck์ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ค์ง [ ] ( ) ! + ์ฌ์ฏ ๊ธ์๋ง์ผ๋ก ํํํ๋ ๋๋
ํ ๊ธฐ๋ฒ์ด๋ค. ![]๋ false, +[]๋ 0, []+[]๋ ๋น ๋ฌธ์์ด์ฒ๋ผ, ์์๊ฐ๊ณผ ํ๋ณํ์ ์กฐํฉํด ์ซ์ยท๋ฌธ์ยทํจ์๋ฅผ ๋ง๋ค์ด ๋ธ๋ค. ์ต์ข
์ ์ผ๋ก๋ Function("์ฝ๋")() ํํ๋ก ์์ ์ฝ๋๋ฅผ ์คํํ๋ค. ๋ณต๊ตฌ๋ ์ด๋ฏธ์ง์๋ JSFUCK, DECODE THE SECRET์ด๋ผ๋ ํํธ๊ฐ ํผ์งํ๊ฒ ๋ฐํ ์๋ค.

๐ฃ ํต์ฌ โ ์คํํ์ง ๋ง๊ณ eval ์ ๊ฐ๋ก์ฑ๋ผ
JSFuck์ ๊ทธ๋ฅ ์คํํ๋ฉด ๋ง์ง๋ง ()์์ ์ฝ๋๊ฐ ๋์ ๋ฒ๋ฆฐ๋ค. CTF ํ์ด๋ก๋๋ ๋๊ฐ ๋ฌดํดํ์ง๋ง, ์ฌ๊ธฐ์๋ ์คํ ๊ฒฐ๊ณผ๊ฐ ํ๋๊ทธ ๋ฌธ์์ด๋ก ํ๋ฅด๋ค๊ฐ { ๋๋ฌธ์ ๋ฌธ๋ฒ ์ค๋ฅ๋ก ํ๋ค. ๊ทธ๋์ ์คํํ๋ ๋์ , JSFuck์ด ์ต์ข
์ ์ผ๋ก ํธ์ถํ๋ eval์ ๊ฐ๋ก์ฑ ๊ทธ ์ธ์(=๋ง๋ค์ด์ง ์ฝ๋/๋ฌธ์์ด)๋ง ๊บผ๋ธ๋ค.
// extract.js โ eval ์ ํ
์ผ๋ก ๋ฐ๊ฟ ์คํ ์์ด ์ธ์๋ง ํ์
const fs = require("fs");
let code = fs.readFileSync("payload.jsfuck.js", "utf8").trim();
const realEval = globalThis.eval;
let flag = null;
globalThis.eval = function (a) { flag = a; return ""; }; // ์คํ ๋์ ์ธ์ ์ ์ฅ
try { realEval.call(globalThis, code); } catch (e) {}
console.log("FLAG:", flag);JSFuck์ Function("return eval")()๋ก ์ง์ง eval ์ฐธ์กฐ๋ฅผ ์ป์ ๋ค eval(๋ง๋ _๋ฌธ์์ด)์ ํธ์ถํ๋ค. ๊ทธ eval์ ์ค์ฝํ์์ ์ ์ญ eval์ ์ฐพ์ผ๋ฏ๋ก, ์ ์ญ eval์ ์ฐ๋ฆฌ ํจ์๋ก ๋ฐ๊ฟ ๋๋ฉด ์ธ์๊ฐ ๊ทธ๋๋ก ์์ ๋ค์ด์จ๋ค. ๊ทธ ์ธ์๊ฐ ๊ณง ํ๋๊ทธ๋ค. ์ธ์ ๋ฌธ์์ด์ \173({), \175(}), \137(_) ๊ฐ์ 8์ง ์ด์ค์ผ์ดํ๋ก ์กฐ๋ฆฝ๋ผ ์์๋ค.
๐ฏ ํ์ด โ ๋ค์ง๊ธฐ โ base64 โ JSFuck โ ํ๋๊ทธ
# solve.py
import base64, subprocess
raw = open("Reverse_Decoding.jpg", "rb").read()
s = raw.lstrip(b"\x00") # ์์ชฝ ๋ ์ ๊ฑฐ
b64 = set(b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=")
i = 0
while i < len(s) and s[i] in b64: i += 1 # ๋จธ๋ฆฌ์ base64 ๊ตฌ๊ฐ๋ง ์๋ผ
jsfuck = base64.b64decode(s[:i][::-1]) # ๋ค์ง์ด ๋์ฝ๋ โ JSFuck
open("payload.jsfuck.js", "wb").write(jsfuck)
print("[1] reversed base64 ->", len(jsfuck), "bytes of JSFuck:", jsfuck[:24].decode(), "...")
out = subprocess.run(["node", "extract.js"], capture_output=True, text=True).stdout.strip()
print("[2] node eval-hook ->", out)
์ญ์ base64๋ฅผ ๋ค์ง์ด ๋์ฝ๋ํ๋ 8260๋ฐ์ดํธ์ง๋ฆฌ JSFuck์ด ๋์ค๊ณ , eval์ ๊ฐ๋ก์ฑ๋ ํ๋๊ทธ๊ฐ ๊ทธ๋๋ก ๋จ์ด์ง๋ค. ํ๋๊ทธ ๋ด์ฉ h1dd3n_1n_p14in_JS("hidden in plain JS")๊ฐ ๋ฌธ์ ์ ์ ์ฒด๋ฅผ ๊ทธ๋๋ก ๋งํด ์ค๋ค.
FLAG: bisc2024{h1dd3n_1n_p14in_JS}
๐ ๊ฒฐ๋ก
"์ ์ด๋ฆฌ๋ ํ์ผ"์ ํ์์ด ์๋๋ผ ๋ฐฐ์น๊ฐ ๋ค์งํ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค.
file์ด ์ ์ฒด๋ฅผ ๋ชป ๋งํ๊ณ ์๊ทธ๋์ฒ๊ฐ ์ ๋ณด์ผ ๋, ๋ค์ง๊ธฐยทXORยท๋นํธ ๋ฐ์ ๊ฐ์ ๋จ์ ๋ณํ์ ๋จผ์ ์์ฌํ๋ค. ์ฌ๊ธฐ์๋ base64 padding =์ด ๋ฌธ์์ด ์์ ์๋ค๋ ์ฌ์ค ํ๋๊ฐ "๋ค์งํ ์๋ค"๋ ๊ฑธ ํ์ ํด ์คฌ๋ค. ์ธ์ฝ๋ฉ์ ๊ณ ์ ๋ ํน์ง(์๊ทธ๋์ฒยทpadding ์์น)์ ๋ฐฉํฅ์ ์๋ ค์ฃผ๋ ๋์นจ๋ฐ์ด๋ค.
๋๋ ํ ์ฝ๋๋ ์คํํ์ง ๋ง๊ณ ๊ฐ๋ก์ฑ๋ผ.
JSFuckยทpacker ๋ฅ๋ ๊ฒฐ๊ตญ eval์ด๋ Function์ผ๋ก ์๋ณธ ์ฝ๋๋ฅผ ์คํํ๋ค. ๊ทธ ๊ด๋ฌธ ํ๋๋ง ํํนํ๋ฉด ์คํํ์ง ์๊ณ ๋ ์๋ณธ์ ์์ ๋ฃ์ ์ ์๋ค. ์ ๋ขฐํ ์ ์๋ ์ฝ๋๋ฅผ ๋ค๋ฃฐ ๋์ ๊ธฐ๋ณธ๊ธฐ์ด์, ์ด ๋ฌธ์ ์์๋ ๊ฐ์ฅ ๊น๋ํ ์ง๋ฆ๊ธธ์ด์๋ค.
Comments
๋๊ธ
๋๊ธ์ ๋จ๊ธฐ๋ ค๋ฉด ๋ก๊ทธ์ธ์ด ํ์ํด์. (๋ค์ด๋ฒ ยท ๊ตฌ๊ธ ๊ณ์ )
๋๊ธ ๋ถ๋ฌ์ค๋ ์คโฆ