
들어가면 ? 자리에 문자들이 순서대로 주르륵 지나갑니다. 다시 확인해보면 FLAG 뒤에 플래그가 쭉 지나가는 거 같습니다. 물론 뛰어난 동체시력을 가지고 있으시거나(이걸 한 번 보고 외우실 수 있다면 진로를 바꿔보시는게...?) 녹화를 해서 플래그를 찾는 방법도 있겠지만, 저희는 출제자의 의도대로 풀어보도록 하겠습니다.
function run(){
if(window.ActiveXObject){
try {
return new ActiveXObject('Msxml2.XMLHTTP');
} catch (e) {
try {
return new ActiveXObject('Microsoft.XMLHTTP');
} catch (e) {
return null;
}
}
}else if(window.XMLHttpRequest){
return new XMLHttpRequest();
}else{
return null;
}
}
x=run();
function answer(i){
x.open('GET','?m='+i,false);
x.send(null);
aview.innerHTML=x.responseText;
i++;
if(x.responseText) setTimeout("answer("+i+")",20);
if(x.responseText=="") aview.innerHTML="?";
}
setTimeout("answer(0)",1000);
코드를 보니 뭔가 익숙하지 않은 문법이 보입니다. 이 코드는 웹 페이지를 새로고침하지 않고 서버와 데이터를 주고받기 위해 사용했던 초창기 AJAX(Asynchronous JavaScript and XML) 통신의 아주 오래된 레거시(과거) 코드입니다. 주로 인터넷 익스플로러(IE) 시절에 브라우저 간 호환성을 맞추기 위해 이렇게 작성했다고 합니다.
무슨 동작을 하는지 간단히 요약을 해보겠습니다.
준비 및 대기: 페이지가 열리고 1초 기다린 후, 첫 번째 통신을 시작합니다.
데이터 요청: 서버에 0번 데이터(?m=0)를 내놓으라고 요청합니다.
화면 업데이트: 서버에서 받아온 텍스트를 즉시 화면(aview 영역)에 보여줍니다.
연속 반복: 받아온 내용이 있다면, 숫자를 1 늘려서(?m=1, ?m=2...) 0.02초(20ms)라는 아주 짧은 간격으로 서버에 계속해서 다음 데이터를 요청합니다.
작동 종료: 만약 서버에서 더 이상 줄 데이터가 없어서 빈칸("")이 돌아오면, 화면에 ?를 띄우고 반복 통신을 완전히 멈춥니다.
짧은 간격으로 서버에 계속해서 다음 데이터를 요청하기 때문에 개발자 도구의 Network 탭에서 확인할 수 있습니다.
확인을 해보면 Preview 탭에서 출력되는 문자를 확인할 수 있습니다.

모든 m 값에 대한 출력을 모으면 플래그를 얻을 수 있습니다.
자동화하는 코드는 아래와 같습니다.
async function collectAnswers() {
let i = 0;
const aview = document.querySelector('#aview');
while (true) {
const response = await fetch(`?m=${i}`);
const text = await response.text();
if (text === "") {
aview.innerHTML += "?";
break;
}
aview.innerHTML += text;
i++;
await new Promise(resolve => setTimeout(resolve, 20));
}
}
setTimeout(collectAnswers, 1000);