A Little Backstory
As more companies move their infrastructure into the cloud, attackers are adapting their techniques to target these resources. One of the bigger changes is the shift to using Azure Active Directory (Azure AD) rather than an on-site solution. We’ll focus here on password spray attacks. Normal techniques, such as an automated spray against Office 365, can still prove successful, but it is becoming more common to see these thwarted by more secure configurations, defensive toolsets, and increased awareness by the blue team. It then becomes clear that attackers need a new approach to password spraying.
The Blind Spot
Microsoft’s definition of the Azure AD Graph API is as follows: “The Azure Active Directory Graph API provides programmatic access to Azure AD through REST API endpoints.”  Why should we focus here?
- No Browser Needed: It takes the browser out of the equation for performing authentication to Azure AD.
- Relatively Obscure: Graph API is a commonly over-looked endpoint for MFA implementations.
- Blue Team Blind Spot: We have observed much fewer detections and alerts around this endpoint through purple teams, making it a good target for a stealthy password spray.
So properly protecting the Graph API should keep Azure AD safe right?
Not so much. Microsoft has provided several other resources for programmatic access into an Azure AD environment and many of them are just as over-looked as the Graph API, if not more so. A few examples of these resources include Office 365 Exchange Online, OneNote, and the Azure Key Vault. We will expand on these later on, but for now let’s take a look at how an attacker can abuse these endpoints.
- Credential Validation: These endpoints can validate whether stolen or sprayed credentials are valid in the environment
- Access Token: Once authenticated, an access token is obtained that can be used to gain additional access into an Azure AD environment. For example, with an access token obtained from the Graph API, you can enumerate Azure AD objects through the use of tools such as ROADrecon. Please note that access tokens have a specific scope and may not work against other resources. However some endpoints are more broadly scoped than others.
- Inconsistent MFA: Often, endpoints have conditional access policies applied that force users to have MFA, while a subset of other endpoints are left untouched by those policies. A common configuration that we see is when MFA is properly configured to access sites like SharePoint and Outlook, but the Graph API is left untouched by the conditional access policies.
As Azure AD presents new targets for attackers, blue teamers must also have a way to keep track of these endpoints and determine what may have slipped through the cracks of an otherwise well-covered MFA deployment.
The tool can be found in the Security Risk Advisors GitHub: https://github.com/SecurityRiskAdvisors/msspray.git
Taking the view from both sides, MSSpray is a tool to aid in performing targeted password sprays as well as endpoint validation to highlight the defensive gaps an organization may have with their Azure AD tenancy. MSSpray is written in Python3 and relies on the ADAL library written by Microsoft for use with Azure. It allows you to authenticate against a targets Azure AD by using the ADAL library’s “acquire_token_with_username_password” function. Relying on this function, we created two modules, Spray and Validate.
Running the tool with no arguments will present you with a help menu and list out the available endpoints for authentication.
MSSpray’s Spray module allows the user to perform a targeted password spray, taking an input list of email addresses (one per line), a spray password, and the endpoint to authenticate against. Additionally, you can specify stop as the last argument to tell it to stop the password spray once the first successful login is obtained (NOTE: This will not trigger on “conditional” logins such as MFA required, locked or disabled accounts, etc..)
Selecting an endpoint from the list above, an attacker can then perform a spray against that endpoint using the following command:
python3 msspray.py spray <user_list> <password> <endpoint selection> <stop/blank>
As successful spray can be seen below, highlighting a true login, and noting any success that has a condition (MFA Required and Password Expired in the example).
One final aspect of the spray module is that it will halt upon receiving five 50053 error codes in a row, which correspond to Azure’s locked account error. This is due to behavior we have seen while performing password sprays that were determined to be blocked by the target. MSSpray will prompt the user to either continue, if you suspect that a block was NOT the case, or to quit and dump all previous attempts to a file.
Validate Module and a Fix
MSSpray’s Validate module allows the blue team to enumerate which endpoints in their Azure AD environment are configured with MFA. The approach here is to use a valid account and attempt to login to each resource endpoint on the list. MSSpray will then read the error codes and interpret them as either a successful login or MFA required. This can be greatly beneficial in determining defensive gaps in authentication, point out endpoints that may not currently be on the blue team’s radar.
The Validate module can be run by supplying the valid account name and password.
python3 msspray.py validate email@example.com ReallyBadPass!
Seen below are three different runs of the validate function against a test domain. In the first, we can see that many of the endpoints come back with “Successful login”, suggesting that MFA controls are not present on those resources. In that run we only applied the MFA conditional access policy that we most commonly see in the real world, being only applied to Office 365 and a few related applications such as Exchange Online and SharePoint Online.
We then changed our conditional access policy in Azure to apply to ALL cloud applications. This time around, we can see that our applied changes to the Azure policies were successful in enforcing MFA for all applications for the user. The only caveat is there are some discrepancies on what gets properly protected.
We also tested the legacy control of the MFA Enforcement Policy in Azure. This approach is successful in applying MFA to all of the resource endpoints, but Microsoft will soon be deprecating this functionality in the interest of using conditional access policies.
MSSpray generates logs from every spray or validation attempt. In the spray logs, you will see the full tokens obtained from successful login attempts, which can be used for further access into the Azure AD environment.
MSSpray will be supported and updated continuously. Please submit any bugs or feature requests to the GitHub repo directly. If you have any questions about the tool, please feel free to reach out to me on Twitter @__TexasRanger.