Understanding the full potential of sqlmap during bug bounty hunting
11 minutes to read
Swiss army knife for SQL Injection attacks, sqlmap was first developed in 2006 by Daniele Bellucci and later maintained by Bernardo Damele and Miroslav Stampar.
Its early development took off thanks to the OWASP Spring of Code 2007 and was first under the serious media coverage during the Black Hat Europe 2009 conference. If you are interested in more dates and early milestones, I highly recommend checking the History page on the official Wiki. It's worth to mention that there is also a fairly recent interview with Miroslav Stampar by The Daily Swig.
Next-gen SQL injection opens server door; A vulnerability estimated to affect more than 1 in 10 websites could go lethal with the finding that it can be used to reliably take complete control of the site's underlying server.TheRegister.co.uk - Dan Goodin, 2 Apr 2009
Stable version 1.0 was released ten years later on Feb 27, 2016 and with continuous releases even to this day, sqlmap is number one tool for detecting and exploiting SQL injection flaws.
So what exactly is sqlmap?
sqlmap is an open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of database servers. It comes with a powerful detection engine, many niche features for the ultimate penetration tester and a broad range of switches lasting from database fingerprinting, over data fetching from the database, to accessing the underlying file system and executing commands on the operating system via out-of-band connections.
- Website: http://sqlmap.org/
- GitHub: https://github.com/sqlmapproject/sqlmap
- Twitter: https://twitter.com/sqlmap
- Wiki: https://github.com/sqlmapproject/sqlmap/wiki
- YouTube: https://www.youtube.com/user/inquisb/videos
I'm not by any means an expert on SQL Injection attacks, but I have been using this tool for several years and thought that it would nice to share some tips & tricks with you. If you are in the web security field, it's necessary to understand the fundamentals of how SQLi works and everyone should be able to exploit this vulnerability manually. On the other hand, automation is the new trend :)
The thing is, I saw numerous questions from the students/newbies in the bug bounty industry and if you are just blindly pasting URLs into the sqlmap, you are doing something wrong!
Sometimes people are passing the vulnerabilities that are there because they won't get the hit on the first try and just move on. I won't help you understand how SQL injection works, but this post can help you understand how to use the tool ... Hope this won't be super long in the end.
If you ever read the Usage manual, there are so many options, switches, and features. I won't probably go over all of them, I will instead focus on the most common usage, some misconceptions, and recommendations. Overall, most of the readers are probably interested in bug bounty hunting and this is meant to be a guide for them, so if you are already experienced in the game, you can stop right here and save yourself some precious time :)
It's probably a good idea to preface this with an official sqlmap disclaimer:
Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program[!] legal disclaimer
The first thing is to specify the URL for testing, you can do that with
--url parameter (
-r for saved request):
$ sqlmap -u "http://0.0.0.0:1234/?id=2"
By default, sqlmap performs HTTP requests with the user-agent like:
sqlmap/1.2.4#stable (http://sqlmap.org), which can get you blocked by some firewalls even before you start. So the next step is to change it to something more real. There are three options on how to do that, you can either specify custom user-agent header with
, use random one
or even imitate smartphone with
$ sqlmap -u "http://0.0.0.0:1234/?id=2" --random-agent
Protip: use SQLMAP_RANDOMAGENT environment variable to always use random user-agent:
$ echo "export SQLMAP_RANDOMAGENT=1" >> ~/.bash_profile && source ~/.bash_profile
You can do more tunning like this, just look into
/etc/sqlmap/sqlmap.conf for some inspiration ...
Even if some researchers are against it, there are bug bounty programs like Goldman Sachs or Verizon that will award you a bonus if you play nice and specify a custom identifiable header like
X-Bug-Bounty:HackerOne-username. You can do it easily with
$ sqlmap -u "http://0.0.0.0:1234/?id=2" --headers="X-HackerOne:username"
And most importantly, with a rising number of researchers and automated tools or scans, it is wise to follow the rules and limit your requests per second according to each program's policy. The last thing you want to do is to cause some infrastructure disturbances, outages or get yourself banned. If the program allows max 5 req/s, you can specify the
between each request to 200 milliseconds:
$ sqlmap -u "http://0.0.0.0:1234/?id=2" --delay=0.2
With the info said above, there shouldn't be any reason to increase the number of
--threads during bug bounty hunting unless you know what you are doing or don't care at all. There is also an option to create custom configuration files and use them with
-c based on your needs, for example:
$ sqlmap -u "http://0.0.0.0:1234/?id=2" -c ~/sqlmap.ini $ cat ~/sqlmap.ini [Target] [Request] delay = 0.2 randomAgent = True headers = X-HackerOne: username
This can be rather useful mainly while doing bug bounty hunting through own SOCKS5 proxy and don't want to configure it each time. Crafting the specific config according to your own needs will benefit you a lot in a long turn.
If you are hunting for bugs only with Burp Suite Community Edition, you can also leverage some advantages to be able to effectively find SQLi vulnerabilities. Most of you probably already know about the Burp SQLiPy extension, or open-source tools leveraging sqlmap API like SQLiScanner or SQLi-Hunter.
I would like to show you another useful feature. Let's say that you are browsing the target web application with Burp Suite and have a bunch of requests in Burp's HTTP history. You can select everything with CRTL+A, then continue with a right-click and "Save items" option. Just like this, it is possible to export the whole HTTP history as an XML file, for example: "burp_history.xml". With sqlmaps'
-l option, just specify the log file:
$ sqlmap -l burp_history.xml
Don't forget that you should always stay in scope of the program, it can be done with
--scope option (regex):
$ sqlmap -l burp_history.xml --scope="0.0.0.0:1234"
With the examples above, it is easy to follow the rules of a bug bounty program and at least somehow automate the SQLi testing, but speaking about automation, it's not finished without the notifications. There is
switch which will make a sound when SQLi is found, but nowaday everything is running in the cloud, so this is not an option. Thankfully, there is another
--alert option, which will run host OS command(s) when SQL injection is found. Basically in my scenario, it will run a simple bash script to send me a Telegram notification, this can be easily changed to webhook/slack/discord message ...
The thing that was bothering me the most, if I'm running a lot of different scans, how the bash script can differentiate between them. For example, each scan can have unique identification ID, but it would be cool if the bash script could notify me with the whole sqlmap command with all the parameters used. After a lot of trial/error bash fu, I came up with the following solution:
$ sqlmap -u "http://0.0.0.0:1234/?id=2" --alert="./sqli2telegram.sh $$"
And the terrible bash script itself:
#!/bin/bash command="$(ps -f | grep [email protected] | grep sqlmap | ps ww -o cmd= -p $(cut -d' ' -f 2))" date="$(date "+%d %b %Y %H:%M")" #Collect date & time. text="<b>SQLi found !</b>%0A <i>$date</i>%0A <code>$command</code>" # Telegram: user="***SECRET***" key="***SECRET***" url="https://api.telegram.org/bot$key/sendMessage" curl -s --max-time 10 -d "chat_id=$user&disable_web_page_preview=1&parse_mode=html&text=$text" $url > /dev/null
This is not the best solution at all and might cause some issues, but only your imagination is a limit, perhaps people will share any ideas on how to do things better. The whole command with all the mentioned examples might look like this:
$ sqlmap -c ~/sqlmap-config.ini -l ~/burp-history.xml --scope="0.0.0.0:1234" --batch --alert="~/sqli2telegram.sh $$"
--batch option will tell the sqlmap to never ask for user input and always use the default behavior. There is a ton of other useful features, it is always recommended to experiment and find what will suit you the best.
For the testing, I highly recommend to use DSVW (Damn Small Vulnerable Web), also authored by Miroslav Stampar :) By running
docker run -p 1234:8000 -it appsecco/dsvw you will have end-points for all interesting vulnerabilities, including SQLi. I'm putting together a list of another awesome vulnerable applications, but it's not done yet, help is always welcomed ...
While testing for SQLi, don't forget that every user input might be vulnerable. There might be a vulnerability in cookies, headers like referer, host etc. Quite recently on /r/bugbounty, I released a CTF challenge to celebrate 5k subscribers. The solution was blind SQLi in insert (sqlite database), and the vulnerable parameter was user-agent. It took a bunch of researchers a lot of hours and tens/hundreds of thousands of requests to find it. It could be found quite easily just with running sqlmap and increasing
--risk options and speed up fingerprinting and specifying the right database. Always try harder and look beyond the low hanging fruits!
PS: I forgot to mention the tamper scripts :(