Enumeration | Optimization | Protection detection and bypass using "tamper" scripts |
Database content retrieval | File system access | Execution of the operating system (OS) commands. |
SQLMap has the largest support for DBMSes of any other SQL exploitation tool. SQLMap fully supports the following DBMSes:
MySQL |
Oracle |
PostgreSQL |
Microsoft SQL Server |
SQLite |
IBM DB2 |
Microsoft Access |
Firebird |
Sybase |
SAP MaxDB |
Informix |
MariaDB |
HSQLDB |
CockroachDB |
TiDB |
MemSQL |
H2 |
MonetDB |
Apache Derby |
Amazon Redshift |
Vertica , Mckoi |
Presto |
Altibase |
MimerSQL |
CrateDB |
Greenplum |
Drizzle |
Apache Ignite |
Cubrid |
InterSystems Cache |
IRIS |
eXtremeDB |
FrontBase |
The SQLMap team also works to add and support new DBMSes periodically. SQLMap is the only penetration testing tool that can properly detect and exploit all known SQLi types.
The technique characters BEUSTQ
refers to the following:
-
B
: Boolean-based blind: SQLMap exploitsBoolean-based blind SQL Injection
vulnerabilities through the differentiation ofTRUE
fromFALSE
query results, effectively retrieving 1 byte of information per request. The differentiation is based on comparing server responses to determine whether the SQL query returnedTRUE
orFALSE
. This ranges from fuzzy comparisons of raw response content, HTTP codes, page titles, filtered text, and other factors.-
TRUE
results are generally based on responses having none or marginal difference to the regular server response. -
FALSE
results are based on responses having substantial differences from the regular server response. -
Boolean-based blind SQL Injection
is considered as the most common SQLi type in web applications.
-
-
E
: Error-based: If thedatabase management system
(DBMS
) errors are being returned as part of the server response for any database-related problems, then there is a probability that they can be used to carry the results for requested queries. In such cases, specialized payloads for the current DBMS are used, targeting the functions that cause known misbehaviors. SQLMap has the most comprehensive list of such related payloads and coversError-based SQL Injection
for the following DBMSes:MySQL PostgreSQL Oracle Microsoft SQL Server Sybase Vertica IBM DB2 Firebird MonetDB Error-based SQLi is considered as faster than all other types, except UNION query-based, because it can retrieve a limited amount (e.g., 200 bytes) of data called "chunks" through each request.
-
U
: Union query-based: With the usage ofUNION
, it is generally possible to extend the original (vulnerable
) query with the injected statements' results. This way, if the original query results are rendered as part of the response, the attacker can get additional results from the injected statements within the page response itself. This type of SQL injection is considered the fastest, as, in the ideal scenario, the attacker would be able to pull the content of the whole database table of interest with a single request.
-
S
: Stacked queries: Stacking SQL queries, also known as the "piggy-backing," is the form of injecting additional SQL statements after the vulnerable one. In case that there is a requirement for running non-query statements (e.g.INSERT
,UPDATE
orDELETE
), stacking must be supported by the vulnerable platform (e.g.,Microsoft SQL Server
andPostgreSQL
support it by default). SQLMap can use such vulnerabilities to run non-query statements executed in advanced features (e.g., execution of OS commands) and data retrieval similarly to time-based blind SQLi types.
-
T
: Time-based blind: The principle ofTime-based blind SQL Injection
is similar to theBoolean-based blind SQL Injection
, but here the response time is used as the source for the differentiation betweenTRUE
orFALSE
.Time-based blind SQL Injection
is considerably slower than the boolean-based blind SQLi, since queries resulting inTRUE
would delay the server response. This SQLi type is used in cases whereBoolean-based blind SQL Injection
is not applicable.
-
Q
: Inline queries: This type of injection embedded a query within the original query. Such SQL injection is uncommon, as it needs the vulnerable web app to be written in a certain way. Still, SQLMap supports this kind of SQLi as well. Out-of-band SQL Injection: This is considered one of the most advanced types of SQLi, used in cases where all other types are either unsupported by the vulnerable web application or are too slow (e.g., time-based blind SQLi). SQLMap supports out-of-band SQLi through "DNS exfiltration," where requested queries are retrieved through DNS traffic.
Getting Started with SQLMap
1.Basic Listing
shows only the basic options and switches, sufficient in most cases (switch -h
)Advanced Listing
shows all options and switches (switch -hh
)the switch '--batch' is used for skipping any required user-input, by automatically choosing using the default option.
SQLMap Output Description
- "target URL content is stable" ,
- "GET parameter 'id' appears to be dynamic"
- "GET parameter 'id' might be injectable"
- "parameter 'id' might be vulnerable to cross-site scripting (XSS) attacks"
- "it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n]"
- "for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n]"
- "GET parameter 'id' appears to be 'AND boolean-based blind - WHERE or HAVING clause' injectable (with --string="luther")"
with --string="luther"
indicates that SQLMap recognized and used the appearance of constant string value luther
in the response for distinguishing TRUE
from FALSE
responses. This is an important finding because in such cases, there is
no need for the usage of advanced internal mechanisms, such as
dynamicity/reflection removal or fuzzy comparison of responses, which
cannot be considered as false-positive. - "time-based comparison requires a larger statistical model, please wait........... (done)"
- "automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found"
- "ORDER BY' technique appears to be usable. This should reduce the time needed to find the right number of query columns. Automatically extending the range for current UNION query injection technique test"
As a heuristic check for the UNION-query SQLi type, before the actual UNION
payloads are sent, a technique known as ORDER BY
is checked for usability. In case that it is usable, SQLMap can quickly recognize the correct number of required UNION
columns by conducting the binary-search approach.
- "GET parameter 'id' is vulnerable. Do you want to keep testing the others (if any)? [y/N]"
This is one of the most important messages of SQLMap, as it means that the parameter was found to be vulnerable to SQL injections. In the regular cases, the user may only want to find at least one injection point (i.e., parameter) usable against the target. However, if we were running an extensive test on the web application and want to report all potential vulnerabilities, we can continue searching for all vulnerable parameters.
- "sqlmap identified the following injection point(s) with a total of 46 HTTP(s) requests:"
Following after is a listing of all injection points with type, title, and payloads, which represents the final proof of successful detection and exploitation of found SQLi vulnerabilities. It should be noted that SQLMap lists only those findings which are provably exploitable (i.e., usable).
- "fetched data logged to text files under '/home/user/.sqlmap/output/www.example.com'"
www.example.com
.
After such an initial run, where the injection point is successfully
detected, all details for future runs are stored inside the same
directory's session files.Running SQLMap on an HTTP Request
SQLMap has numerous options and switches that can be used to properly set up the (HTTP) request before its usage. In many cases, simple mistakes such as forgetting to provide proper cookie values, over-complicating setup with a lengthy command line, or improper declaration of formatted POST data, will prevent the correct detection and exploitation of the potential SQLi vulnerability.
- Curl Commands: One of the best and easiest ways to properly set up an SQLMap request
against the specific target is by utilizing
Copy as cURL
feature from within the Network (Monitor) panel inside right click the url and copy value and copy url to curl posix every browser is same Chrome, Edge, or Firefox Developer Tools.
Copy as cURL
feature from within the Network (Monitor) panel inside right click the url and copy value and copy url to curl posix every browser is same Chrome, Edge, or Firefox Developer Tools.Ctrl-V
) into the command line, and changing the original command curl
to sqlmap
, we are able to use SQLMap with the identical curl
command:- GET/POST Requests: In the most common scenario,
GET
parameters are provided with the usage of option-u
/--url
, as in the previous example. As for testingPOST
data, the--data
flag can be used, as follows: sqlmap 'http://www.example.com/' --data 'uid=1&name=test' - In such cases,
POST
parametersuid
andname
will be tested for SQLi vulnerability. For example, if we have a clear indication that the parameteruid
is prone to an SQLi vulnerability, we could narrow down the tests to only this parameter using-p uid
. Otherwise, we could mark it inside the provided data with the usage of special marker*
as follows: sqlmap 'http://www.example.com/' --data 'uid=1*&name=test'
- Full HTTP Requests: If we need to specify a complex HTTP request with lots of different header values and an elongated POST body, we can use the
-r
flag. With this option, SQLMap is provided with the "request file,"
containing the whole HTTP request inside a single textual file. In a common scenario, such HTTP request can be captured from within a specialized proxy application (e.g. Burp
) and written into the request file. An example of an HTTP request captured with Burp
would look like: - GET /about_en.php?id=2 HTTP/1.1
- Host: www.uni-1.com.hk
- Cache-Control: max-age=0
- Upgrade-Insecure-Requests: 1
- User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36
- Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
- Accept-Encoding: gzip, deflate, br
- Accept-Language: en-US,en;q=0.9,bn;q=0.8
- Connection: keep-alive
-r
flag. With this option, SQLMap is provided with the "request file,"
containing the whole HTTP request inside a single textual file. In a common scenario, such HTTP request can be captured from within a specialized proxy application (e.g. Burp
) and written into the request file. An example of an HTTP request captured with Burp
would look like: - Custom SQLMap Requests: If we wanted to craft complicated requests manually, there are numerous switches and options to fine-tune SQLMap. if there is a requirement to specify the (session) cookie value to. like
- PHPSESSID:tsp9mv599geou4radthsh1s6r5 option
--cookie
would be used as follows:
The same effect can be done with the usage of option -H/--header
: sqlmap ... -H='Cookie:PHPSESSID=ab4530f4a7d10448457fa8b0eadac29c'
We can apply the same to options like --host
, --referer
, and -A/--user-agent
, which are used to specify the same HTTP headers' values. Furthermore, there is a switch --random-agent
designed to randomly select a User-agent
header value from the included database of regular browser values.Also, if we wanted to specify an alternative HTTP method, other than GET
and POST
(e.g., PUT
), we can utilize the option --method
, as follows:
--cookie
would be used as follows: The same effect can be done with the usage of option -H/--header
: sqlmap ... -H='Cookie:PHPSESSID=ab4530f4a7d10448457fa8b0eadac29c'
--host
, --referer
, and -A/--user-agent
, which are used to specify the same HTTP headers' values. Furthermore, there is a switch --random-agent
designed to randomly select a User-agent
header value from the included database of regular browser values.sqlmap -u www.target.com --data='id=1' --method PUT
- Custom HTTP Requests: Apart from the most common form-data
POST
body style (e.g. id=1
), SQLMap also supports JSON formatted (e.g. {"id":1}
) and XML formatted (e.g. <element><id>1</id></element>
) HTTP requests.
POST
body style (e.g. id=1
), SQLMap also supports JSON formatted (e.g. {"id":1}
) and XML formatted (e.g. <element><id>1</id></element>
) HTTP requests.Handling SQLMap Errors
We may face many problems when setting up SQLMap or using it with
HTTP requests. In this section, we will discuss the recommended
mechanisms for finding the cause and properly fixing it. With this option, SQLMap will automatically print the DBMS error,
thus giving us clarity on what the issue may be so that we can properly
fix it. The -t
option stores the whole traffic content to an output file: sqlmap -u "http://www.target.com/vuln.php?id=1" --batch -t /tmp/traffic.txt. As we can see from the above output, the /tmp/traffic.txt
file now contains all sent and received HTTP requests. So, we can now
manually investigate these requests to see where the issue is occurring. Another useful flag is the -v
option, which raises the verbosity level of the console output:sqlmap -u "http://www.target.com/vuln.php?id=1" -v 6 --batch, As we can see, the -v 6
option will directly print all
errors and full HTTP request to the terminal so that we can follow along
with everything SQLMap is doing in real-time. Finally, we can utilize the --proxy
option to redirect the whole traffic through a (MiTM) proxy (e.g., Burp
). This will route all SQLMap traffic through Burp
, so that we can later manually investigate all requests, repeat them, and utilize all features of Burp
with these requests.
Attack Tuning
-
vector (e.g.,
UNION ALL SELECT 1,2,VERSION()
): central part of the payload, carrying the useful SQL code to be executed at the target. -
boundaries (e.g.
'<vector>-- -
): prefix and suffix formations, used for proper injection of the vector into the vulnerable SQL statement.
--prefix
and --suffix
can be used as follows: sqlmap -u "www.example.com/?q=test" --prefix="%'))" --suffix="-- -" %'))
and the suffix -- -
.--level=1 --risk=1
), the number of payloads used for testing a single parameter goes up to 72, while in the most detailed case (--level=5 --risk=3
) the number of payloads increases to 7,865. As SQLMap is already tuned to check for the most common boundaries and
vectors, regular users are advised not to touch these options because it
will make the whole detection process considerably slower.
Nevertheless, in special cases of SQLi vulnerabilities, where usage of OR
payloads is a must (e.g., in case of login
pages), we may have to raise the risk level ourselves. Database Enumeration
--hostname
), current user's name (--current-user
), current database name (--current-db
), or password hashes (--passwords
). SQLMap will skip SQLi detection if it has been identified earlier and directly start the DBMS enumeration process.Enumeration usually starts with the retrieval of the basic information:
- Database version banner (switch
--banner
) - Current user name (switch
--current-user
) - Current database name (switch
--current-db
) - Checking if the current user has DBA (administrator) rights (switch
--is-dba
)
In most common scenarios, after finding the current database name (i.e. testdb
), the retrieval of table names would be by using the --tables
option and specifying the DB name with -D testdb
, is as follows.
After spotting the table name of interest, retrieval of its content can be done by using the --dump
option and specifying the table name with -T users
, as follows. --dump -T users -D testdb.
When dealing with large tables with many columns and/or rows, we can specify the columns (e.g., only name
and surname
columns) with the -C
option, as follows. --dump -T users -D testdb -C name,surname. To narrow down the rows based on their ordinal number(s) inside the table, we can specify the rows with the --start
and --stop
options (e.g., start from 2nd up to 3rd entry), as follows. --dump -T users -D testdb --start=2 --stop=3. If there is a requirement to retrieve certain rows based on a known WHERE
condition (e.g. name LIKE 'f%'
), we can use the option --where
, as follows: --dump -T users -D testdb --where="name LIKE 'f%'". As for the --dump-all
switch, all the content from all the databases will be retrieved.
Advanced Database Enumeration
Now that we have covered the basics of database enumeration with
SQLMap, we will cover more advanced techniques to enumerate data of
interest further in this section. If we wanted to retrieve the structure of all of the tables so that
we can have a complete overview of the database architecture, we could
use the switch --schema
: sqlmap -u "http://www.example.com/?id=1" --schema.
When dealing with complex database structures with numerous tables and
columns, we can search for databases, tables, and columns of interest,
by using the --search
option. This option enables us to search for identifier names by using the LIKE
operator. For example, if we are looking for all of the table names containing the keyword user
, we can run SQLMap as follows: sqlmap -u "http://www.example.com/?id=1" --search -T user
Once we identify a table containing passwords (e.g. master.users
), we can retrieve that table with the -T
option. -D master
: Specifies the database. sqlmap -u "http://www.example.com/?id=1" --dump -D master -T users.
Tip: The '--all' switch in combination with the '--batch' switch, will automa(g)ically do the whole enumeration process on the target itself, and provide the entire enumeration details.
Bypassing Web Application Protections
WAF Bypass: Whenever we run SQLMap, As part of the initial tests, 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). There will be a substantial change in the response compared to the
original in case of any protection between the user and the target. 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. In case of a positive detection, to identify the actual protection mechanism, SQLMap uses a third-party library identYwaf,
containing the signatures of 80 different WAF solutions. If we wanted
to skip this heuristical test altogether (i.e., to produce less noise),
we can use switch --skip-waf
. --skip-waf --tamper=between,charencode --random-agent --dump.
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. 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.
IP Address Concealing: In case we want to conceal our IP address, or if a certain web
application has a protection mechanism that blacklists our current IP
address, we can try to use a proxy or the anonymity network Tor. A proxy
can be set with the option --proxy.
In addition to that, if we have a list of proxies, we can provide them to SQLMap with the option --proxy-file
. This way, SQLMap will go sequentially through the list, in case of any problems (e.g., blacklisting of IP address), it will just skip from current to the next from the list. If we wanted to be sure that Tor is properly being used, to prevent unwanted behavior, we could use the switch --check-tor
.
OS Exploitation
Reading Local Files: SQLMap has the ability to utilize an SQL Injection to read and write files from the local system outside the DBMS. SQLMap can also attempt to give us direct command execution on the remote host if we had the proper privileges. 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. read local files, the DB user must have the privilege. While we do not necessarily need to have database administrator privileges (DBA) to read data, this is becoming more common in modern DBMSes. The same applies to other common databases. Still, if we do have DBA privileges, then it is much more probable that we have file-read privileges.
Checking for DBA Privileges: To check whether we have DBA privileges with SQLMap, we can use the --is-dba
option. like this: sqlmap -u "http://www.uni-1.com.hk/about_en.php?id=2" --is-dba. 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 it shows true this means we have DBA access. let's see one which has a access and DBA : true
so let's windows payload. it's maybe fix. let's another. here you can see we successfully read the file .
We have successfully retrieved the remote file.
Writing Local Files: When it comes to writing files to the hosting server, it becomes much
more restricted in modern DMBSes, since we can utilize this to write a
Web Shell on the remote server, and hence get code execution and take
over the server. 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:
OS Command Execution
xp_cmdshell
in Microsoft SQL Server. To get an OS shell with SQLMap, we can use the --os-shell
option, as follows:Error-based SQL Injection
, which we can specify with --technique=E
:Note: SQLMap first asked us for the type of language used on this remote server, which we know is PHP. Then it asked us for the server web root directory, and we asked SQLMap to automatically find it using 'common location(s)'. Both of these options are the default options, and would have been automatically chosen if we added the '--batch' option to SQLMap.
0 Comments
Thanks For your comment