Building Attacks
Last updated
Last updated
Replace the curl command
with sqlmap
When providing data for testing to SQLMap, there has to be either a parameter value that could be assessed for SQLi vulnerability or specialized options/switches for automatic parameter finding (e.g. --crawl
, --forms
or -g
).
In the most common scenario, GET
parameters are provided with the usage of option -u
/--url
, as in the previous example. As for testing POST
data, the --data
flag can be used, as follows:
In such cases, POST
parameters uid
and name
will be tested for SQLi vulnerability. For example, if we have a clear indication that the parameter uid
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:
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, as follows:
To run SQLMap with an HTTP request file, we use the -r
flag, as follows:
If we wanted to craft complicated requests manually, there are numerous switches and options to fine-tune SQLMap.
For example, if there is a requirement to specify the (session) cookie value to PHPSESSID=ab4530f4a7d10448457fa8b0eadac29c
option --cookie
would be used as follows:
The same effect can be done with the usage of option -H/--header
:
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
While SQLMap, by default, targets only the HTTP parameters, it is possible to test the headers for the SQLi vulnerability. The easiest way is to specify the "custom" injection mark after the header's value (e.g. --cookie="id=1*"
). The same principle applies to any other part of the request.
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:
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
--batch
and --dump
are useful flags. The first will run all default options and the second will dump the possible tables.
The first step is usually to switch the --parse-errors
, to parse the DBMS errors (if any) and displays them as part of the program run
The -t
option stores the whole traffic content to an output file:
Another useful flag is the -v
option, which raises the verbosity level of the console output:
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
In most cases, SQLMap should run out of the box with the provided target details. Nevertheless, there are options to fine-tune the SQLi injection attempts to help SQLMap in the detection phase. Every payload sent to the target consists of:
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.
There is a requirement for special prefix and suffix values in rare cases, not covered by the regular SQLMap run.
For such runs, options --prefix
and --suffix
can be used as follows:
By default, SQLMap combines a predefined set of most common boundaries (i.e., prefix/suffix pairs), along with the vectors having a high chance of success in case of a vulnerable target. Nevertheless, there is a possibility for users to use bigger sets of boundaries and vectors, already incorporated into the SQLMap.
For such demands, the options --level
and --risk
should be used:
The option --level
(1-5
, default 1
) extends both vectors and boundaries being used, based on their expectancy of success (i.e., the lower the expectancy, the higher the level).
The option --risk
(1-3
, default 1
) extends the used vector set based on their risk of causing problems at the target side (i.e., risk of database entry loss or denial-of-service).
As for the number of payloads, by default (i.e. --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.
To further fine-tune the detection mechanism, there is a hefty set of switches and options. In regular cases, SQLMap will not require its usage. Still, we need to be familiar with them so that we could use them when needed.
Status Codes
For example, when dealing with a huge target response with a lot of dynamic content, subtle differences between TRUE
and FALSE
responses could be used for detection purposes. If the difference between TRUE
and FALSE
responses can be seen in the HTTP codes (e.g. 200
for TRUE
and 500
for FALSE
), the option --code
could be used to fixate the detection of TRUE
responses to a specific HTTP code (e.g. --code=200
).
Titles
If the difference between responses can be seen by inspecting the HTTP page titles, the switch --titles
could be used to instruct the detection mechanism to base the comparison based on the content of the HTML tag <title>
.
Strings
In case of a specific string value appearing in TRUE
responses (e.g. success
), while absent in FALSE
responses, the option --string
could be used to fixate the detection based only on the appearance of that single value (e.g. --string=success
).
Text-only
When dealing with a lot of hidden content, such as certain HTML page behaviors tags (e.g. <script>
, <style>
, <meta>
, etc.), we can use the --text-only
switch, which removes all the HTML tags, and bases the comparison only on the textual (i.e., visible) content.
Techniques
In some special cases, we have to narrow down the used payloads only to a certain type. For example, if the time-based blind payloads are causing trouble in the form of response timeouts, or if we want to force the usage of a specific SQLi payload type, the option --technique
can specify the SQLi technique to be used.
For example, if we want to skip the time-based blind and stacking SQLi payloads and only test for the boolean-based blind, error-based, and UNION-query payloads, we can specify these techniques with --technique=BEU
.
UNION SQLi Tuning
In some cases, UNION
SQLi payloads require extra user-provided information to work. If we can manually find the exact number of columns of the vulnerable SQL query, we can provide this number to SQLMap with the option --union-cols
(e.g. --union-cols=17
). In case that the default "dummy" filling values used by SQLMap -NULL
and random integer- are not compatible with values from results of the vulnerable SQL query, we can specify an alternative value instead (e.g. --union-char='a'
).
Furthermore, in case there is a requirement to use an appendix at the end of a UNION
query in the form of the FROM <table>
(e.g., in case of Oracle), we can set it with the option --union-from
(e.g. --union-from=users
).
Failing to use the proper FROM
appendix automatically could be due to the inability to detect the DBMS name before its usage.