
Salut, je suis K, c’est ma première CVE, qui est une vulnérabilité d’exécution de code à distance (RCE). C’est le début de mon parcours en tant que chercheur en sécurité.
Exécution de code à distance authentifiée dans Chamilo LMS 1.11.32 via une validation inadéquate du téléchargement de fichiers dans le point de terminaison AJAX
ck_uploadimage. Un étudiant disposant de faibles privilèges peut télécharger un shell web PHP déguisé en image, compromettant ainsi entièrement le serveur.
| Champ | Détails |
|---|---|
| Produit | Chamilo LMS |
| Version | 1.11.32 (Confirmée) |
| Vulnérabilité | Téléchargement de fichier sans restriction avec type dangereux (CWE-434) |
| Impact | Exécution de code à distance authentifiée (RCE) |
| CVSS v3.1 | 8.8 (ÉLEVÉE) — CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| Authentification requise | ✅ Oui — Rôle étudiant (faible privilège) |
| CWE | CWE-434 : Téléchargement sans restriction de fichier avec type dangereux |
| Découvert par | MENG HOKSENG |
POST /main/inc/ajax/document.ajax.php?a=ck_uploadimage&cidReq=[COURSE_ID]
Fichier vulnérable : main/inc/ajax/document.ajax.php
Fonction vulnérable : ck_uploadimage
Le gestionnaire de téléchargement effectue uniquement une validation du type MIME à l'aide de la fonction PHP mime_content_type(), qui inspecte les octets magiques du fichier (les premiers octets du contenu), et non l'extension du fichier.
// Logique de validation vulnérable (simplifiée)
$mime = mime_content_type($_FILES['upload']['tmp_name']);
if (!mimeAccepted($mime, ['image'])) {
die("Invalid file type");
}
// ❌ Aucune validation de l'extension
// ❌ Aucune assainissement du nom de fichier
move_uploaded_file($_FILES['upload']['tmp_name'], $uploadPath . $fileUploadName);
Deux faiblesses distinctes se combinent pour former une chaîne d'exploitation complète :
GIF89a).php, dans un répertoire accessible via le webUn fichier malveillant est conçu comme suit :
GIF89a;<?php system($_GET['cmd']); ?>
mime_content_type() lit GIF89a → le classe comme image/gif → passe la validationmove_uploaded_file() l'enregistre sous shell.php dans /app/upload/users/<id>/ → directement exécutable via le navigateurExécutez l'exploit complet qui se connecte en tant qu'étudiant pour effectuer automatiquement le téléchargement du fichier
Après avoir exécuté l'exploit Python complet, nous pouvons trouver notre shell web téléchargé à l'adresse http://localhost:8081/app/upload/users/3/3/my_fileszhxoxgwj.php?cmd=id

L'exploitation réussie de cette vulnérabilité entraîne la compromission totale du serveur à partir d'un compte de niveau étudiant :
Impact CIA : Perte complète de la confidentialité, de l'intégrité et de la disponibilité.
▪ Imposer une liste blanche stricte des extensions de fichiers Seules les extensions de fichiers image explicitement autorisées (par exemple, .jpg, .png, .gif) doivent être acceptées. Les fichiers téléchargés avec des extensions exécutables telles que .php, .phtml ou .phar doivent être rejetés quel que soit le type MIME.
▪ Ne pas se fier uniquement à la validation du type MIME Les contrôles du type MIME utilisant des fonctions telles que mime_content_type() ne doivent pas être utilisés comme contrôle de sécurité principal, car ils peuvent être contournés à l'aide d'en-têtes de fichiers falsifiés. La validation MIME ne doit être utilisée que comme contrôle secondaire.
▪ Stocker les fichiers téléchargés en dehors des répertoires accessibles via le web Le contenu téléchargé doit être stocké dans un répertoire qui n'est pas directement accessible via le serveur web. Si un accès public est requis, les fichiers doivent être servis via un gestionnaire contrôlé plutôt que par un accès direct.
MENG HOKSENG
Chercheur en sécurité indépendant
Ce projet est publié uniquement à des fins éducatives et de recherche en sécurité autorisée. L'auteur n'est pas responsable de toute utilisation abusive ou de tout dommage causé par cet exploit. Obtenez toujours une autorisation écrite explicite avant d'effectuer des évaluations de sécurité.