WordPress Username Enumeration
Adrian Pastor is a member of the BlogSecurity team and the GNUCITIZEN Group. His personal web site is available at ikwt. As always, Adrian gives us a very detailed advisory around how an attacker can enumerate valid WordPress user accounts and then launch password guessing attacks in an attempt to compromise the blog. His proof of concept brute force script is available here.
This post is the follow up to my previous work on username enumeration vulnerabilities. In this post we primarily concentrated on various identification techniques. In this post, we will explore some of the issues around the same subject which are present in the latest Wordpress build. In short, we will deal with exploitation as opposed to identification.
As you might already know, there are many tools you can use to exploit username enumeration vulnerabilities. For instance, you can use Burp, which allows you to flag user-defined responses. I personally feel that Burp waits too long between each request, making the process very slow. Now, we all have our favorite tools and tricks, but in this post I will use bash + curl. The reason for this is because both combined produce a very powerful and customizable tool. Moreover, we don’t have to be advanced coders at all in order to use bash – far from it!
Let’s discuss how we can attack Wordpress 2.2.1 login facilities. The Wordpress login page is usually easily identifiable. Unless the blog owner put extra effort to re-arrange some of the core Wordpress modules, it would be located on the following path by default:
If you try logging in with any non-existent username and a random password the login page will return the following message:
Error: This username is invalid. Please enter a valid username.
Thus the login page leaks the fact that probed username does not exist. Hint: notice “This username is invalid”
On the other hand, if we enter a username that does exist and an invalid password, the login page would return the following message:
Error: Incorrect password
As we can see the error message is now different and suggests that the username we entered does exist on the system. As developers, we could fix this username leak on the login page by simply returning a general authentication failure message when the username and/or the password is/are wrong. Thus, attackers wouldn’t have means to find out whether a username already exists on the database unless a valid username and its corresponding password were both cracked.
i.e:
ERROR: Incorrect username and/or password.
Let’s see what we need to do in our attack script:
Incorrect passwordIn order to get a rough idea of what we’re talking about, you can take a look at the following snippet from the PoC script we have created for this article. Note: such script has been tested on Wordpress 2.2.1 but might also work on previous versions.
if curl -s -d "log=$U&pwd=mypassword&wp-submit=Login+%C2%BB&redirect_to="
--url "http://$1/wordpress/wp-login.php" | grep -i 'Incorrect password' > /dev/null
What we have is the following. The ‘-s’ flag avoids printing unnecessary status info (’s’ for silent). ‘-d’ allows you to submit parameters as a POST request. $U is each username read from the wordlist. Notice we are submitting a dummy password (’mypassword’). Lastly, if we get a ‘true’ signal from grepping ‘Incorrect password’, then we know we found a valid username. If you see the source code of the script, you’ll notice that there is not much more to it, except for a ‘for’ loop that reads the wordlist file. It really is that simple!
Sometimes however, dictionary attacks might not be necessary in order to identify existing usernames. For instance, some Wordpress templates show the author’s name on each post. Additionally, the author name can also be found within RSS feeds’ tags. Unfortunately, the author’s name shown in posts and RSS feeds is not necessarily the same as the login username. Hint: what information will be shown as the author’s name is set on the Profile/Display name publicly as menu.
Just remember, there might be scenarios in which a dictionary attack on a functionality that is vulnerable to username enumeration is your last resort to collect usernames. As an example, there are companies and large organizations using Wordpress with several admin users whose usernames are not used to publish posts but rather to moderate other user’s posts. In such case a username enumeration vulnerability might come in handy for attempting to enumerate admin usernames.
Here are some possible admin usernames you might want to add to your favorite usernames wordlist:
admin, administrator, moderator, manager, root,
<companyname>admin, blogadmin, wpmoderator, wpadmin,
wpmanager
There are other places where you might be able to find some usernames. A good example are Wordpress author templates which allow you to extract usernames through URLs with the following syntax: /wordpress/author/authorname/
i.e.:
http://www.target-domain.com/wordpress/author/admin/
A different functionality we can attack is Wordpress 2.2.1’s signup page (”/wordpress/wp-register.php”) which is also vulnerable to username enumeration. When registering a new account we need to enter a username and email address. However, when entering either a valid or invalid email address the application will reveal whether or not the username entered exists on the system. For instance, if we entered the username “admin” and the email address “notvalidemail”, we would get the following message, thus revealing that the username entered already exists:
ERROR: The email address isn't correct.
ERROR: This username
is already registered, please choose another one.
What you want to do in this case is probe usernames using invalid email addresses. That way when you probe a username that does exist, the application won’t create a new account, therefore making the attack more stealth. You could also argue that probing existing usernames on a signup page is less obvious than doing it on a login page.
That’s all guys. In this post I just chose Wordpress to illustrate some examples but remember that username enumeration vuls, although usually considered a low risk, might have bigger implications on sites of different nature such as financial applications. As usual, please feel free to provide feedback, which after all is what makes publishing research on blogs interesting.
Although attackers may be able to brute force valid usernames, strong passwords will help mitigate the affects of such an attack. So in short, ensure that you choose strong 6-8 characters (should include a digit, and an upper-case character) password or passphrase. WordPress will hopefully take this advisory into consideration in a future release.
Read some of Adrian’s other articles:
Random Posts
If you enjoyed this post, please leave a comment or subscribe to the feed and get future articles delivered to your feed reader.
Comments
That vulnerability is the perfect example for a blog which isn’t hardened. That attack isn’t possible when you hardened your blog. Or it’s quite harder to achieve if you have at least password protected your wp-admin area. So for all who didn’t considered harden their wp install should rethink their decision.
Phil, yes, those who implemented our hardening guide (atleast those able to) would be immune to a degree against this attack, nice point!
David,
Don’t take my word for it, but I think the 6 chars are a derived from a partial hash (first 6 chars of MD5 hash?) of a random value. Hopefully it’s truly random, otherwise we have
36^6 = 2176782336 combinations
which is a lot! :)
Not too long ago we came across a financial app. The app would generate new passwords when clicking on “I forgot my password” that would be sent to your email. The problem is that the pwds were made of a word from either of the following groups:
- classic musician names
- fruits
- colors
plus two digits. You might think I’m kidding but this is a real story.
[...] it is not holding back new WordPress holes from disclosure — for example, a new article yesterday showed how to perform enumeration on WordPress installation by brute force, so that valid usernames [...]
[...] von einem lesenswerten (englischsprachigen) Artikel ›WordPress Username Enumeration‹ in BlogSecurity ein paar kurze Anmerkungen zu Verwendung von Benutzernamen in Wordpress – [...]
Very very cool article! I created a wordpress plugin that you might want to check out and see if your method will still be useful.




Adrian, sometimes we underestimate the traditionl brute force approach, awesome article.