Database Fingerprinting
Before crafting targeted SQL injection payloads, identify the backend database management system. Different DBMSs use different syntax for string concatenation, version queries, error messages, time delays, and metadata access. Fingerprinting narrows the payload space and avoids wasted requests.
Version queries
Each DBMS exposes version information through different functions and system views:
| DBMS | Version query |
|---|---|
| MySQL | SELECT @@version or SELECT version() |
| Microsoft SQL Server | SELECT @@version |
| PostgreSQL | SELECT version() |
| Oracle | SELECT banner FROM v$version or SELECT version FROM v$instance |
These can be appended to an existing query via UNION — e.g., ' UNION SELECT @@version--. MySQL and MSSQL share @@version; distinguish them via string concatenation or error messages.
String concatenation
Concatenation syntax differs across vendors and can be tested with boolean operations (construct a tautology that only works if the concatenation is valid):
| DBMS | Concatenation |
|---|---|
| MySQL | CONCAT('a','b') or 'a' 'b' (space-separated) |
| Microsoft SQL Server | 'a' + 'b' |
| PostgreSQL | `‘a' |
| Oracle | CONCAT('a','b') or `‘a' |
Test with a boolean equivalent to 1=1 — e.g., ' AND 'a'||'b'='ab'-- for PostgreSQL/Oracle. URL-encode pipes and spaces when operating directly on a URL.
Error messages
When verbose errors are returned, fingerprinting is trivial:
- MySQL — errors always contain the string “MySQL” and often the server version
- Oracle — all errors are prefixed with
ORA-followed by a five-digit number - Microsoft SQL Server — errors mention “Microsoft SQL Server” or use MSSQL-specific syntax terminology
- PostgreSQL — errors use
ERROR:orFATAL:prefixes with PostgreSQL-specific detail format
Behavioral differences
| Feature | MySQL | MSSQL | PostgreSQL | Oracle |
|---|---|---|---|---|
| Time delay | SLEEP(n) | WAITFOR DELAY 'h:m:s' | pg_sleep(n) | dbms_pipe.receive_message() |
| Substring | SUBSTRING() | SUBSTRING() | SUBSTRING() | SUBSTR() |
| Limit rows | LIMIT n | TOP n | LIMIT n | ROWNUM |
| Stacked queries | Sometimes (driver-dependent) | Yes | Yes | No |
| Batched query separator | ; | ; or newline | ; | N/A |
Sources
- SQL injection cheat sheet — PortSwigger
- Examining the database in SQL injection attacks — PortSwigger
- MySQL 8.0 Reference Manual — String Functions and Operators
- @@VERSION (Transact-SQL) — SQL Server | Microsoft Learn
See also
- sql-injection-attacks — the hub page for SQLi types and defense
- test-for-sqli — detection methodology
- enumerate-database-schemas — next step after fingerprinting
- common-sql-variables — server variables useful for recon
- sqlmap — automates fingerprinting with
--fingerprintand--banner