Drupal RCE
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
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.
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
Then click on Add content -> Select Basic Page or Article -> Write php shellcode on the body -> Select PHP code in Text format -> Select Preview
Finally just access the newly created node:
In current versions i't no longer possible to install plugins by only having access to the web after the default installation.
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.
Download the most recent version of the module from the Drupal website.
wget https://ftp.drupal.org/files/projects/php-8.x-1.1.tar.gz
Once downloaded go to Administration
> Reports
> Available updates
.
Click on Browse
,
select the file from the directory we downloaded it to, and then click Install
.
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.
In current versions it's no longer possible to install plugins by only having access to the web after the default installation.
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. Scroll down and copy the link for the tar.gz archive.
Download the archive and extract its contents.
Create a PHP web shell with the contents:
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.
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.
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.
Post shared by Coiffeur0x90
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:
After activation:
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
To:
File: system.file.yml
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
To:
File: field.field.media.document.field_media_document.yml
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).
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
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 (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).
File: Patched LICENSE.txt
First, we leverage the Add Document (/media/add/document) feature to upload our file containing the Apache directives (.htaccess).
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.
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.
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)