This is my first tutorial on web-security related topic. I chose SQLmap because it is one of the most used tools but also not so well known by those new to the security domain. And also I wanted to learn it in more depth than the superficial knowledge I had.
What is SQLmap?
From the original website:
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.
Alright, let’s go through some definitions here. There are a lot of good terms that we should get to know more.
A penetration test, aka pen test or ethical hacking, is an authorized simulated cyber-attack on a computer system, performed to evaluate the security of the system. In other words, the objective is to find vulnerabilities on a system. This information is to be shared with the owner of that system, possibly along with recommendations on how to remove them.
This is an ethically better word for hacking 🙂
Aka sqli, this is a technique used to identify application vulnerability that allows to execute SQL code directly on the database behind that application. It consists of finding ways to inject carefully crafted data so it bypasses the application validation, or identify the lack of such. It can lead to possibly taking over a server with administrator privileges. We will go through many techniques in this tutorial.
In this context, database fingerprinting is the process of using specific SQL queries that would identify the type, name, version… of a database instance. With this information, the attacker can then craft more specific SQL queries to inject or exploit particular vulnerabilities. This can be achieve in multiple steps.
For example, by getting an application to display the database error messages can indicate the database type. Then the attacker can inject a query to extract the version from the database. With that information the attacker can create the specific SQL commands to obtain (hashed) credentials, execute shell commands on the host (if supported/enabled) create outbound connections, send emails (if supported)
Aka OOB connections, consists of using SQLi to have the database server initiate connections to a remote system. The connection can be DNS requests or HTTP. The idea is to include a payload to these requests that an attacker could use, by monitoring the network or by having the connections go to the attacker own servers.
For example, it is possible to inject a command that would make a DNS request to resolve a domain name to an IP address (even if it wouldn’t try to connect to it). The attacker would:
- attacker owns the domain attackerdomain.org and configure a DNS server for it and optionally an HTTP server that resolves *.attackerdomain.org
- select some useful data
- concat the data to data1.data2.dataX.attackerdomain.org
- use the above domain in the command that resolves DNS request
- retrieve the data from the DNS logs or HTTP server
There are many ways to do so, depending on your operating system. It is beyond the scope of this tutorial for the simple reason I have created a web-security tools docker container that can be run from any OS which support running Linux based container. Start the container by running the command:
docker run -it --name jsc-hack-tools jscdroiddev/jsc-hack-tools:latest bash
You can then run the command sqlmap with relevant options.
For the most basic test, all we need is a URL from the target system that takes at least one query string parameter. Let’s say
What we are going to test is whether the request parameter is vulnerable to SQLi. SQLmap is going to test all the known exploits on it. Run the command:
sqlmap -u 'https://authorized-target.com/someapi?id=3'
If SQLmap finds the query string parameter is injectable, it will display the different ways to do so:
If the parameter is in a
POST payload, you can use
sqlmap -u 'https://authorized-target.com/someapi' --data='id=3'
If there are multiple parameters but you want to only exploit a specific one (i.e. some parameters need a specific value) then you can add
Along came Web-Application Firewalls
Web-Application Firewall, aka WAFs, are application or hardware that analyze incoming requests to a web-application and perform some validation before authorizing the request to hit the web-application. Most popular ones are Akamai, Cloudflare, you might have met them in your activities.
The most basic checks are:
- the number of requests coming from an IP address or a user-agent
- the URI and query string (and POST payload for un-encrypted connections). A regex or pattern matching on typical SQLi terms (like the well-known
' OR '1'='1)
There are a few ways SQLmap can bypass these:
--randomagentin the command to generate a different User-Agent for each requests
- execute the tests with some time between each of them. SQLmap can detect if there is a WAF and will automatically decrease the number of requests per second or minutes to try and bypass the WAF restrictions
To minimize the risk to be detected, you can limit:
- the tests level: by default it is 1. You can set it between 1 and 5. At level 5 it will perform in-depth tests
- the risk level: by default it is 1. You can set is between 1 and 3. Higher number will increase the chance to detect vulnerabilities, but also the risk to be detected by a WAF
Let’s get some data
Once we know a query parameter is injectable, we can now ask perform more thorough tests. We could try and get the table names. Simply adding
--tables to the command gets the job done. Then running the command with
-T tablename --dump will retrieve the data from that table and dump it to the output.
SQLmap is a great tool, but it goes as far as it is told to do. Sometimes (read always 🙂 ) you will not find an injectable field. Don’t give up. Increase the logging level to be able to see the steps SQLmap is taking. By doing so, you will learn what requests and commands are performed by SQLmap. You might realize that it missed something and you could run the command yourself with
curl or so. Add
-v X with X between 0 and 6 to define the verbosity.
But wait! I have some intel…
As you do manual inspection of the victim system, you might want to test an endpoint that requires to be logged-in, or need a specific HTTP Header, or to go through a proxy.
You can add
Getting a remote shell
Once we have a vulnerable site, we can upload a shell by using the
sqlmap -u 'https://authorized-target.com/someapi?id=3' --dbms "mysql" --os-shell
You will be prompted to select the platform architecture, language/framework and file location. It will then display the URL you can access the shell on the browser where you can upload more files.
To be continued…
In the next tutorial we will look at how to use SQLmap to perform a penetration test on an authorized victim (a locally running docker image).
Penetration Test: https://en.wikipedia.org/wiki/Penetration_test