Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I've read that different databases (mysql, sql server,...) have different vulnerabilities and that they are vulnerable to some specific sql injections.

When attacker try to perform a database attack against a website (like SQL injection) first of all identifies the kind of database, and after performs the attack thinking of the database detected.

How this previous inspection is performed by the attacker? Using some special queries? Are there specific tools? I've not found any information of this.

share|improve this question
add comment

4 Answers

up vote 10 down vote accepted

Let's say you've got a query like this:

$q="SELECT username, joindate FROM users WHERE username LIKE '%" . $search . "%' LIMIT 20";

Now imagine you control $search via a parameter. We would usually make it return the user passwords in the joindate field like this:

$search="' UNION SELECT username, password FROM users; -- -";

As such the query becomes:

SELECT username, joindate FROM users WHERE username LIKE '%' UNION SELECT username, password FROM users; -- - %' LIMIT 20

The part after the double-hyphen is a comment, so it's ignored, and we get all the username and password combinations appended as new records at the end of the dataset, after the legitimate records. Awesome!

But now we want to adapt this so we can find the database name, for further investigation of their database. On MySQL, we can use the DATABASE() function:

$search="' UNION SELECT DATABASE(), 1; -- -";

The use of 1 here is to pad the joindate field, which we aren't using.

On MSSQL we can do exactly the same, but with DB_NAME():

$search="' UNION SELECT DB_NAME(), 1; -- -";

Both of these tricks will append a single row to the end of the result set, containing the database name.

We can then expand this trick to use VERSION() on MySQL or @@VERSION on MSSQL, which returns the current database version. For Oracle and PL/SQL you can check for the existence of the v$version table, simply by doing a query on it and checking for an error.

share|improve this answer
    
+1 for your AWESOME profile picture. –  marco-fiset Dec 10 '12 at 15:53
    
Haha, cheers. It's from Metal Gear Awesome (warning: nsfw) –  Polynomial Dec 10 '12 at 16:03
1  
Yeah I know about that :P That's why I put some emphasis on "awesome" ;) –  marco-fiset Dec 10 '12 at 16:07
    
How did I miss that one? Clearly not had enough coffee today... –  Polynomial Dec 10 '12 at 16:10
    
Also, check out the SQL Injection pocket reference docs.google.com/… –  droope Dec 13 '12 at 20:13
add comment

There are a number of methods to do this. However, note that you do not need to know the type of database to perform an attack. Knowing it may provide additional or alternative attack vectors, but is not necessary for SQL injection.

Most database provide funcitons or have dictionary tales which can be used to identify the database type and version. These differ between vendors, but provided you have found a general sql injection point, you can just try each until you get a valid response.

There are also syntactic differences between many different dialects of SQL. For example, Oracle has the (+) syntax to represent outer joins. There are often subtle differences in available datatypes, such as postgres' text type (which Oracle does not have) or in how sequences/auto incrementing columns are handled etc.

Sometimes, you can tell by just getting database driver or connector details. Depending on the environment, language etc, this may or may not be trivial.

share|improve this answer
add comment

In addition to the other answers, one method I use for database fingerprinting (especially where the injection is blind and not data is returned) is differences in syntax between database engines. There's a good sample on slide 34 of this presentation which I tend to use.

So a good example is string concatenation. MS-SQL and DB2 use + whereas Oracle PL/SQL and PostGRES use ||, so you can insert that into strings and watch the behaviour of the application. If it behaves like the string was concatenated then it's possibly injection.

share|improve this answer
add comment

One of the simplest ways for an attacker to determine what database is being used by an application would be to cause the application to error in some way with a database query.

Then if error handling isn't enabled within the application ( which often its not ) the database error will be shown. These are usually quite detailed and you can determine the database from that.

Its also worth considering if you know any of the following the language the web application is written in, the framework being used, the platform that is being used, the hosting provider e.t.c. they can all help work out what database is being used. For example if they are using asp most likely be using MSSQL and if they are using PHP most likely MySQL. This isn't true all the time obviously but if you where having to guess for say a blind sql injection attack its another way of narrowing things down.

share|improve this answer
    
Not very concrete, and if you've already got an SQL injection there are much easier and more reliable methods. –  Polynomial Dec 10 '12 at 11:59
    
@Polynomial your right without a doubt. I'm just saying without knowing any potential SQL Injection attack that's a place to start. –  Mark Davidson Dec 10 '12 at 12:14
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.