WordPress β Discovery & Enumeration
Background
WordPress (launched 2003) is the most popular CMS on the internet, accounting for roughly 32.5% of all sites. Written in PHP, it typically runs on Apache with MySQL. Its extensibility through themes and plugins makes it ubiquitous β and vulnerable.
Key stats:
- 50,000+ plugins, 4,100+ GPL themes
- 54% of known WordPress vulnerabilities come from plugins, 31.5% from core, 14.5% from themes (WPScan data)
- ~8% of hacks due to weak passwords; ~60% due to outdated WordPress versions
Discovery / Footprinting
robots.txt
A WordPress installation almost always has a robots.txt that exposes its directory structure:
User-agent: *
Disallow: /wp-admin/
Allow: /wp-admin/admin-ajax.php
Disallow: /wp-content/uploads/wpforms/
Sitemap: https://inlanefreight.local/wp-sitemap.xml
Presence of /wp-admin and /wp-content confirms WordPress. Browsing /wp-admin/ redirects to /wp-login.php β the back-end login portal.
Key paths
| Path | Purpose |
|---|---|
/wp-login.php | Admin login portal |
/wp-admin/ | Admin dashboard (redirects to login) |
/wp-content/plugins/ | Installed plugins |
/wp-content/themes/ | Installed themes |
/wp-content/uploads/ | Uploaded files (often directory-listable) |
/xmlrpc.php | XML-RPC API (can be abused for brute-force / pingback attacks) |
/readme.html | Discloses WordPress version |
User roles
| Role | Capabilities |
|---|---|
| Administrator | Full access β add/delete users and posts, edit source code |
| Editor | Publish and manage all posts (including other usersβ) |
| Author | Publish and manage own posts only |
| Contributor | Write and manage own posts, cannot publish |
| Subscriber | Browse posts, edit own profile |
Administrator access is generally sufficient for RCE. Editors and Authors may have access to vulnerable plugins.
Manual enumeration
Confirm WordPress and fingerprint version
curl -s http://blog.inlanefreight.local | grep WordPress
<meta name="generator" content="WordPress 5.8" />
Enumerate theme
curl -s http://blog.inlanefreight.local/ | grep themes
href='http://blog.inlanefreight.local/wp-content/themes/business-gravity/assets/...
Enumerate plugins from page source
curl -s http://blog.inlanefreight.local/ | grep plugins
.../wp-content/plugins/contact-form-7/includes/css/styles.css?ver=5.4.2...
.../wp-content/plugins/mail-masta/lib/subscriber.js?ver=5.8...
The ?ver= query parameter often reveals the plugin version. Check additional pages too:
curl -s http://blog.inlanefreight.local/?p=1 | grep plugins
.../wp-content/plugins/wpdiscuz/themes/default/style.css?ver=7.0.4...
Plugin readme files
If directory listing is enabled on a plugin directory, browse to it and look for readme.txt:
http://blog.inlanefreight.local/wp-content/plugins/mail-masta/
readme.txt typically contains a Stable tag: line that confirms the installed version.
User enumeration
WordPress login error messages are different depending on whether the username exists:
| Condition | Message |
|---|---|
| Valid username, wrong password | The password for username **admin** is incorrect. |
| Invalid username | The username **someone** is not registered on this site. |
This oracle allows username enumeration at /wp-login.php.
WPScan
WPScan is the standard automated WordPress scanner. It fingerprints core version, themes, plugins, users, and maps findings to known CVEs via the WPVulnDB API.
Install
sudo gem install wpscan
Full enumeration scan
sudo wpscan --url http://blog.inlanefreight.local --enumerate --api-token <TOKEN>
Supply an API token from WPVulnDB (free tier: 25 requests/day) to get CVE mappings.
Key --enumerate targets
| Argument | Enumerates |
|---|---|
ap | All plugins |
at | All themes |
u | Users |
vp | Vulnerable plugins only (default) |
vt | Vulnerable themes only (default) |
Example: enumerate all plugins only:
sudo wpscan --url http://blog.inlanefreight.local --enumerate ap --api-token <TOKEN>
WPScan output β what to look for
| Finding | Significance |
|---|---|
XML-RPC seems to be enabled | Brute-force via xmlrpc.php; pingback abuse |
WordPress readme found | Version disclosure at /readme.html |
Upload directory has listing enabled | Browse uploaded files |
WordPress version X.Y identified (Insecure) | Check listed CVEs |
Plugin/theme with [!] vulnerabilities identified | Note version and CVE for exploitation |
| Users identified | Feed into password spraying / brute-force |
Limitations of automated scanning
WPScan may miss plugins that are not referenced on the main page (e.g., plugins only loaded on specific post types). Manual curl | grep plugins across multiple page URLs is necessary to catch everything. The two approaches are complementary β neither replaces the other.
Enumeration checklist summary
After manual + automated enumeration, document:
- WordPress core version (check
/readme.html, RSS generator, page source meta tag) - Active theme name and version
- All plugins found and their versions
- Any plugins / core versions with known CVEs
- Valid usernames confirmed via login error oracle
- Whether
/xmlrpc.phpis accessible - Whether directory listing is enabled on
/wp-content/uploads/or plugin directories - Whether
/readme.htmlis accessible (version disclosure)