quinta-feira, 23 de junho de 2016

Exploiting SQL Injection by Bypassing WAF (Mod_Security)

Since years, SQL Injections have been the most dreadful and frightening of all vulnerabilities discovered till date. The power of a single quote (') is beyond comparison. SQL injection attacks were first discovered in 1998, with one of the first live attacks taking place in 2002 on the fashion retailer Guess and the rest is History. Billions of Dollars and reputations have been lost. In spite of implementing multiple forms of fixes, it’s a never ending war between developers and hackers. If the former comes up with a way to prevent it, the latter comes up with a way to bypass it.
The blog focuses on providing in-depth insights into the discussion of the techniques used to bypass one of such prevention methods. This blog will not help you to learn the basics of SQL Injection; so I would recommend you to go through OWASP before even thinking about jumping into advanced techniques. This blog is more focused on bypassing Mod_Security (Web Application Firewall) and eventually exploiting SQL Injection vulnerability. 
The Attack:
First and foremost, we need to find our target website. In this case I am using:

Looks perfect! Right? Now let's try to insert a single quote at the end of the URL and observe what happens:

Hmmm!! Different response!
The page appears but no data. So something did happen but still we don’t have a confirmation whether SQL Injection exists or not. Let's modify our query a bit to see how the application responds.
http://targetsite.com/demo/exams.php?sort=8' or 1=1--

Normally in a vulnerable website the above query would return values from the entire table since the Boolean condition is always true. Let's see how this website responds:

It seems like our target website has a WAF implemented to prevent itself from being targeted. So, if I am not wrong, any attacks directed towards the database will be blocked by Mod_Security.
Well in some cases, it is possible to block such attacks if you have the implementation done correctly with an up-to-date version of WAF being used and regular update of security patches being rolled out.
But then again, aren't we hackers? We don't give up, do we? Let's try to get around it. Sounds intriguing? Let's play.
First we need to make some queries work just to be sure that SQL Injection indeed exists.
Finding the Number of Columns:
Till now I would say that we are kinda hacking in the dark. No real MySQL errors which actually proved the presence of SQL Injection. The only success we had was when we used a single quote in the above mentioned URL and received a blank page in response…no rows…no data. This can however mean that we somehow managed to change the structure of the underlying query and the page might be vulnerable to SQL Injection. Let's try and get some confirmation.
Finding the number of columns present in the current database might actually prove its presence. This can be achieved by using a simple "ORDER BY" clause.
http://targetsite.com/demo/exams.php?sort=8 ORDER BY 1-- 

No Error! Expected Response! Cool…there's Hope after all….
Let's proceed further…
http://targetsite.com/demo/exams.php?sort=8 ORDER BY 2--           No Error
http://targetsite.com/demo/exams.php?sort=8 ORDER BY 3--           No Error
http://targetsite.com/demo/exams.php?sort=8 ORDER BY 4--           No Error
http://targetsite.com/demo/exams.php?sort=8 ORDER BY 5--           No Error
http://targetsite.com/demo/exams.php?sort=8 ORDER BY 6--           No Error
http://targetsite.com/demo/exams.php?sort=8 ORDER BY 7--           No Error but a Blank Page

As seen above, ORDER BY 7-- query generated a different response thereby proving the existence of 6 columns in the current database. We were lucky though since the WAF did not block the 'ORDER' keyword. We need that sometimes!
However, since now we know the number of columns in use; let’s see which columns get displayed in the response.

OOPS! Mod_Security again!
So I guess the filter has been set on 'UNION' and 'SELECT' keywords. So now it's time to actually bypass the WAF (since we've had enough of it) by modifying the query and force the backend database to exfiltrate data as we desire.
Bypassing WAF:
Let's try the modified query below:

It seems like the 3rd, 4th and 6th columns are being displayed. Now we can use SQL Injection to extract data and display them on the above displayed columns
Let's extract our first GOLDEN PRIZED data by finding out the MySQL version and the current database user.
http://targetsite.com/demo/exams.php?sort=8+/*!50000union*/+/*!50000select*/+1,2, current_user(),@@version,5,6--+

Extracting Data from Database:
Since we know it’s a MYSQL database, we also know that there are some globally defined database tables, columns and schema. The names and hierarchies are as follows:
·         information_schema - name of the meta-database in MYSQL which has the following table
Ø columns - is the table name in the information_schema which in turn has the following columns inside
ü       table_name - all tables in all databases
ü       column_name - all columns in all the tables of all the databases
ü       table_schema - all databases in server
Now let’s use this to get some data.

Anything interesting? 'users' table seems to be interesting!
Let's query it further to see what kind of columns it has.

I guess we reached the 'orgasmic' point where the next step could lead you to a complete different level. Imagine having a list of all the usernames and passwords at your disposal and especially if you have the ADMIN creds. Well I am not saying anything but you are intelligent enough to make use of it. So ready for your final attempt? Here we GO

The data that I am most interested in is:
Looks like a SHA-1 Hash which finally resolves to 'pass' once reversed. So the final value:

Username: admin
Password: pass

Do I need to tell you what to do next!! Just go find the GOD DAMN admin console and do whatever you wanna do. My Job here is done. See you again. Till then
Hasta la vista