Monday, January 21, 2008

Starting out with SQL injection

Let's jump right in. There are many different types of SQL injections. We'll begin with the simplest form.

A majority of websites have some form of login interface. You must log in to either see your account, get administrative priveleges, get user priveleges, and so on. You have a user name and password that you use to log in. How does it work.

Somewhere in the behind the scenes of the website there is a database. That database contains a whole bunch of tables. One of those tables list all the authorized users, or usernames, and in another column, it has the password that corresponds to that user. When you enter a username and password, the website may send a SQL query to the database. What it does is it takes the entered username and looks for it on the table containing the username/password information. Once it finds the row containing the username, it checks the other column to see if the password entered matches the one saved on that corresponding row. If it matches, it gives you the green light to access whatever you were trying to get to.

What does matches mean. It checks to see the value of the equation 'password entered=password saved'. If it does equal, then the equation is true. If it is different than the saved password, then the equation returns 'false'.

Here's where SQL injection comes in. I will not use real SQL language yet, becuase so far we don't really have to know what were doing, only how to do it and why it works. In more advanced injection, we will discuss correct syntax.

In simple form when you press the login button on the website after entering your username and password, here's what happens. Actually, here's what happens on vulnerable websites, which the majority today are not. The website takes your input and sticks it into a SQL query, like this: check.table.username.column.for.'username entered' and.match.with.'password entered'. This is not the actual language used, but this is what is essentially being sent.

First the SQL query will look in the username column for a row that returns 'true' for the equation 'username entered=username saved'. When it gets a 'true' value, it then sees if 'password entered=password saved' in that row. If all is true, you're in.

Now what if we were to type this for the username and password:

Username: x' OR 'x'='x
Password: x' OR 'x'='x

What gets sent to the SQL query? Instead of

check.table.username.column.for.'username entered' and.match.with.'password entered' it now reads:

check.table.username.column.for.'x' OR 'x'='x' and.match.with.'x' OR 'x'='x'

The blue text is exactly what we entered. What is happening here and what's all those apostrophes ('). What the satement now reads is - Check for a column that 'x=password saved' or that 'x'='x'. Well, 'x'='x' in every column on the table, because 'x'='x' always returns 'true', because the ARE equal. So the SQL query looks at the table and gets a 'true' return in the first row it looks at. 'True' because either 'username entered=username saved' or 'x=x'. So the SQL query moves on to check the password. Does 'password entered=password saved' or does 'x=x'. This query also returns 'true', since 'x' stills equals 'x'. Now the SQL query tells the website, 'Let this guy in, he's the real thing'. YOU'RE IN!!!!

The reason we put all those quotes (') in is because if you look at the original statement, the website pasted our input in between apostrophes. What we're doing is first putting one ' to close the first ', and then starting a new open quote for our 'x'='x' statement. We don't put a quote at the end, because there already is one there to close the original statement. We supplied the original statement with our own quote, and the other closing quote is there for us to use. Study the above statements and the difference between the quotes colored blue and the ones colored black, and you'll hopefully get what I'm talking about.

This only works with websites using SQL queries in this specific format. Although this vulnerability is well known, it amazes me how many websites haven't patched up their code to disallow this injection.

Please note as always. It is illegal to access a websites information that was not meant to be accessed. You are not allowed to log in without permission. You must be authorized by the website owner to enter. Therefore, only try this on websites that you own or that you got permission to enter. I, by no means, condone illegal entry. As I have explained many times before, I am only writing this article for 2 reasons. One, so that you will recognize the vulnerability and patch up your own site. Two, because hacking is a science like any other, and I and many others love this knowledge as an end on it's own.

To find websites that may be vulnerable, you may want to search google for this:

inurl:login.asp
or inurl:admin/login.asp

Disclaimer again: Only try to inject into a website after you have contacted the website administrator and got permission, preferably in writing. The sites returned with the second search above have a greater chance of giving you full administrators rights on a site. Therefore, please be responsible and don't mess with anything you shouldn't be. You may also want to use a proxy when accessing these sites, but since you got permission, there's no need for that.

We'll be in touch

1 comment:

SQL training said...

Can I do this to any sites?