Thoughts on Account Enumeration

by Sam@sayen.io

As a pen-tester who makes his living doing various proactive services, I have had the opportunity to do authenticated and unauthenticated pen-tests on dozens and dozens of professionally developed web applications.

Many of the Open Web Application Security Project (OWASP) "top ten" findings are talked about extensively and, on a technical level, they are more interesting than account enumeration.  Subtle details with authentication make what is typically considered a low-level finding quite exploitable and serious.  Let me explain this very common configuration which in a high percentage of sites is exploitable.

For a moment, let's disregard any automation safeguards such as CAPTCHA or lockout via IP addresses.

Although some top tier applications have these features, your thousands of mid-level e-commerce and company web applications typically do not (in my experience).  To authenticate a non Multi-Factor Authentication (MFA) enabled account, a user must know two things: an email address/username and a password.  Guess which one is harder to figure out in bulk if there are no enumeration vulnerabilities?  Password?  Guess again.

The email addresses for all but the largest applications (Amazon, eBay, sites with millions of users) are going to be harder to guess in bulk.  The reason is that for a mid-size application, I can likely guess a common person such as Joe Smith will have an account.  What I cannot easily guess is that user's email address.  Popular freemail services like Gmail are so saturated that unless Joe was an early adopter, he does not own:

  • joe.smith@gmail.com
  • jsmith@gmail.com
  • josephsmith@gmail.com

His address is more likely to be:

  • jsmith0217@gmail.com
  • joseph.r.smith@some_local_randomass_ISP_provider.com

To put it another way, I would rather take the bet that one of the knucklehead users of an application has the password Trump2020 than bet that a user of the application has the email address joe.smith@gmail.com.

Seems counterintuitive, right?  This is compounded by the fact that almost all public websites have weak password policies of eight characters and one special character or number.  The overall point I am trying to get at is that if bulk compromises are the goal (not compromising one specific account), a valid email address is at least as valuable to an attacker as a known password.

Although damn near every website is vulnerable to email address enumeration, most are vulnerable to it via the password reset function, which gives a unique message stating that the recovery email has been sent, or that the account has been sent a recovery email.

To an attacker, these are not particularly useful because the user has been alerted with an email, and now the account is (likely) locked until the unique link gets clicked and the password is reset.  There is plenty of room for "issues' in that process, but that is not the focus of this discussion.  What I consider to be a very exploitable and common (mis)configuration that leaves many sites vulnerable to account takeovers is at a glance a non-finding for many pen-testers.

If a site allows you to authenticate using an email address or a username, it is game on.  Why?  Because most sites that use usernames allow you to create them.  If you can create a username, you can enumerate usernames.  There isn't a feasible way that an application can keep people from registering an already taken username without telling the user that the account is available or taken, a.k.a., enumeration.

Usually it is a simple GET request to an API that looks something along the lines of:

GET /API/user/<USERNAME>/check

Many applications return a simple true or false value in a JSON blob indicating if the username is available.

Others may return an encoded response that is numeric, but those are still vulnerable to enumeration.  The problem with this is that now an attacker can create a word list of common names and common last names with all the letters of the alphabet in front of them to throw at the API.  This is usually the most common enumeration vulnerability for web applications.  In the worst enumeration cases (which are amazingly common), user accounts are assigned an incremented numerical number that coincides with the username.  At that point an attacker can essentially dump the application's user database by walking the API call using consecutive numbers with a proxy automation tool such as Burp Intruder.

Other areas that are prime for user account enumeration include messaging functionality that auto-completes your typing.  If you start to type "Bob" and the application starts to auto-complete for you, then you can usually just turn on intercept with your proxy tool to catch the Ajax/XHR request so you can replay the GET request to alphabetically enumerate usernames (typically returned in JSON blobs).  Parse or grep through the JSON for the win.

At the heart of exploitation for username enumeration is the method of password spraying.  Password spraying is the exact inverse of brute forcing.  Instead of submitting many passwords for one account, we submit many accounts with the same password.  This is a useful attack for two reasons.  If you want authenticated access to an environment, the details of which account grants access are not important.  The other reason is that by submitting one password to hundreds of accounts, you will not lock out any users, or likely alert them about the failed authentication attempt.

Critical mass for successfully password spraying enumerated accounts varies.

From my experience, I am usually performing an account takeover after only one password spray if I have around 300-400 usernames enumerated.

What is an effective way to thwart this incredibly easy account takeover method?

Do not allow usernames for authentication.

Sure, you can have them assigned to accounts and used once you are in the application, but make the users authenticate with an email address.  If you configure an application in this manner, the hard-to-fix username enumeration vulnerabilities still exist, but they don't give the attacker 50 percent of the authentication request.

The most likely place to get a solid email address list to spray is by mining previous breaches and hitting the application with a long list, which can be slow.

In the end, time is money for an attacker... and for a pen-tester.

Return to $2600 Index