A couple of days ago I wrote my first post about DBMS fingerprint through SQL injection focusing on two techniques implemented in sqlmap.
Today the post is about two more techniques to fingerprint the web application database backend through SQL injection:
Today the post is about two more techniques to fingerprint the web application database backend through SQL injection:
- DBMS functions output comparison
- DBMS specific features
I will use the same scenario proposed in my first post and I recommend you to read the previous post before going further with this.
DBMS functions output comparison
Once we know that at least one target url parameter is affected by an exploitable inband SQL injection we can use this SQL injection technique also to perform a DBMS fingerprint based upon functions static output comparison. Otherwise, like each other detection technique already described, we should try to perform a blind SQL injection or an error based SQL injection to take advantage of the SQL injection vulnerable parameter.
The aim of DBMS function output comparing is to fingerprint the DBMS by comparing the output of standard and more important specific DBMS functions to their static values, requesting for instance http://example/index.php?id=1+UNION+SELECT+NULL, CONCAT('sql',+'injection'), we get:
This technique is more useful than inband DBMS error messages because, not only we get the DBMS backend, we can also get its exact release and version number by requesting functions that are implemented, in our scenario, only from a certain release or above.
For instance, if we already know with CONCAT() that it is MySQL and we request http://example/index.php?id=1+UNION+SELECT+NULL, CURRENT_USER(), the web application will reply with the actual database username (in our scenario testuser@localhost) only if the MySQL version is greater than or equal 4.0.6 because CURRENT_USER() function was introduced from this version.
Otherwise if the web application returns us a DBMS error message or a blank value in the page it means that the remote DBMS is MySQL <>
The same technique can be used for PostgreSQL and any other DBMS that implements, with new releases, new functions and variables with static outputs and values. These information can be retrieved having a look at the DBMS official websites in the press release release, documentation changelog and sometimes also revision control commit messages.
At the moment of writing this post I implemented this technique in sqlmap code for MySQL and PostgreSQL:
DBMS specific features
The aim of exaustive DBMS fingerprint through a SQL injection is to detect as much information as possible about the database backend. I wrote about three techniques so far and this last is probably the most peculiar because its existance and output totally differs depending on the DBMS.
MySQL has a feature that turns into a threat when exploiting a SQL injection. It can be used to fingerprint the DBMS exact version. This technique can be called MySQL comment injection and is based, in facts, on MySQL comment syntax.
In our scenario we now already know that the web application database backend is MySQL, but what happens if we append a syntatically valid SQL comment to the value of parameter id?
Requesting, for instance, http://example/index.php?id=1+/*+comment+*/ does not lead to an error because there are no syntax errors, but, quoting the MySQL manual:
Implementation on sqlmap code:
A peculiarity in Microsoft SQL Server is that the DBMS banner (@@VERSION variable) value leaks more information than what it is commonly known. The @@VERSION value is similar to:
A detailed list of versions with corresponding patch level is available at Chip Andrews' SQLSecurity.com website.
Implementation on sqlmap code:
DBMS functions output comparison
Once we know that at least one target url parameter is affected by an exploitable inband SQL injection we can use this SQL injection technique also to perform a DBMS fingerprint based upon functions static output comparison. Otherwise, like each other detection technique already described, we should try to perform a blind SQL injection or an error based SQL injection to take advantage of the SQL injection vulnerable parameter.
The aim of DBMS function output comparing is to fingerprint the DBMS by comparing the output of standard and more important specific DBMS functions to their static values, requesting for instance http://example/index.php?id=1+UNION+SELECT+NULL, CONCAT('sql',+'injection'), we get:
<table>CONCAT() is a DBMS specific function present is MySQL. If we got an error we could assume that the remote DBMS is not MySQL, but since we can see that in the HTML of the response we have sqlinjection string we have one more input that the remote DBMS is MySQL.
<tr><td>1</td></tr>
<tr><td>foo</td></tr>
<tr><td>sqlinjection</td></tr>
</table>
This technique is more useful than inband DBMS error messages because, not only we get the DBMS backend, we can also get its exact release and version number by requesting functions that are implemented, in our scenario, only from a certain release or above.
For instance, if we already know with CONCAT() that it is MySQL and we request http://example/index.php?id=1+UNION+SELECT+NULL, CURRENT_USER(), the web application will reply with the actual database username (in our scenario testuser@localhost) only if the MySQL version is greater than or equal 4.0.6 because CURRENT_USER() function was introduced from this version.
Otherwise if the web application returns us a DBMS error message or a blank value in the page it means that the remote DBMS is MySQL <>
The same technique can be used for PostgreSQL and any other DBMS that implements, with new releases, new functions and variables with static outputs and values. These information can be retrieved having a look at the DBMS official websites in the press release release, documentation changelog and sometimes also revision control commit messages.
At the moment of writing this post I implemented this technique in sqlmap code for MySQL and PostgreSQL:
DBMS specific features
The aim of exaustive DBMS fingerprint through a SQL injection is to detect as much information as possible about the database backend. I wrote about three techniques so far and this last is probably the most peculiar because its existance and output totally differs depending on the DBMS.
MySQL has a feature that turns into a threat when exploiting a SQL injection. It can be used to fingerprint the DBMS exact version. This technique can be called MySQL comment injection and is based, in facts, on MySQL comment syntax.
In our scenario we now already know that the web application database backend is MySQL, but what happens if we append a syntatically valid SQL comment to the value of parameter id?
Requesting, for instance, http://example/index.php?id=1+/*+comment+*/ does not lead to an error because there are no syntax errors, but, quoting the MySQL manual:
If you add a version number after the “!” character, the syntax within the comment is executed only if the MySQL version is greater than or equal to the specified version number. The TEMPORARY keyword in the following comment is executed only by servers from MySQL 3.23.02 or higher:Requesting then http://example/index.php?id=1+/*!50114+AND+1=2*/ the SQL condition within the comments is evaluated only if MySQL version is greater than or equal MySQL 5.1.14 (because of 50114). In our scenario we already know from DBMS banner parsing technique that our database backend is MySQL 5.0.38, so such request would show the normal page because the condition within brackets is not evaluated, but requesting http://example/index.php?id=1+/*!50038+AND+1=2*/ we get a DBMS error message or a blank page because the SQL condition (WHERE ID=1 AND 1=2) is evaluated since 50038 pointed is 5.00.38 which is MySQL version 5.0.38.
CREATE /*!32302 TEMPORARY */ TABLE t (a INT);
Implementation on sqlmap code:
A peculiarity in Microsoft SQL Server is that the DBMS banner (@@VERSION variable) value leaks more information than what it is commonly known. The @@VERSION value is similar to:
Microsoft SQL Server 2000 - 8.00.194 (Intel X86)The first line of the value discloses the exact version and patch level of the database management system in fact the string 8.00.194 is Microsoft SQL Server 2000 without any DBMS service pack or minor patch. At the moment of writing this post the latest Microsoft SQL Server 2000 version is 8.00.2249 which is Microsoft SQL Server 2000 with Service Pack 4 + cumulative patch Q936232 and the latest Microsoft SQL Server 2005 version is 9.00.3169 which is Microsoft SQL Server 2005 Service Pack 1 + cumulative Q937041.
Aug 6 2000 00:57:48
Copyright (c) 1988-2000 Microsoft Corporation
Developer Edition on Windows NT 5.0 (Build 2195: Service Pack 4)
A detailed list of versions with corresponding patch level is available at Chip Andrews' SQLSecurity.com website.
Implementation on sqlmap code:

1 comments:
A really nice place to find useful informations about sql injection. Especially for the beginners :) But also geeks will find something interesting here :)
Post a Comment