๋ฌธ์ : DreamHack โ 403-forbbiden ๋ถ๋ฅ: Web ๋์ด๋: ๐ฅ Bronze 4 FLAG:
DH{afjqofuida34@1!21%!1204m1n13aax091!kJ@$}
๋ฌธ์ ์ด๋ฆ๋ถํฐ "403 forbidden error"๋ค. ์ด ์ ๋๋ก ๋ ธ๊ณจ์ ์ธ ์ ๋ชฉ์ด๋ฉด ๋ณดํต IP ์คํธํ ํค๋๋ ๊ฒฝ๋ก ์ ๊ทํ ํธ๋ฆญ์ผ๋ก ์ ๊ทผ ์ ์ด๋ฅผ ์ฐํํ๋ ๋ฌธ์ ๋ฅผ ๊ธฐ๋ํ๊ฒ ๋๋ค. ๊ทธ๋ฐ๋ฐ ์ด๋ฒ์ ๊ทธ ๊ธฐ๋ ์์ฒด๊ฐ ํจ์ ์ด์๋ค โ ํ๋ฉด์ ๋ณด์ด๋ "๋ณดํธ๋ ํ์ด์ง"๋ ์ ์ด์ ์๋ฒ์ ์กด์ฌํ์ง๋ ์๋ ์ํ์ด์๊ณ , ์ง์ง ์ทจ์ฝ์ ์ ์ ํ ๋ค๋ฅธ ์๋ฆฌ์ ์กฐ์ฉํ ๋์ฌ ์์๋ค.
๋ฌธ์ ๊ฐ์
VM์ ๋์ฐ๋ฉด ์๋ฐ์คํฌ๋ฆฝํธ๋ก ๊ทธ๋ฆฐ ๊ฐ์ง ๋ธ๋ผ์ฐ์ ์ฐฝ ํ๋๊ฐ ๋ฌ๋ค. ์ฃผ์์ฐฝ์ฒ๋ผ ์๊ธด ์์์ securevault.dreamhack.games/secret์ด๋ผ๋ ๊ทธ๋ด๋ฏํ URL์ด ์ ํ ์๊ณ , ๊ทธ ์์ ํผ์ง๋งํ๊ฒ "403 Forbidden"์ด ํ์๋๋ค.
์ฌ๊ธฐ์ ์ฒ์ ๋์ฌ๊ฒจ๋ด์ผ ํ ๊ฒ ์๋ค โ ์ง์ง ๋ธ๋ผ์ฐ์ ์ฃผ์์ฐฝ(์์ชฝ, Chrome ์์ฒด์ ๊ฒ)๊ณผ ํ์ด์ง ์์ HTML/CSS๋ก ๊ทธ๋ ค์ง ๊ฐ์ง ์ฃผ์์ฐฝ(ํฐ ๋ฐฐ๊ฒฝ์ "๋ธ๋ผ์ฐ์ ํฌ๋กฌ" ๋ชฉ์
)์ ์๋ก ๋ค๋ฅธ ๊ฒ์ด๋ค. securevault.dreamhack.games/secret์ ์ค์ ๋ก ์์ฒญ์ด ๊ฐ๋ ์ฃผ์๊ฐ ์๋๋ผ, ๊ทธ๋ฅ ํ๋ฉด์ ์ ํ ํ
์คํธ์ผ ๋ฟ์ด๋ค.
โถ๐ณ๏ธ ์ฝ์ง โ ์ ๋ชฉ์ด ์ํจ ๋๋ก 403 ์ฐํ ๊ธฐ๋ฒ์ ์์๋๋ก ์๋ํด๋ดค๋ค
์ ๋ชฉ์ด "403 forbidden error"์ด๋ ์์ฐ์ค๋ฝ๊ฒ ํํ 403 ์ฐํ ๊ธฐ๋ฒ๋ถํฐ ํ๋์ฉ ์๋ํ๋ค. /secret์ด ํ๋ฉด์ ์ ํ "๋ณดํธ๋ ๊ฒฝ๋ก"์ฒ๋ผ ๋ณด์์ผ๋, ๊ทธ ๊ฒฝ๋ก๋ฅผ ์ง์ ๋๋๋ฆฌ๋ ๊ฒ๋ถํฐ ์์ํ๋ค.
$ curl -s -o /dev/null -w '%{http_code}' http://host3.dreamhack.games:PORT/secret
404403์ด ์๋๋ผ 404๋ค. ์ด๋ฏธ ์ฌ๊ธฐ์ ์ด์ํ ์ ํธ์์ง๋ง, ์ผ๋จ ํํ ํค๋ ์คํธํ ๊ธฐ๋ฒ๋ค์ ๊ณ์ ์๋ํ๋ค โ ๋ฆฌ๋ฒ์ค ํ๋ก์๊ฐ ๋ด๋ถ IP๋ฅผ ์ ๋ขฐํ๋ ๊ฒฝ์ฐ๋ฅผ ๋
ธ๋ฆฌ๋ X-Forwarded-For, ๊ทธ๋ฆฌ๊ณ ์ผ๋ถ WAF/ํ๋ก์ ๊ตฌ์ฑ์์ ์ค์ ์์ฒญ ๊ฒฝ๋ก ๋์ ์ฐธ์กฐ๋๋ X-Original-URL ํค๋๊น์ง.

์ ๋ถ 404. ์ด๋ค ์กฐํฉ์ ์๋ํด๋ ๊ฒฐ๊ณผ๊ฐ ๋ฐ๋์ง ์์๋ค. ์ด ์์ ์์ ๊ฒฐ๋ก ์ ๋ค์ง์๋ค โ /secret์ ์ฐํํด์ผ ํ "๋ณดํธ๋ ์๋ฃ"๊ฐ ์๋๋ผ, ์ ์ด์ ๋ฐฑ์๋์ ์กด์ฌํ์ง ์๋ ๊ฒฝ๋ก์๋ค. ํ๋ฉด์ ๊ทธ๋ ค์ง ๊ฐ์ง ์ฃผ์์ฐฝ์ ํ
์คํธ์ผ ๋ฟ, ์ค์ ๋ผ์ฐํ
๊ณผ๋ ๋ฌด๊ดํ ์ํ์ด์๋ ๊ฒ์ด๋ค. ๋ฌธ์ ์ ๋ชฉ์ด ๋ง๋ ์ ์
๊ฒฌ("403์ด๋๊น ํค๋ ์ฐํ๊ฒ ์ง")์ด ์ ํํ ์ฌ๊ธฐ์ ๋ฐ๋ชฉ์ ์ก์๋ค โ ์ง์ง ์ทจ์ฝ์ ์ /secret์ด ์๋๋ผ ์ ํ ๋ค๋ฅธ ์๋ํฌ์ธํธ์ ์์๋ค.
๐ฃ ํต์ฌ โ ํ๋ฉด์ ๋ ผ๋ฆฌ์ ์๋ฒ์ ๊ฒ์ฆ์ ๋ณ๊ฐ๋ค
/flag๋ผ๋ ๊ฒฝ๋ก๊ฐ ์๋ค๋ ๊ฑด ํ์ด์ง์ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ๋ณด๋ฉด ๋ฐ๋ก ์ ์ ์๋ค. view-source:๋ก ํ์ด์ง ์์ค๋ฅผ ์ด์ด๋ดค๋ค.
์คํฌ๋กค์ ๋ด๋ ค <script> ํ๊ทธ๋ฅผ ํ์ธํ๋ค.
๋ก์ง์ ์ ๋ฆฌํ๋ฉด ์ด๋ ๋ค.
const statusEl = document.getElementById("statusCode");
new MutationObserver(() => {
if (statusEl.textContent.trim() === "200") {
fetch("/flag", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ status: "200" })
})
.then(r => r.json())
.then(data => {
if (data.flag) { /* ์ฑ๊ณต ํ๋ฉด ํ์ */ }
});
}
}).observe(statusEl, { childList: true, subtree: true, characterData: true });#statusCode(ํ๋ฉด์ ํผ์ง๋งํ๊ฒ ๋ณด์ด๋ "403" ํ
์คํธ)์ ๋ด์ฉ์ด "200"์ผ๋ก ๋ฐ๋๋ ์๊ฐ์ MutationObserver๊ฐ ๊ฐ์งํด์, ๊ทธ๋ /flag์ POST ์์ฒญ์ ๋ณด๋ด๊ณ ์๋ต์ผ๋ก ๋ฐ์ flag ๊ฐ์ ํ๋ฉด์ ํ์ํ๋ค. ๊ทธ๋ด๋ฏํ "ํด๋ผ์ด์ธํธ๊ฐ 200์ ๋ง๋ค์ด๋ด๋ฉด ์๋ฒ๊ฐ ์ธ์ ํด์ค๋ค"๋ ํ๋ฆ์ฒ๋ผ ๋ณด์ด์ง๋ง, ์ ์ ์ ํ
์คํธ๋ฅผ ์ค์ ๋ก "200"์ผ๋ก ๋ฐ๊พธ๋ ์ฝ๋๋ ํ์ด์ง ์ด๋์๋ ์๋ค. ์ฆ ์ด MutationObserver๋ ํ ๋ฒ๋ ์๋์ผ๋ก ๋ฐ๋ํ ์ผ์ด ์๋, ์์ํ๊ฒ ์ฐ์ถ์ฉ์ผ๋ก ์ฌ์ด๋ ์ฅ์์ด๋ค.
์ฌ๊ธฐ์ ํต์ฌ์ ์ง์ด์ผ ํ๋ค. ์ด ์คํฌ๋ฆฝํธ๊ฐ ํ๋ ์ผ์ ๋ณธ์ง์ ๊ฒฐ๊ตญ **"์ด๋ค ์กฐ๊ฑด์ด ๊ฐ์ถฐ์ง๋ฉด /flag์ {"status": "200"}์ด๋ผ๋ JSON์ ๋ด์ POST๋ฅผ ๋ณด๋ธ๋ค"**๋ ๊ฒ๋ฟ์ด๋ค. ๋ธ๋ผ์ฐ์ ๊ฐ ๊ทธ ์กฐ๊ฑด์ ์ค์ค๋ก ํ๋จํด์ ์์ฒญ์ ๋ณด๋ด๋ , ์ฐ๋ฆฌ๊ฐ ๊ทธ๋ฅ curl๋ก ๋๊ฐ์ ์์ฒญ์ ์ง์ ๋ณด๋ด๋ , ์๋ฒ ์
์ฅ์์๋ ์์ ํ ๋์ผํ HTTP ์์ฒญ์ด๋ค. DOM ์ํ๋ ์ธ์
, ์ด๋ค ํ์ด์ง์์ ์๋์ง(Referer) ๊ฐ์ "์์ฒญ์ด ๋์จ ๋งฅ๋ฝ"์ ์๋ฒ๊ฐ ์ ํ ๊ฒ์ฆํ์ง ์๋๋ค๋ฉด, ๊ทธ ์์ฒญ์ ๋๊ตฌ๋ ๊ทธ๋๋ก ์ฌํํ ์ ์๋ค.
๋จผ์ GET์ผ๋ก /flag๋ฅผ ์ง์ ์ด์ด๋ดค๋ค โ ์์๋๋ก POST ์ ์ฉ ์๋ํฌ์ธํธ์๋ค.
๐ฏ ์์ฒด ์๊ฒฐ solve
์คํฌ๋ฆฝํธ๊ฐ ๋ณด๋ด๋ ๊ฒ๊ณผ ์ ํํ ๊ฐ์ ์์ฒญ์ curl๋ก ๊ทธ๋๋ก ์ฌํํ๋ค.
$ curl -X POST http://host3.dreamhack.games:PORT/flag \
-H 'Content-Type: application/json' \
-d '{"status":"200"}'
DOM์ ์ค์ ๋ก ์กฐ์ํ ํ์๋, ๋ธ๋ผ์ฐ์ ์ MutationObserver๊ฐ ๋ฐ๋ํ๊ธธ ๊ธฐ๋ค๋ฆด ํ์๋ ์์๋ค โ ์๋ฒ๋ ์ด ์์ฒญ์ด ์ง์ง ๋ธ๋ผ์ฐ์ ์์ ์๋์ง, ํ๋ฉด์ "403"์ด ์ ๋ง "200"์ผ๋ก ๋ฐ๋ ๋ค์ ์๋์ง ๊ทธ ์ด๋ค ๊ฒ๋ ๊ฒ์ฆํ์ง ์์๋ค. ๊ทธ๋ฅ ์ด JSON ๋ฐ๋ ํ๋๋ง ๋ณด๊ณ flag๋ฅผ ๋ด์คฌ๋ค.
๊ฐ์ ์์ฒญ์ ๋ธ๋ผ์ฐ์ ์ฝ์์์ ์ง์ ์คํํด๋ ๋ฌผ๋ก ๋์ผํ๊ฒ ๋์ํ๋ค โ ๊ฐ๋ฐ์ ๋๊ตฌ ์์ด๋, ๊ทธ๋ฅ #statusCode์ ํ
์คํธ๋ฅผ ๊ฐ์ ๋ก ๋ฐ๊ฟ์ ์๋ ์๋๋ MutationObserver ํ๋ฆ์ ์ค์ ๋ก ํธ๋ฆฌ๊ฑฐํด๋ดค๋ค.
MutationObserver๊ฐ ์ ์์ ์ผ๋ก ๋ฐ๋ํ๋ฉด์ ์ง์ง /flag ์๋ต์ ๋ฐ์์ "Access Granted!" ํ๋ฉด๊ณผ ํจ๊ป flag๋ฅผ ํ์ํ๋ค โ curl๋ก ์ง์ ๋ณด๋ธ ๊ฒ๊ณผ ์๋ฒ ์๋ต์ ์์ ํ ๋์ผํ๋ค.
DH{afjqofuida34@1!21%!1204m1n13aax091!kJ@$}flag์ ํน์๋ฌธ์(!, @, %, $)๊ฐ ๋ง์ ์ ๋ฌ ๊ณผ์ ์์ ๊นจ์ง ์ ์์ผ๋, ์๋ฒ์์ flag๋ฅผ ๋ค์ ์กฐํํด ์ ํํ ๊ฐ์ ๋ฌธ์์ด์ธ์ง ํ์ธํ ๋ค ์ ์ถํ๋ค. "์ ๋ต! ํด๊ฒฐ ์ฒ๋ฆฌ๋จ".
๐ ๊ฒฐ๋ก
์ด ๋ฌธ์ ๊ฐ ์ง์ด์ค ์ง์ ์ ๋ ๊ฐ์ง์๋ค.
- ๋ฌธ์ (๋๋ ํ๋ฉด) ์ ๋ชฉ์ด ๋ง๋๋ ์ ์
๊ฒฌ์ ์์ฌ ์์ด ๋ฐ์๋ค์ด๋ฉด ์ ๋๋ค. "403 forbidden"์ด๋ผ๋ ์ ๋ชฉ๊ณผ ๊ทธ๋ด๋ฏํ ๋ชฉ์
ํ๋ฉด์ ์์ฐ์ค๋ฝ๊ฒ "ํค๋ ์ฐํ"๋ผ๋ ์ต์ํ ์นดํ
๊ณ ๋ฆฌ๋ก ์ฌ๊ณ ๋ฅผ ๋ชฐ์๊ฐ๋ค. ํ์ง๋ง ์ค์ ๋ก ์กด์ฌํ์ง ์๋ ๊ฒฝ๋ก(
/secret)๋ฅผ ๋์์ผ๋ก ์๋ฌด๋ฆฌ ์ ๊ตํ ์ฐํ ๊ธฐ๋ฒ์ ์๋ํด๋ ๊ฒฐ๊ณผ๋ ๋ฐ๋์ง ์๋๋ค โ ๋ช ๋ฒ์ ์์ฒญ์ผ๋ก "์ฐํํ ๋์์ด ์ง์ง๋ก ์กด์ฌํ๋๊ฐ" ์์ฒด๋ฅผ ๋จผ์ ํ์ธํ๋ ์ต๊ด์ด, ์๋ฑํ ๋ฐฉํฅ์ผ๋ก ์๊ฐ์ ์ฐ๋ ๊ฑธ ๋ง์์ค๋ค. - ํด๋ผ์ด์ธํธ๊ฐ "์ด ์กฐ๊ฑด์ด ์ถฉ์กฑ๋๋ฉด ์ด ์์ฒญ์ ๋ณด๋ธ๋ค"๋ ๋ก์ง์ ๊ฐ๊ณ ์๋ค๋ฉด, ๊ทธ ์กฐ๊ฑด ์์ฒด๊ฐ ์๋๋ผ ์ต์ข
์ ์ผ๋ก ๋๊ฐ๋ ์์ฒญ์ด ์ง์ง ๊ณต๊ฒฉ ํ๋ฉด์ด๋ค. ์ด ๋ฌธ์ ์
MutationObserver๋ "๋ธ๋ผ์ฐ์ DOM์ด ์ด๋ค ์ํ๊ฐ ๋์ด์ผ๋ง" ์์ฒญ์ด ๋๊ฐ๋ ๊ฒ์ฒ๋ผ ๋ณด์ด๊ฒ ์ค๊ณ๋ผ ์์์ง๋ง, ์๋ฒ๋ ๊ทธ ์์ฒญ์ด ์ด๋ค ๊ฒฝ๋ก๋ก ๋ง๋ค์ด์ก๋์ง ์ ํ ๋ชจ๋ฅธ๋ค โ HTTP ์์ฒญ์ ๊ทธ ์์ฒด๋ก ์์ ํ ๊ฒ์ด๊ณ , ๋ธ๋ผ์ฐ์ ๊ฐ ์ด๋ค ์กฐ๊ฑด ํ์ ๊ทธ๊ฑธ ๋ณด๋๋์ง๋ ์๋ฒ์๊ฒ ์๋ฌด ์๋ฏธ๊ฐ ์๋ค. ํด๋ผ์ด์ธํธ ๋ก์ง์ด ์๋ฌด๋ฆฌ ๋ณต์กํด ๋ณด์ฌ๋, ์๋ฒ๊ฐ ์ต์ข ์์ฒญ์ ๋ด์ฉ๋ง ๊ฒ์ฆํ๋ค๋ฉด ๊ทธ ์์ฒญ์ ๊ทธ๋๋ก ์ฌํ ๊ฐ๋ฅํ๋ค. - "์ ๋ต ํ์ "์ด ํด๋ผ์ด์ธํธ ์ฃผ๋๋ก ๋ณด์ด๋ UX์ผ์๋ก, ์๋ฒ ์ชฝ ๊ฒ์ฆ์ด ์ค์ ๋ก ์ด๋๊น์ง์ธ์ง ํ์ธํด์ผ ํ๋ค. ์ด๋ฒ ์๋ํฌ์ธํธ๋ body์
statusํ๋ ์กด์ฌ ์ฌ๋ถ์กฐ์ฐจ ์๋ฏธ ์๊ฒ ๊ฒ์ฌํ์ง ์๋ ๊ฒ์ฒ๋ผ ๋ณด์๋ค โ ์ง์ง ํ์ํ ๊ฑด ์ธ์ ์ด๋ ์ด์ ์์ฒญ ์ด๋ ฅ์ ๊ธฐ๋ฐํ ์๋ฒ ์ฌ์ด๋ ์ํ ๊ฒ์ฆ์ด์์ ํ ๋ฐ, ๊ทธ๊ฒ ์ ํ ์์๋ค.
๋ฐฉ์ด์ ๊ด์ ์์ ๋ณด๋ฉด ์ด ๋ฌธ์ ๋ ๋จ์ํ์ง๋ง ์ค๋ฌด์์ ์ค์ ๋ก ๋ฐ๋ณต๋๋ ํจํด์ ์ ํํ ์ง๋๋ค โ "์ ๊ทผ ์ ์ด"์ฒ๋ผ ๋ณด์ด๋ ํ๋ฉด ์ฐ์ถ๊ณผ ์ค์ ์ ๊ทผ ์ ์ด๋ ๋ค๋ฅด๋ค. ํ๋ก ํธ์๋์์ ์๋ฌด๋ฆฌ ๊ทธ๋ด๋ฏํ ์กฐ๊ฑด๋ถ UI๋ฅผ ๋ง๋ค์ด๋, ๊ทธ UI๊ฐ ํธ๋ฆฌ๊ฑฐํ๋ API ์๋ํฌ์ธํธ ์์ฒด๊ฐ ๋ณ๋์ ์ธ์ฆ/์ธ๊ฐ ๊ฒ์ฆ ์์ด ์ด๋ ค ์๋ค๋ฉด ๊ทธ UI๋ ์ฅ์์ผ ๋ฟ์ด๋ค. /flag ๊ฐ์ ๋ฏผ๊ฐํ ์๋ํฌ์ธํธ๋ ์์ฒญ์ "ํํ"๊ฐ ์๋๋ผ ์์ฒญ์ ๋ณด๋ธ ์ฃผ์ฒด(์ธ์
, ํ ํฐ, ์ด์ ๋จ๊ณ์ ์๋ฒ ์ฌ์ด๋ ์ํ)๋ฅผ ๊ฒ์ฆํด์ผ ํ๋ค.
Comments
๋๊ธ
๋๊ธ์ ๋จ๊ธฐ๋ ค๋ฉด ๋ก๊ทธ์ธ์ด ํ์ํด์. (๋ค์ด๋ฒ ยท ๊ตฌ๊ธ ๊ณ์ )
๋๊ธ ๋ถ๋ฌ์ค๋ ์คโฆ