
Moodle 5.2.3 - Élevé - À distance - Chemin - Blackboard img src copie des fichiers en dehors de l'arborescence d'import
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · moodle-blackboard-img
Moodle LMS 5.2.3 - Moodle
Classe : Lecture de fichier Portée : Distante
qformat_blackboard_six_base::text_field concatène img src sur $this->filebase sans PARAM_PATH. store_file_for_text_field copie ensuite ce chemin dans la zone de fichiers brouillon de l'utilisateur. get_filecontent, de la même famille, se protège déjà avec clean_param($path, PARAM_PATH). MSA-26-0012 a protégé l'import d'activité de base de données avec PARAM_FILE. Le img src de Blackboard ne faisait pas partie de cet ensemble.
Un enseignant capable d'importer un zip Blackboard injecte <img src="https://raw.githubusercontent.com/html/config.php">. L'« image » brouillon est config.php. Les étudiants ne peuvent pas importer.
| ID | pas encore de CVE |
| CWE | CWE-22 / CWE-73 |
| CVSS | Moyen : 6.5 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N |
| Produit | Moodle |
| Affecté | 5.2.3 tag v5.2.3 (344232c15336c71b80f9aca8359ce0e0a9f3d116) |
| Auth | enseignant (banque de questions / import Blackboard de leçon) |
| Licence | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1 uniquement |
Écrivain : un enseignant capable d'importer un zip Blackboard dans la banque de questions (ou une leçon). Le gain typique est config.php (mot de passe de la base de données) en tant qu'utilisateur PHP. Pas de RCE à moins d'enchaîner avec un second résidu. Pas de LPE.
| Privilège | Méthode / sink | Reconnaissance / intégrité / disponibilité | Prouvé en lab ou déduit |
|---|---|---|---|
Lire un fichier que l'utilisateur PHP peut ouvrir, via ../ dans img src | text_field concatène $this->filebase . '/' . $path ; store_file_for_text_field copie dans la zone brouillon | Reconnaissance (octets du fichier) | Prouvé en lab. Les octets brouillon correspondent à /var/www/html/config.php et contiennent MOODLE-BLACKBOARD-IMG-WITNESS |
| Télécharger ce brouillon en tant qu'« image » | itemid du brouillon + nom de fichier @@PLUGINFILE@@ réécrit | Reconnaissance | Prouvé en lab. GET /draft a renvoyé 298 octets, sha256 égal à config.php |
| Quiconque peut ensuite ouvrir la question importée | Même brouillon / pluginfile | Reconnaissance | Déduit. Le lab s'est arrêté à la correspondance du brouillon de l'enseignant |
| Import par un étudiant | même zip, role=student | n/a | Prouvé en lab fermé. HTTP 403 teacher-only |
Même chemin via clean_param($path, PARAM_PATH) | gadget jail=1 | n/a | Prouvé en lab fermé. Aucune correspondance, aucun témoin, le chemin reste sous filebase |
| RCE PHP / LPE OS | n/a | n/a | Fermé. Ce résidu copie les octets du fichier dans un brouillon. Il ne les exécute pas |
Un Moodle par défaut sans import Blackboard n'est pas concerné par ce bug. MSA-22-0016 n'a nettoyé que baseurl.
Autres résidus du même pin : enrol_database SQLi, grades feedback IDOR, hidden grade items.
J'ai épinglé moodle/moodle v5.2.3 après MSA-26-0042/0043. MSA-26-0012 a protégé l'import d'activité de base de données. Je me suis ensuite penché sur Blackboard parce que get_filecontent() connaissait déjà PARAM_PATH et que text_field() faisait toujours une concaténation brute.
Fausses pistes déjà consignées : considérer l'import étudiant comme la fuite (c'est un 403) ; qualifier cela de RCE parce que le fichier copié est du PHP (le brouillon stocke les octets, il ne les include pas) ; supposer que MSA-22-0016 avait terminé le travail (baseurl uniquement). Un reverse shell. Du théâtre.
Gadget fidèle au pin text_field / store_file_for_text_field, pas une application PHP Moodle complète. how=gadget.
python3 moodle-blackboard-img-Abraxas-Labs.py
ou
cd lab
./run.sh
Cible uniquement http://127.0.0.1:19560. Projet Compose moodle-blackboard-img. La stack est démontée après l'exécution.
SUCCESS moodle-blackboard-img how=gadget pin=v5.2.3 teacher-import=yes draft-match-config=yes student=403 param-path-jail=yes MOODLE-BLACKBOARD-IMG-WITNESS
clean_param($path, PARAM_PATH) sur img src, puis realpath doit rester sous realpath($this->filebase). Même forme que get_filecontent().
formatbase.php (text_field, store_file_for_text_field)format.php (get_filecontent utilise déjà PARAM_PATH)GNU Affero GPL v3.0. Voir LICENSE. Lab en boucle locale uniquement. Aucune garantie.