먼저 텍스트 필드에 <script>alert(document.domain)</script> 를 넣어보면 그냥 문자열로 페이지에 출력되고 특수문자들은 HTML encoding 되어진다.
0. 문제
function escape(s) {
return s.split('#').map(function(v) {
// Only 20% of slashes are end tags; save 1.2% of total
// bytes by only escaping those.
var json = JSON.stringify(v).replace(/<\//g, '<\\/');
return '<script>console.log('+json+')</script>';
}).join('');
}
JSON , JSON 2 와 다르게
'</'를 '<\/>'로 바꿔버린다.
+ #을 기준으로 split해서 값을 처리한다.
ex) string1#string2가 input으로 들어가면
'<script>console.log(string1)</script><script>console.log(string2)</script>'
가 리턴된다.
1. 풀이
<script> 태그 안에 들어가게 되면 html 내에서 Script data state 상태로 넘어가게 된다.
script data state 에서 <!-- 를 만나게 되면 Script data escaped dash dash state 상태가 되는데
여기서 <script를 만나게 되면 Script data double escaped state 상태가 된다.
<script> 태그인 Script data state에서 </script> 태그를 만나면 html data state로 빠져나가게 되는 것같이
<!--<script 인 Script data double escaped state 상태에서 </script를 만나게 되면 Script data escaped state 상태가 되고
-->를 만나게 되면 Script data state 상태가 된다.
따라서 <!--<script 상태에서 </script>를 만나게 되도 script data state가 유지가 되면서 해당 태그 또한 javascript문으로 인식이 되게 된다.
이를 이용해 input으로
<!--<script #)/+alert(1)//--> 을 넣어주면
<script>console.log("<!--<script ")</script><script>console.log(")/+alert(1)//-->")</script>
이렇게 리턴되어서 alert(1)을 띄울 수 있다.
추가적으로 설명하자면
중간의 </script>문은 html의 end tag로 해석되지 않기 때문에
/script>
console.log("
그 뒤의 alert(1)쪽은 dobule quote를 탈출했기 때문에 왼쪽 문자열뒤에 연산자 혹은 ;를 붙여주며 구분해준 뒤
alert(1)을 적고 뒤에 있는 //은 -->"를 주석처리 해주기 위해서 추가해준다.
+++++++++++++++++++++++++++++++++++++++++++++++++ 19.11.24
'//' 대신 '\u2028' or '\u2029'를 넣어주면 주석처리가 됨.
copy('\u2028')후 '//'자리에 붙여넣으면 28글자로 풀이 가능함.
[공부내용]
1. html spec으로 parser를 제대로 살펴보면 다 이해가 됨
2. script data state에서는 <!--가 주석이 아님
3. spec에는 희안한게 많음
[Reference]
https://m.blog.naver.com/PostView.nhn?blogId=dmbs335&logNo=221451852498&navType=tl
'Web hacking' 카테고리의 다른 글
[분석] PHP - Object member naming when type changing to array (0) | 2020.02.22 |
---|