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.
Request | Response |
---|---|
Wrong Username / Wrong Password | Invalid username |
Correct Username / Wrong Password | Password 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
.
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
Request | Response |
---|---|
Wrong Username / Email | User does not exist! |
Correct Username / Email | Check email for confirmation link! (Or note the 3xx redirect) |
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
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