WordPress Enumeration and User Exposure

This section is devided into two parts. User Enumeration and User Exposure. The key differences is that in User Enumeration, it's possible to verify that a username or email is registered on the application. The User Exposer may, in some instances, not be a username and be a Nickname. WordPress have this feature where nicknames can be created and in some instances, these are exposed. This is why it's very important to verify User Exposure users with User Enumeration vulnerabilities to cnfirm that the user is registered on the application.

User Enumeration

Note: It's advised, if some endpoints are hidden or locked behind a WAF, to review the Default Directories to reach the desired endpoints.

Author Directory

The /author/* directory may be fuzzed for users, indexed via Search Engines or exposed via the REST API.

https://example.com/author/admin/

Author Parameter

/?author=X

Replace X with an integer to enumerate the application's usernames. This will reveal the username by either redirecting you through a 3xx response code and may reveal the username within the location header or forward you directly with a 200 OK response to the authors page through /author/admin where admin is the username used to sign into the application.

These are a couple of other bypasses if a WAF, plugin or filter blocks your requests. In this instance, a user with the integer X is enumerated (Change to a desired value):

/?author={num:X}
/?author={X}
/?author=%X
/?author=%25X
/?author=aX
/?author[]=X

Login Page

A way to enumerate usernames are within the Administrative Interface that usually is found within the /wp-login.php directory. When attempting to authenticate with an existing user and a random password, one error message is sent to the client. When a non-existing user and a random password is sent, another error message is shown.

RequestResponse
Wrong Username / Wrong PasswordInvalid username
Correct Username / Wrong PasswordPassword is incorrect for user admin

Left side shows a non-existing user, right side shows an existing user. Each request sent with a wrong password. Login Enumeration Picture

Request Sample For Authenticating:

POST /wp-login.php HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded

log=admin&pwd=password&wp-submit=Log+In&redirect_to=https%3A%2F%2Fwww.example.com%2Fwp-admin%2F&testcookie=1

Password Reset Page

A way to enumerate usernames, once again, is via the forgotten password following directory.

/wp-login.php?action=lostpassword
RequestResponse
Wrong Username / EmailUser does not exist!
Correct Username / EmailCheck email for confirmation link! (Or note the 3xx redirect)

Reset Password Enumeration Picture

Request Sample For Resetting Password:

POST /wp-login.php?action=lostpassword HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded

user_login=admin&redirect_to=&wp-submit=Get+New+Password

XML-RPC

Use WordPress built in API to enumerate or brute force users. Please see the XML-RPC page for more information.

User Exposure

Feed Directories

The following endpoints may, in some instances, reveal the registered users on the application. Their name are exposed within the <dc:creator> XML parameter

/feed/
/feed/rss/
/feed/rss2/
/feed/rdf/
/feed/atom/

Same endpoint as above, but used to bypass WAF:

/?feed=rss
/?feed=rss2
/?feed=rdf
/?feed=atom

Google Hacking/Dorking

Change www.example.com to your target website

site:www.example.com inurl:/author/

Search Parameter

The /?search=test or /?s=test is a Default Parameter in WordPress. It can be used to search through out the blog and search for the keyword author within the source code. At times, just one character may not help - Be sure to type in more into the parameter value! Maybe let burps intruder fuzz from a-z and observe the different sized responses

WP-json - Embed / Users

  • Embed

Append the &format=xml or &format=js to the URLs below in order to potentially expose an Author.

Note: Note how the value of the url parameter can be URL-encoded and an existing path within the application can be appended to it if a WAF blocks the request or the application doesn't respond the way you want it to due to different configurations.

/wp-json/oembed/1.0/embed?url=https%3A%2F%2Fwww.example.com%2F&format=xml
/wp-json/oembed/1.0/embed?url=https://www.example.com/gdpr/&format=js

Imagine there is a /work/about-us/ endpoint on the application. This could also be a valid endpoint

/wp-json/oembed/1.0/embed?url=/work/about-us/
  • Users

This endpoint reveals existing users on the application:

/wp-json/wp/v2/users

If the endpoint /wp-json/wp/v2/users/ is restricted, adding an integer or making it capitalized fuzzing the integer may get results!

/wp-json/wp/v2/users/1/
/wp-json/wp/v2/Users

wp-json user exposure picture

Yoast SEO Plugin

This endpoint may be accessed if Yoast is present on the WordPress application. It will not show all authors, but some authors:

/author-sitemap.xml

yoast user exposure picture