Vulnerability Walkthrough – Password Spraying

In a previous post, we covered timing-based username enumeration vulnerabilities and how an attacker can exploit these weaknesses to craft a list of known-valid user accounts. The next step in that attack chain is using that list of valid accounts to conduct password attacks and try to gain unauthorized access to an organization’s exposed login portals. The most successful of those password attacks (and coincidentally most popular) is a password spraying attack. In this blog, we’ll define password spraying, walk through how this exploitation technique works, and discuss some mitigating controls that can be implemented.

What is Password Spraying?

As we’ve already covered in a previous blog here, password spraying is a type of password attack that flips the paradigm of a traditional password attack on its head. Rather than trying a bunch of different passwords against a single account as you would in a dictionary attack or brute force attack, an attacker will try a small number of common passwords against a list of users. This approach is beneficial for a couple very important reasons. First, an attacker can avoid account lockouts this way. By spacing out the attempts to allow any lockout counters to reset and only trying one or two passwords at a time, no user accounts will be locked out during this attack process. Second, most monitoring and alerting tools are not going to detect and stop this kind of attack by default, and from we’ve seen, a lot of network defenders aren’t actively looking for it either. This means this type of attack will likely go unnoticed, not setting off any alerts or alarm bells.

The important thing to understand about this type of attack is that it takes advantage of human nature and your organization’s weak password policy. By trying statistically likely passwords, such as Spring2019 or <YourOrganizationName>1, an attacker is trying to quietly find some low-hanging fruit. Given enough time, odds are good that an outsider could eventually gain access to one account using this technique in most organizations, based on our historical experiences in using this attack. But the success of this attack really hinges on crafting a good username list. This is where vulnerabilities like timing-based username enumeration on Microsoft OWA/EWS/Lync servers that we previously discussed come into play.

Exploitation

So how does an attacker go about exploiting this issue? Well if they’ve identified a Microsoft OWA server on your perimeter, as we’ll use in this example, and have already gone through the process of crafting as large a list of valid usernames as they can, the next part is fairly simple. Using the domain name gathered from the username enumeration process and the list of usernames, Burp Suite Pro (or MailSniper, Spray, etc.) can be configured to submit a login request for each user on the list and catalog the responses using the Intruder module. First you’ll find take the POST request submitted to the target mail server and send it to to the Intruder module for editing. In Intruder, you should leave the default attack type to “Sniper” indicating you want your list to be run through in a single field and your request should look something like the screenshot below. The username field will be the domain name \ username (URL encoded), the username portion should be enclosed in the variable tags, and the password field should be set to whatever common password you want to try. You’re going to want to keep a list of these passwords and the time at which you launched the attack to avoid duplicating effort or hitting account lockouts.

password spraying

Then, after you hit launch, you’re looking for a response size, response time, or response code that differs from the other invalid attempts. You can optionally configure Burp Suite to flag responses that contain a particular string (something that only a logged in user would see, for example), but generally it’s pretty obvious even without doing that. Your results will look something like what’s shown below:

password spraying

Now that I have, what looks like, a valid set of credentials I can go manually login to verify. At this point, I’ve gotten access to an Active Directory account and my primary concern will be figuring out what this user can log into on the organization’s perimeter, searching their email for sensitive information, and trying to use this access to gain further access within the organization. Additionally, MailSniper can be used to automate the process of logging in to the OWA server and retrieving the entire Global Address List (GAL) in order to get more valid usernames and conduct more spraying, in attempt to gain access to more accounts with hopefully different or more elevated privileges.

Mitigating Controls

A password spraying attack can’t be completely prevented unless you don’t have login interfaces exposed to the Internet, which is very unlikely. So the focus here is going to be on reducing the chance of success for finding valid usernames and valid passwords, reduce the impact if a set of valid credentials is discovered, and monitoring for this type of attack. We’ve gone into detail on some steps to reduce the risk of password spraying attacks here, but for a quick summary:

  • Reduce your attack surface – Only expose the login interfaces that are absolutely necessary to the Internet. For the login interfaces exposed, make sure they aren’t vulnerable to username enumeration.
  • Multi-Factor Authentication – Implement MFA on any login interfaces that do need to be exposed to prevent unauthorized access when valid credentials are obtained.
  • Improve Password Policy – 8 character minimums aren’t enough to keep the bad guys out, consider a longer minimum for your password length and implementing a password blacklist to prevent users from setting extremely weak passwords.
  • Configure Monitoring/Alerting – You want your network defenders to be alerted to this type of attack so it can stopped. Make sure your monitoring tools are configured with correlation rules along the lines of, “if x failed login attempts occur within y time-frame, we want to know about it.”