106
Posted December 10, 2009 by Spyros in Security
 
 

How I Hacked a Popular Website Using SQL Injection

sql_injection
sql_injection

Few people really mind security matters before anything bad happens to them. Once they get to feel how it is to lose data or give away precious information due to security faults, they begin to get more concerned over protecting their data. When it comes to websites, SQL security is one of the most important thing that haunts them. Of course, the most important one, is the php/asp or whatever code it uses.

The problem with almost every security fault is trust. In the world of websites and user related data, nothing is to be taken for granted. Do you ask your users to register for your website under a given name ? Then, you should check what that input. Never, ever assume that the website user will not be a malicious person. Do not trust your users !

What is SQL injection ?

This idea extends to lots of different exploits, but certainly one of the most well known and easily exploitable ones is definately mySQL injections. As with any other input devices, databases handle user input as well, and heavily. In this post, i assume that you’re at least familiar with SQL. If not, please take a look at this tutorial about mysql programming.

The scenario is simple. There is a part of a website that handles some user input and then makes a simple query back to the database. Let’s suppose that in this webpage, a user gets to view his/her emails. The url of the page is like “www.website.com?index.php?page=mail&uid=3”.

Now, as you see, there is a GET parameter passed to a php script. This corresponds to our user id, being 3. So, in the actual php script, the code that gets a user emails from the database would be like :


$query = "SELECT * FROM mails WHERE uid='$_GET['uid']' ";
mysql_query($query);

Now this seems ok, doesn’t it ? Actually, it is a very vulnerable execution flow. Using that, an attacker can even delete the whole database, in some cases. What they could easily do, is get the mails of other users apart from the ones of their legitimate account. As you see, we specify the uid value through the url. What would happen if that value was 4 instead of 3 ? Well, we would just be able to see every email, that a user who was unlucky enough to have the user id 4, has stored inside the system.

How I Hacked a Popular Website

Well, there are actually hundreds of websites that follow this scheme. However, i was surprised to see that a very well known website had this trivial security problem. I will not specify the actual url, but i will present you with the test case. One of the very first things that i do when i want to test a website for vulnerabilities, is check if there is an /admin page.

In this case, there was one. A typical one, needing a username and a password. The next step is checking for sql vulnerabilities. One of the easiest ways to do so is just input a single quote (‘) as a username or password. Doing so, you get this error :

“error 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 ”” and password=” )’ at line 1″

This now makes it sure for us that there is a big mySQL vulnerability here. Why this error comes up ? Well, think of the previous query specified above. If you just input a single quote, the query becomes faulty and mySQL returns an error code.We know that this is vulnerable, but what can we do ? First of all, let’s think how the actual registration check may look like. It could be like this :


$query = "SELECT COUNT(*) as count FROM users WHERE password='$password' ";
 $result = mysql_query($query);

if ($result['count'] > 0)  ..... // you are admin

If somebody enters the correct admin password, they become an administrator. While this would be fair, the implementation is not secure. We could make it so that the query returns more than 0 results. But how ? What about selecting all the users of the system ? If the query was like :


$query = "SELECT COUNT(*) as count FROM users WHERE password='$password' OR 1=1";

This selects every user, if the password correct or 1=1. But 1 will be 1 for every user ! Therefore, every user will be selected. This principle is what makes it easy for us now to exploit. The key would be an input value like 1′ or ‘1’=’1 . This makes the sql command like :


$query = "SELECT COUNT(*) as count FROM users WHERE password='1' or '1'='1'  ";

Do you see it ? It returns as a count the total number of all the users in the database, meaning that we effectively get to be admins. Once you input that, welcome to the administration panel ..

In The End, Sanitize

If you do not that to happen to your programs, make sure that you check what the user has inputted. First of all, escape special characters. Quotes should always be escaped for instance. Take a look at magic quotes for mysql. Then, also make sure that if you need a numeric value, never accept strings. Limit user input and guess what their “out of the ordinary” input can be. Play safe to be safe.


Spyros