Keyboard shortcuts

Press ← or β†’ to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

🏠 Back to Blog

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

PathPurpose
/wp-login.phpAdmin 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.phpXML-RPC API (can be abused for brute-force / pingback attacks)
/readme.htmlDiscloses WordPress version

User roles

RoleCapabilities
AdministratorFull access β€” add/delete users and posts, edit source code
EditorPublish and manage all posts (including other users’)
AuthorPublish and manage own posts only
ContributorWrite and manage own posts, cannot publish
SubscriberBrowse 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:

ConditionMessage
Valid username, wrong passwordThe password for username **admin** is incorrect.
Invalid usernameThe 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

ArgumentEnumerates
apAll plugins
atAll themes
uUsers
vpVulnerable plugins only (default)
vtVulnerable 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

FindingSignificance
XML-RPC seems to be enabledBrute-force via xmlrpc.php; pingback abuse
WordPress readme foundVersion disclosure at /readme.html
Upload directory has listing enabledBrowse uploaded files
WordPress version X.Y identified (Insecure)Check listed CVEs
Plugin/theme with [!] vulnerabilities identifiedNote version and CVE for exploitation
Users identifiedFeed 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.php is accessible
  • Whether directory listing is enabled on /wp-content/uploads/ or plugin directories
  • Whether /readme.html is accessible (version disclosure)