Vulnerability Walkthrough – Timing-Based Username Enumeration
From time to time, when we see a particular vulnerability that keeps showing up over and over again during penetration testing engagements, we like to write about it and help spread awareness. This can help explain the issue, the subsequent risk it presents to your organization, and how to successfully remediate the issue or at least mitigate some of the risk. In this instance, we’re going to cover timing-based username enumeration vulnerabilities. We’ve been seeing these consistently on external penetration tests and they almost always lead to use gaining unauthorized access to externally applications, including email, file shares, or even VPNs. The most common applications harboring these vulnerabilities are Microsoft Exchange Servers with Outlook Web Application (OWA) or Exchange Web Services (EWS) exposed or Microsoft Lync Servers.
What’s the big deal?
To understand the vulnerability itself first, let’s break it apart. First, username enumeration is a vulnerability that occurs when an attacker can submit a request to an application, such as a login request, password reset request, or registration request, and the application response will indicate the validity of the username submitted. This can be as obvious as an error message (“That account doesn’t exist.”) or simply be a slight change in response error codes (maybe there’s a hidden parameter called login error that changes from a 1 to a 2). Either way, an attacker can abuse this to automatically build a list of valid usernames that can be used with password attacks. The timing-based part of this vulnerability comes in when the application doesn’t have an obvious way to determine the validity of a username, but the timing of the web server’s response changes. In the case of Microsoft OWA servers, a valid username submitted with a login request has a much faster response time than an invalid username. Usually, this is caused by flaws in the application’s login processing code that create a much longer execution path, inducing a longer timing delay.
So however they are able to accomplish it, whether it be an overt enumeration method or a more subtle one like timing, an attacker being able to build a big list of valid usernames is a big risk. This provides half of what you need to login to whatever application is being targeted, significantly increasing the chances of someone gaining unauthorized access. Now the only thing standing between your organization and a compromise is the strength of your users’ passwords, which I think we can all agree are probably not all that great. Let’s walk through how this user list gets built and what attacks it facilitates.
Exploiting Timing-Based Username Enumeration
If you run across a login interface for Microsoft OWA, Microsoft EWS, Microsoft Lync, or any other application you think may be vulnerable to timing-based username enumeration, what do you do next? Well there are a ton of different tools to help facilitate this attack, but all your really need is your trusty intercepting proxy (our default choice is usually Burp Suite Pro). One tool you may want to consider in tandem with your intercepting proxy is MailSniper. This tool, released by Beau Bullock aka @dafthack, is really useful for automating portions of the attack and facilitating information gathering post-exploitation. I’m going to use a Microsoft OWA server to demo this methodology for the purposes of this blog. So one thing we’ll need for the rest of the attack that MailSniper can quickly get us is the target’s Active Directory domain they use to authenticate. The fastest way to get this is by using the Invoke-DomainHarvestOWA module when you’re targeting an email server, as shown below.
Now that you’ve got the suspected Active Directory domain name, we need some usernames that we’re going to try and validate. Keep in mind this is an online process with an associated timing delay, so it is not going to be super speedy. You can usually try somewhere between 700 and 1000 usernames an hour, depending on your Internet speeds and the response time of the target. With that in mind, we want to test high probability usernames first. To get these potential usernames, I generally use a two-pronged approach:
- Scrape users from LinkedIn – This is the best place to get employee names, hands down. There are a lot of tools that can help with this out there, but we use a custom script to cycle through the employee list for a company and extract the first and last name of all potential employees from the responses. This process can be supplemented with other social media sites or employee rosters that you can find through OSINT.
- Create a list of the most common names – Using Daniel Miessler’s SecLists, you can take his lists of the most common US family names and first names to combine those and create potential usernames.
- If you’re having trouble finding username formats or just want a larger list, use FOCA to search for publicly available documents on your target organization’s domains and scrape the metadata from them. Oftentimes, this will contain usernames/email addresses.
So with the names of potential employees, we need to create a single list of potential usernames. 99% of the time, you’ll be able to find the username format from the email addresses of employees that you can find through OSINT. Most companies follow a standard and use something like first.last, firstinitial+lastname, etc. Once you find that format and script a transform for your employee names -> usernames, we’re ready to start validating. With your intercepting proxy, capture a login request to the OWA server. The POST request shown below is what you should see that you can then send to Intruder (in Burp Suite) to modify and start the process of validating usernames. Specifically, you’ll see the username field which should be a URL-encoded version of “DOMAIN\username” and the password field which can be any value. We can then mark the username field in intruder to rotate through our list of potential usernames we created, and analyze the timing of the responses. Shorter response times mean a valid username, and if it’s working, you should see a timing difference of roughly an order of magnitude or more for invalid usernames (200ms vs 2000ms).
This can also be done with MailSniper using the Invoke-UsernameHarvestOWA module. That module requires the target hostname (mail.example.com), the path to your file containing potential usernames, and a filename to output the list of valid users. Your results should look something like this:
And now an attacker has a potentially substantial list of valid usernames that they can use to run password attacks against these exposed login interfaces, conduct social engineering attacks using this information, or attempt to find valid credentials from other sources and use credential stuffing. One of the most prevalent password attacks that you would usually see as a next step is a password spraying attack, which we’ll discuss in a separate blog post.
Now that we’ve seen how timing-based username enumeration can be used to attack your organization, how do you go about fixing it? Well if you own the application that is vulnerable and developed the code in-house, you’ll want to raise this issue to the developers and discuss ways to avoid large timing differences in login processes. If you don’t own the code, as is the case with commercial-off-the-shelf (COTS) software like Microsoft OWA, this get’s a little more tricky. Microsoft has acknowledged this issue and maintained the stance that they don’t plan on fixing it. So that leaves you with moving away from on-prem email solutions and instead using Office 365 (which is not vulnerable to any type of username enumeration) or not exposing peripheral applications like Microsoft Lync to the Internet and making sure it is only accessible from the internal network.
Besides truly fixing the root cause, your next best bets are some compensating controls that can help reduce the risk of unauthorized access. The most effective control would be to implement multi-factor authentication (MFA) on any of your exposed login interfaces. This way, even if an attacker did gain access to valid credentials using the list of enumerated usernames, they would need that second factor to get in. Alternatively, making sure you’ve got strict account lockouts in place (although this won’t save you from password spraying) and a strong password policy can help increase resiliency to password attacks. A password policy with a longer minimum length requirement (e.g. 14 or 20 characters) and the implementation of a password blacklist to prevent users from setting extremely weak passwords can help prevent unauthorized access. Finally, if you can’t stop these attacks, at least monitor for them. Make sure your logging and alerting environment is configured to detect multiple invalid authentication attempts from a single source, regardless of the username (to identify spraying activity and brute force attempts), so your admins can stop these attacks in progress.