This site is the archived OWASP Foundation Wiki and is no longer accepting Account Requests.
To view the new OWASP Foundation website, please visit

OWASP Backend Security Project DBMS Fingerprint

Revision as of 22:21, 22 July 2008 by Dbellucci (talk | contribs) (Banner Grabbing)

Jump to: navigation, search


To furthermore exploit SQL Injection vulnerability you need to know what kind of Database Engine your web application is using. There are a few techniques to accomplish this task:

  * Error Code Analysis
  * Engine Fingerprint


After determining that a web application is vulnerable to SQL Injection we need to fingerprint backend DBMS to furthermore exploit such a vulnerbility. Fingerprint is performed against a set of peculiarities of DBMS. Such a peculiarities are listed below in order of accuracy:

  • Informations exposed through an error code
  • String concatenation functions
  • SQL Dialects

Through a SQL Injection we can retrieve Backend DBMS banner but be aware that it could have been replaced by a system administrator. Such a SQL Injection shall include a SQL Statement to be evaluated. Let'see how to accomplish this task:

  • MySQL: SELECT version()
  • Postgres: SELECT version()
  • Oracle: SELECT version FROM v$instance
  • MS SQL:

Fingerprinting with string concatenation

Different DBMS handle string concatenation with different operators:

MS SQL: 'a' + 'a'

MySQL: CONCAT('a','a')

Oracle: 'a' || 'a' or CONCAT('a','a')

Postgres: 'a' || 'a'

As you can see both Oracle and Postgres use the || operator to perform such a concatenation, so we need another difference to distinguish them.

PL/SQL define the CONCAT operator as well to perform string concatenation and as you can guess this one is not defined on Postgres.


Let say you're testing the following URL:

You checked that the above URL is vulnerable to a Blind SQL Injection. It means that return back the same contents with both

id=1 (


id=1 AND 1=1 ( AND 1=1)

You know that different engine have different operators to perform string concatenation as well so all you have to do is to compare the orginal page (id=1) with:

  • MSSQL: id=1 AND 'aa'='a'+'a'
  • MySQL/Oracle: id=1 AND 'aa'=CONCAT('a','a')
  • Oracle/Postgres: id=1 AND 'a'='a'||'a'


The following comparison should be true:

  • AND 'aa'='a'+'a'''


The following comparison should be true:

  • AND 'aa'=CONCAT('a','a')


The following comparison should be true:

  • AND 'aa'=CONCAT('a','a')
  • AND 'aa'='a'||'a'


The following comparison should be true:

  • AND 'aa'='a'||'a'

Fingerprinting through SQL Dialect Injection

Each DBMS extends Standard SQL with a set of native statements. Such a set define a SQL Dialect available to developers to properly query a backend DBMS Engine. Beside of a lack of portability this flaw dafine a way to accurately fingerprint a DBMS through a SQL Injection, or even better a SQL Dialect Injection. SQL Dialect Injection is an attack vector where only statements, operators and peculiarities of a SQL Dialect are used in a SQL Injection.

As an example what does SELECT 1/0 returns on different DBMS?

  • Postgres: ERROR: division by zero
  • Oracle: ORA-00923: FROM keyword not found where expected

Let see more about this fingerprinting technique.


One of MySQL peculiarities is that when a comment block ('/**/') contains an exlamation mark ('/*! sql here*/') it is interpreted by MySQL, and is considered as a normal comment block by other DBMS.

So, if you determine that is vulnerable to a BLIND SQL Injection the following comparison should be 'TRUE: AND 1=1--

When backend engine is MySQL following WEB PAGES should contains the same content of vulnerable URL /*! AND 1=1 */--

on the other side the following should be completely different: /*! AND 1=0 */--


Postgres define the :: operator to perform data casting. It means that 1 as INT can be convert to 1 as CHAR with the following statements:


So, if you determine that is vulnerable to a BLIND SQL Injection the following comparison should be true when backend engine is PostgreSQL: AND 1=1::int

MS SQL Server: ..... .....




Error Codes Analysis

By performing fault injection, or fuzzing, you can gather important information through error code analysis when web application framework reports errors. Let'see some examples:'

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version 
for the right syntax to use near '''''   at line 1'

Warning: pg_exec() []: Query failed: ERROR: unterminated quoted string at or near "'" LINE 1: 
SELECT * FROM products WHERE ID=' ^ in /var/www/store/products.php on line 9


Victor Chapela: "Advanced SQL Injection"