12.3 Blind SQL Injection & Database Enumeration
Key Takeaways
- Inferential (Blind) SQL Injection occurs when an application executes malicious SQL queries without returning database error messages or query result sets in HTTP responses.
- Boolean-based blind SQLi forces differential application behavior by injecting True and False conditional predicates (' AND 1=1 -- vs ' AND 1=2 --), extracting data bit-by-bit or character-by-character.
- Time-based blind SQLi leverages conditional execution delays using engine-specific functions—MSSQL WAITFOR DELAY, MySQL SLEEP(), PostgreSQL pg_sleep(), and Oracle DBMS_PIPE.RECEIVE_MESSAGE().
- Standardized metadata schemas allow systematic structural enumeration: information_schema.tables and information_schema.columns in MySQL/MSSQL/PostgreSQL, and data dictionary views (ALL_TABLES, ALL_TAB_COLUMNS, USER_TABLES) in Oracle.
- Automated exploitation frameworks such as sqlmap automate heuristic detection, character extraction algorithms, and WAF evasion using customizable tamper scripts.
12.3 Blind SQL Injection & Database Enumeration
In modern hardened web applications, database errors are suppressed and query output is rarely reflected directly within HTTP responses. However, an application may remain fundamentally vulnerable to SQL injection if untrusted user input is still concatenated into database execution strings. When data cannot be extracted through in-band channels (UNION or verbose error messages), security analysts must utilize Inferential (Blind) SQL Injection techniques to reconstruct sensitive information by observing subtle side-channel behaviors.
Principles of Inferential (Blind) SQL Injection
Inferential SQL injection differs from in-band injection because the attacker cannot see any direct database data in the application response. Instead, the attacker asks the database a series of binary (True/False) questions. By observing how the application or server responds to these questions, the attacker deduces data character-by-character.
+-----------------------------------------------------------------------------+
| BLIND SQL INJECTION METHODOLOGIES |
+-----------------------------------------------------------------------------+
| Feature | Boolean-Based Blind | Time-Based Blind |
+----------------------+-------------------------------+----------------------+
| Feedback Mechanism | Visible Response Differences | Network Delay |
| Indicator | HTTP 200 vs 500, Content- | Response takes >= N |
| | Length, Specific text message | seconds to return |
| Network Sensitivity | High resilience to network lag| Prone to jitter/skew |
| Execution Speed | Fast (binary search) | Slow (delay penalty) |
+-----------------------------------------------------------------------------+
Boolean-Based Blind SQL Injection
Boolean-based blind SQL injection occurs when the application renders different responses depending on whether an injected SQL condition evaluates to TRUE or FALSE.
[Client Request: id=5 AND 1=1] ---> [Database Evaluates TRUE] ---> Response: "Product Found"
[Client Request: id=5 AND 1=2] ---> [Database Evaluates FALSE] ---> Response: "Product Not Found"
Identifying the Boolean Vulnerability
To establish whether a parameter is susceptible to Boolean blind injection, the tester submits paired test conditions:
- Positive Test (True):
item.php?id=10 AND 1=1(or' AND 'a'='a)- Expected Behavior: The page displays normally, showing the record, a 200 OK status, or expected content.
- Negative Test (False):
item.php?id=10 AND 1=2(or' AND 'a'='b)- Expected Behavior: The page changes—the item is missing, an error message appears ("Item not found"), the HTTP status becomes 404, or the response
Content-Lengthdiffers significantly.
- Expected Behavior: The page changes—the item is missing, an error message appears ("Item not found"), the HTTP status becomes 404, or the response
If the application demonstrates consistent, reproducible differences between True and False inputs, the parameter is vulnerable to Boolean blind exploitation.
Character-by-Character Extraction Mechanics
To extract confidential data, the attacker combines three programmatic SQL functions:
SUBSTRING(str, pos, len)(orMID()): Extracts a single character from a string at a specified 1-based index position.ASCII(char): Converts the extracted character into its decimal ASCII numerical code (e.g.,'a'= 97,'A'= 65,'0'= 48).- Comparative Operators (
>,<,=): Evaluates the numerical ASCII value against test values.
Linear Search vs Binary Search
If a tester tests every ASCII value sequentially from 32 to 126, extracting a 20-character password requires an average of 20 * 47 = 940 HTTP requests.
By implementing a Binary Search (Bisection) Algorithm, the tester halves the search range with each request:
-- Step 1: Is the ASCII value of the 1st character greater than 64? (Range: 0-127)
AND ASCII(SUBSTRING((SELECT password FROM users WHERE username='admin'), 1, 1)) > 64 -- [TRUE]
-- Step 2: Is it greater than 96? (Range: 65-127)
AND ASCII(SUBSTRING((SELECT password FROM users WHERE username='admin'), 1, 1)) > 96 -- [TRUE]
-- Step 3: Is it greater than 112? (Range: 97-127)
AND ASCII(SUBSTRING((SELECT password FROM users WHERE username='admin'), 1, 1)) > 112 -- [FALSE]
-- Step 4: Is it greater than 104? (Range: 97-112)
AND ASCII(SUBSTRING((SELECT password FROM users WHERE username='admin'), 1, 1)) > 104 -- [FALSE]
-- Step 5: Is it greater than 100? (Range: 97-104)
AND ASCII(SUBSTRING((SELECT password FROM users WHERE username='admin'), 1, 1)) > 100 -- [FALSE]
-- Step 6: Is it equal to 97? ('a')
AND ASCII(SUBSTRING((SELECT password FROM users WHERE username='admin'), 1, 1)) = 97 -- [TRUE]
A binary search determines any ASCII character in at most 7 HTTP requests (log2(128) = 7), dramatically accelerating extraction.
Time-Based Blind SQL Injection
In many applications, the web application code handles errors silently and always returns identical content (e.g., "Search processed") regardless of whether the SQL query returned data or encountered an empty set. In this scenario, Boolean conditions produce no discernible change in HTTP status or body.
Time-based blind SQL injection overcomes this limitation by forcing the database server to pause execution for a designated duration (e.g., 5 seconds) when a condition evaluates to TRUE.
Attacker ---> Submits Query with Conditional Sleep ---> Target Server
|
v (Database evaluates: IF condition is TRUE -> SLEEP 5)
|================== [5 Second Pause] ==================>
|
Attacker <--- Receives HTTP Response after 5.12 Seconds <-----------------+
[Conclusion: Condition is TRUE]
Database-Specific Time Delay Primitives
Each database management system implements distinct procedural functions to introduce sleep states:
+-----------------------------------------------------------------------------+
| DATABASE TIME DELAY PRIMITIVES (CPSA CORE) |
+-----------------------------------------------------------------------------+
| RDBMS | Delay Function / Command | Syntax Example |
+--------------------+-------------------------------+------------------------+
| Microsoft SQL | WAITFOR DELAY | WAITFOR DELAY '0:0:5' |
| MySQL / MariaDB | SLEEP() | SELECT SLEEP(5) |
| | BENCHMARK() (Alternative) | BENCHMARK(5000000,MD5(1))|
| PostgreSQL | pg_sleep() | SELECT pg_sleep(5) |
| Oracle RDBMS | DBMS_PIPE.RECEIVE_MESSAGE() | DBMS_PIPE.RECEIVE_MESSAGE|
| | | ('channel', 5) |
| SQLite | randomblob() heavy computation| (SELECT count(*) FROM |
| | | generate_series) |
+-----------------------------------------------------------------------------+
Conditional Branching Syntax
To extract data using time delays, the delay command is wrapped inside a conditional statement (IF or CASE):
- Microsoft SQL Server:
'; IF (SELECT ASCII(SUBSTRING(user_name(), 1, 1))) = 100 WAITFOR DELAY '0:0:5'-- - MySQL:
' AND IF(ASCII(SUBSTRING((SELECT version()), 1, 1)) = 56, SLEEP(5), 0)-- - PostgreSQL:
' AND (SELECT CASE WHEN (ASCII(SUBSTRING(current_user, 1, 1))=112) THEN pg_sleep(5) ELSE pg_sleep(0) END)-- - Oracle:
' AND 1=(CASE WHEN (ASCII(SUBSTRING((SELECT user FROM dual), 1, 1))=83) THEN DBMS_PIPE.RECEIVE_MESSAGE('a', 5) ELSE 1 END)--
Operational Considerations for Testers: Time-based attacks are susceptible to false positives and false negatives caused by network congestion or high database server load. Testers should select delay intervals (typically 3 to 5 seconds) that clearly exceed baseline network jitter while minimizing total assessment duration.
Database Metadata Enumeration Standards
Once an injection vector is established, an analyst systematically enumerates the database environment. Modern relational databases maintain metadata describing schemas, tables, and columns.
ANSI information_schema (MySQL, MSSQL, PostgreSQL)
The ANSI SQL-92 standard defines the information_schema, a set of read-only views available in MySQL, MSSQL, and PostgreSQL:
- Enumerating Databases / Schemas:
SELECT schema_name FROM information_schema.schemata; - Enumerating Tables in the Current Database:
SELECT table_name FROM information_schema.tables WHERE table_schema = database(); - Enumerating Columns within a Specific Table:
SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'tbl_users';
Oracle Data Dictionary Views
Oracle does not support information_schema. Instead, it uses hierarchical data dictionary views prefixed by access scope:
USER_TABLES/USER_TAB_COLUMNS: Objects owned by the currently connected user.ALL_TABLES/ALL_TAB_COLUMNS: Objects accessible to the current user (including granted permissions).DBA_TABLES/DBA_TAB_COLUMNS: All objects across the entire database instance (requires DBA privileges).
-- Enumerating accessible tables in Oracle
SELECT owner, table_name FROM all_tables;
-- Enumerating columns for a specific table in Oracle
SELECT column_name, data_type FROM all_tab_columns WHERE table_name = 'USERS';
PostgreSQL Native Catalog
In addition to information_schema, PostgreSQL provides its internal system catalog in the pg_catalog schema:
SELECT relname FROM pg_catalog.pg_class WHERE relkind = 'r';
SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname = 'public';
Automated Exploitation Tools: Principles and Mechanics of sqlmap
While understanding manual exploitation mechanics is vital for penetration testers, automated tools like sqlmap streamline detection and data recovery across complex web applications.
Detection Techniques & Heuristics
sqlmap systematically tests injection points using six categories of techniques (represented by the letters B, E, U, S, T, Q):
B: Boolean-based blindE: Error-basedU: Union query-basedS: Stacked queriesT: Time-based blindQ: Inline queries
Key Operational Parameters
--level (1-5): Controls the scope of tests performed. Level 1 tests GET and POST parameters. Level 2 addsCookieheaders. Level 3 addsUser-AgentandRefererheaders. Level 5 expands tests to host headers and deep arbitrary payloads.--risk (1-3): Controls the aggressiveness of test payloads. Risk 1 is completely safe. Risk 2 adds heavy time-based tests. Risk 3 addsOR-based tests, which carry a potential risk of unintentionally updating or corrupting database tables if applied toUPDATEorDELETEstatements.--dbs,--tables,--columns,--dump: Directs automated enumeration of databases, tables, columns, and data extraction.
Tamper Scripts for WAF / Filter Evasion
When Web Application Firewalls (WAFs) or input filters block standard SQL keywords, sqlmap applies tamper scripts to rewrite outgoing payloads without altering their semantic meaning:
space2comment.py: Replaces space characters with inline comments (SELECT/**/id/**/FROM/**/users).randomcase.py: Randomizes character casing (SeLeCt * FrOm uSeRs).charencode.py: URL-encodes payload characters to evade pattern-matching signatures.
A penetration tester identifies an injection point in an Oracle application that suppresses all errors and returns identical response pages. Which SQL statement can be injected to confirm a time-based blind vulnerability by inducing a five-second delay?
In Boolean-based blind SQL injection, an analyst wants to minimize the number of HTTP requests required to extract individual characters from a 60-character database hash. Which algorithmic technique should be implemented?
During an engagement against an enterprise database, an analyst needs to enumerate all table names accessible to the current user. Which data source should be queried if the target database is Oracle, as opposed to MySQL or MSSQL?
When configuring the automated exploitation tool sqlmap against a production web application, what is the primary operational hazard associated with setting --risk=3?