반응형
문제설명
드림이는 자신이 한 말에 무조건 인사해주는 웹 서비스를 만들었어요!
하지만 서비스가 최근 이상한 동작을 한다는 제보가 들어왔어요
플래그 형식은 null{...}입니다
코드분석
app.get('/', (req, res) => {
return res.sendFile(path.join(__dirname, "..", "greet.html"));
});
- 메인화면 greet.html을 반환해주는 코드
app.get('/api', (req, res) => {
if (req.ip !== '::1') return res.send('No');
const isAdmin = Number(req.query.admin);
console.log('isAdmin', isAdmin);
if (isAdmin !== 0) {
return res.send(FLAG);
}
return res.send(`${req.query.msg} ❤️`);
});
- /api 요청 시 실행
- 요청 ip가 '::1' 아닐 시 No 반환 → 외부 접근 막으려는 의도
- 쿼리스트링 admin 값을 숫자로 변환해 isAdmin 변수에 삽입
- isAdmin이 0이 아니면 FLAG 반환
- admin이 정확히 0이면 하트를 붙여 반환
app.post('/greet', async (req, res) => {
const msg = String(req.body.msg);
if (msg.includes('admin') || msg.includes('\\') || msg.includes('%') || msg.includes('?') || msg.includes(';') || msg.includes('#') || msg.includes('[') || msg.includes(']')) return res.json({ result: 'Not allowed character' });
const resp = await axios.get(`http://localhost:3000/api?msg=${msg}&admin=0`);
return res.json({ result: resp.data });
});
- /greet 처리
- msg가 응답 바디로 문자열 포함됨
- msg에 admin / \\ / % / ? / ; / # / [ / ] 포함 시 Not allowed character 출력
- 내부 API를 호출 사용자 입력 msg를 URL에 직접 문자열 결합
- 내부 /api 응답을 그대로 result로 돌려줌
/api 엔드포인트를 /greet가 대신 호출해 줌
취약점 분석
- msg를 URL에 직접 이어 붙여 쿼리파라미터 구조를 오염시켜 admin 값 판정을 깨뜨릴 수 있음
- 특정 문자열만 검사해서 \u000d 같은 문자로 우회가능
익스플로잇
먼저 /greet 요청을 가로채기 위해 yeonbug 문자열을 삽입해줌


다음과 같이 화면과 요청/응답을 확인할 수 있음
msg의 값을
"msg" : "yeonbug&a\rdmin=1"
\r 문자열로 인해 admin=0 이라는 검사가 무력화 됨.
즉, CR 때문에 쿼리 해석이 꼬여서 FLAG 분기로 가는 것

반응형
'Dreamhack 워게임 > Lv.1' 카테고리의 다른 글
| ez_race (0) | 2026.02.20 |
|---|---|
| Test Your Luck (0) | 2026.02.19 |
| Hangul - Revenge (0) | 2026.02.19 |
| Ctrl-C (0) | 2026.02.19 |
| Pearfect Markdown (0) | 2026.02.15 |