SQL Injection with SQL Map and bypassing JavaScript filters.
This post will go through what is required for a basic SQL Injection as well as how to bypass input filters enforced by javascript.
What is SQL injection?
SQL injection is a technique used to manipulate a back end database by inputting specially crafted sql syntax into an input field and causing the back end database to run it. The most basic of injections and usually the first one you should try once you have found an injection point is simply admin' or 1=1 -- If you put this into a user name field the query that results is: SELECT * FROM users WHERE username = 'admin'' or 1=1 -- As you can see the username is closed off with the extra ' and then checks if 1=1 which it does and then comment out the rest of the query with -- to cancel the password check. So basically its saying if the username is admin OR if 1 = 1 log me in. This is if the database is mysql which is very common. Their are cheat sheets available for every database out there if this command does not work or it is not a MySQL database.
SQL is a huge topic and there are many different types of injections. The above is the most simplest and easiest to understand the concept. This post should give you an idea of how complex injections can get. Im currently waiting for the book "SQL Injections, Attacks and defence." by Justin Clarke to arrive in the mail so I can get a better grip on the more advanced injections that sqlmap may not pick up.
SQL Injection can be used for updating a database with new users and changing passwords, deleting data, bypassing logins, accessing and downloading databases and even completely compromising the underlying system.
How does this happen?
Injections happen when user input is not "sanitized", meaning any sql syntax is not filtered out so it gets interpreted by the database as a legitimate query. To avoid injections you should always sanitized and filter any user input on every single field that is interacting with a database. Even cookies and hidden fields.
I will cover the Javascript filter bypass as I go through the attack.
For this attack I will be using the vulnerable web app "Mutillidae". It can be downloaded from:
Il be using the vulnerable login screen located under: Owasp 2013, A1 Injection(SQL), SQLi Bypass Authentication. I have also set the security level to Arrogent to enable the javascript filter.
Usually the first way to check for an injection point is to simply add the ' character. This closes off the statement and should result in an error if input is not sanitized. In this case the javascript filter is attempting to block the character.
And important thing to note here is blacklisting is BAD because there are so many other characters that can get around and be used for the same purpose as the characters being blocked. If you do ever need to block characters, use a white list and white list the allowed characters so every other character is blocked by default. That stops the almost unlimited possibilities of bypassing a blacklist.
Ok so this is clearly javascript causing this alert so if we take a look at the source code we find the code that is doing this:
Its doing two checks here. The first is checking if the input length is greater than 15. And the second is the blacklist.
The most simplest way to get around this by turning off JavaScript... Its literally that easy to get around javascript filters... However a more elegent way is to send a valid request and catch it after the java has run but before it has been sent to the server ;)
To do this we use an intercepting proxy to catch every request we make. That way we can alter it after any javascript has been run and then send it on its way. The proxy I will be using is Burp Suite. Simply run burp and configure your browsers proxy to 127.0.0.1:8080. Enter allowed characters into the login, turn on intercept in burp and login:
Burp will catch it after the java filter has checked your input. Now you can add the ' after the username. Forward the request and check if you receive an error. Note, that in the event you do not receive an error that does not mean the application is not still vulnerable. It may just be filtering out the errors and returning you back to the login page. You may be able to still use other techniques such as BLIND injection to exploit it.
The ' character did confuse the database and caused it to throw us an error. This error gives us quite a lot of information about the back end database. We have a full path disclosure:
/var/www/mutillidae/classes/MySQLHandler.php
The database version:
client_info: 5.5.40
That is running on Unix
host_info: Localhost via UNIX socket
The Database is MySQL
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 ''asadf''' at line 1
The table that holds the username information and the database:
Query: SELECT username FROM accounts WHERE username='asadf''; (0) [Exception]
So after that very informative error we know the database is MySQL and that it is vulnerable to injection. So as I stated at the start of this post the first query we should try is admin' or 1=1 -- Two things to note here is that admin can be anything and there needs to be a space after -- . Again catch a request to bypass the filter and change the username.
I did have to play with the syntax a bit. The one that worked was the one above. Adding spaces between each character did the trick. The query that got send to the server was:
SELECT username FROM accounts WHERE username='admin'' or 1 = 1 -- ; This returned true and let us in :)
Our result:
In this case injection was used to bypass the login and get admin access. If you performed this on a page where you where viewing your account or changing a password you may end up changing everyones password, or viewing everyones account.
Introducing SQLMap
So what if you want more than just accessing the admin account or some
usernames and passwords? What if you know there are more databases on
the system and cant access them via manual injection? And what if all of
your manual techniques have failed or are very slow? This is where
sqlmap comes in. SQLMap is an extremely powerful tool and does have the
ability for misuse by script kiddies. SQLmap automates every type of injection and can perform infinite amounts of techniques multiple times a second. SQLMap was written by: Bernardo Damele and Miroslav Stampar and can be downloaded from:
http://sqlmap.org/
SQLMap is used via the console. Type in sqlmap -hh to get a list of options.
You will get a list of all of the options available to you. There are a lot and they are all well worth researching and learning if you want to use this tool effectively. It even includes a wizard for new users to use. sqlmap --wizard.
The way I will be using sql map is by saving my login request that I caught in burp. Simply login to your mutillidae login again and catch the request then right click and choose save to file. After you have done that run this command:
sqlmap -r ~/Desktop/mutilInject -p username --dbms mysql --dbs
-r = your request file you saved from the burp capture. The -r stands for request. -p is the username field. --dbms specifies the database since we found that in our initial injection test. --dbs means if you find an injection tell me all of the databases on the system. The other common option to save you using a saved request is to specify the url with -u instead of -r.
If you require anonymity you can go through the tor network by starting TOR service and adding the commands --use-tor --tor-type SOCKS5 --check-tor
I chose to add a random user agent so it randomizes my browser a bit.
Once you run the command it will go off and test different types of injections on the username field. As you can see it found that it is vulnerable to AND error based injection. A good practice is to turn up the verbosity with -v 6 so you can see exactly what it is doing and what queries it is trying so you can get a better understanding of every injection technique. -v has options 1 to 6 depending on how much you want to see. Here is a screen shot of a UNION attack with the verbosity turned to 3:
If you know what the application is vulnerable too you can specify what type of attack to use with the --technique U switch. In that case the U means UNION. By default sqlmap will check for every type of attack.
So as its found an injection there is no need to continue looking for more. After pressing N we can see the databases returned to us from the --dbs command.
We have 5 databases on this server. The one we want is the Muttilidae one which is nowasp. So now we have choses our database and we want to see what information is inside it:
sqlmap -r ~/Desktop/mutilInject --random-agent -p username --dbms mysql -D nowasp --tables
-D selects the database nowasp and --tables enumerates all of the tables inside it. After running the command we get the table listing:
Interesting that there is a table called "credit_cards". We could enumerate all of the columns inside the table with -D nowasp -T credit_cards --columns but lets just go ahead and download that entire table instead.
sqlmap -r ~/Desktop/mutilInject --random-agent -p username --dbms mysql -D nowasp -T credit_cards --dump
The --dump by default dumps into a csv file. After it completes sqlmap displays the dumped table onto the screen and lets you know where it saved the csv:
All of this was possible from a single input field that did not sanitize its input... Now if you think this is bad enough, it is sometimes possible to upload a meterpreter shell onto the box and completely own the entire network. All of this from one vulnerable input field... This screen shot shows some of the more destructive commands you could use.