Cloud Spotlight: Microsoft 365 Password Attacks
Last updated
Last updated
In this module, we'll focus on password guessing and spray attacks targeting Microsoft 365. These cloud services, like Microsoft 365 and others such as SalesForce and Dropbox, usually have public logins. If there are weaknesses in how these services handle logins, attackers can exploit them to target the services or their users.
We'll explore Microsoft login services (login.microsoftonline.com) as a common example of SaaS and password attacks. Keep two key points in mind: First, attackers can exploit any cloud service, including third-party ones. Second, be aware that attackers use clever techniques, which is important for incident response.
We see a screenshot above of the login.microsoftonline.com page, which is used by Microsoft 365 users. When users log in, their credentials go to login.microsoft.com, which is part of the Azure Active Directory Security Token Service (AADSTS). AADSTS handles authentication for many Microsoft 365 services. After a user logs in, AADSTS sends back a response code that shows whether the login was successful or failed, with details on any issues.
I use the cURL command to send a POST request to thelogin.microsoft.com
for authentication. The --silent
option hides the progress meter, and --data
lets me include the message body, which includes username, password, and authentication type. Some details are left out for brevity.
In this case, authentication fails and returns a JSON object. Using JQ, we extracted the error description, which shows error code 50126, indicating an invalid username or password. You can find more details on these codes at Microsoft’s documentation: https://docs.microsoft.com/en-us/azure/active-directory/develop/reference-aadsts-error-codes.
Detailed response codes from Microsoft are useful to attackers because they show account status, such as if it's active, requires MFA, or is locked. Even if an account needs a second factor for authentication, attackers might still guess passwords. While they might not access Microsoft 365 resources, the passwords could be useful elsewhere.
When an authentication service gives detailed reasons for a failed login, attackers can use this info to speed up their attack and prevent account lockouts. For Microsoft 365, the MSOLSpray
tool by Beau Bullock uses AADSTS response codes to carry out a smart password spray attack. Similar to Hydra’s password spray attacks, MSOLSpray
needs a list of users, usually gathered through OSINT methods and scanning tools like CeWL
. MSOLSpray
is a PowerShell script that works on both Windows and UNIX systems.
We start with a list of three email addresses in users.txt. We then use the MSOLSpray module in PowerShell to run the Invoke-MSOLSpray
cmdlet. This cmdlet tries logging into all the user accounts with the same password and reports which ones succeed.
MSOLSpray is valuable for attackers because it can understand Microsoft 365 login responses. This tool targets SaaS login systems, which is a threat to organizations. Microsoft has solutions to help prevent such attacks. The original MSOLSpray tool by Bullock is available at https://github.com/dafthack/MSOLSpray but isn’t updated often. Joshua Wright maintains a newer version with bug fixes and improvements, found at https://github.com/joswr1ght/MSOLSpray.
Azure Smart Lockout is a default feature for Microsoft 365 accounts that blocks login attempts from IP addresses after several failed tries. For most users, it locks out an IP address after 10 failed attempts, but for US Government customers, it locks out after 3 failed attempts.
Smart Lockout is designed to counter password spray attacks. Unlike brute force attacks targeting one user, password spray attacks use many usernames with a few passwords to avoid locking out accounts. Smart Lockout helps by blocking a source IP after it fails authentication 10 (or 3) times, with a default 60-second lockout before retrying.
MSOLSpray knows that Smart Lockout can stop password spray attacks. If too many failed login attempts happen, the Microsoft 365 server will lock the account. MSOLSpray will stop if it detects over 10 lockouts in one attack and will ask if the attacker wants to continue.
Smart Lockout helps stop password spray attacks but isn't perfect. Attackers can get around it using services like AWS API Gateway. AWS API Gateway lets organizations create a front-end server for their HTTP servers, acting like a proxy. It handles user requests and forwards them to various servers or microservices.
An AWS API Gateway lets users use one hostname for all their web requests. It handles these requests with many workers, sending them to different services, and then sends the responses back to users. This setup lets organizations use a single URL for all their web functions, even if there are many different services behind it.
Attackers use AWS API Gateway to hide their IP address during HTTP attacks. If they go directly to a login page like login.microsoft.com, the site can see their IP address. Since their IP is mostly the same, the site can block them if they keep failing to log in.
When an attacker uses AWS API Gateway instead of going directly to a SaaS login, the API Gateway sends requests through many different IP addresses. This hides the attacker's real IP and changes it with each request, bypassing IP-based security measures like Smart Lockout. The challenge with cloud security is not just the vulnerable systems, but also attackers using cloud services to launch new types of attacks easily.
FireProx, made by Mike Felch (@ustayready), is a simple Python tool found at https://github.com/ustayready/fireprox. It helps you create, list, and delete AWS API Gateway instances using your AWS API credentials and works well with MSOLSpray. For example, we can use the FireProx fire.py script to set up an AWS API Gateway in the us-east-1 region, which then forwards all HTTP requests to a given URL, like login.microsoft.com.
After setting up the endpoint, the attacker can continue the MSOLSpray attack. They use the same arguments but add the -URL argument for the AWS API Gateway URL (from FireProx). This way, each login request to login.microsoft.com comes from a different AWS API Gateway IP, making Smart Lockout ineffective since it can't track the attacker's IP address.
In this module, we've covered how attackers can use a password spray attack on Microsoft 365 and get around security measures like Smart Lockout. Next, we'll discuss how they can also bypass Multi-Factor Authentication (MFA).
If an attacker guesses a Microsoft 365 user's password in a password spray attack, the server will check if extra authentication is needed. If MFA (multi-factor authentication) is set up, the attacker will be told that MFA is required to log in, showing they have the correct password but can't access the account yet. MFA can be applied as a default for all users, making it very effective against password spray attacks, because the attacker also needs access to the MFA device.
Default MFA policies often don't meet business needs, so organizations use Microsoft's Conditional Access (CA) to control when MFA is required. CA lets organizations set specific rules for MFA, such as excluding certain geolocations, IP addresses, platforms (iOS, Android), or legacy systems that don't support MFA. While CA can enhance security by enforcing MFA only when necessary, it can also reduce the need for MFA, potentially lowering security for Microsoft 365 services.
MFASweep, created by Beau Bullock (@dafthack), checks Microsoft 365 authentication endpoints using a valid username and password to find ways to bypass MFA. It tests different device types to spot weaknesses in MFA settings. For example, it found that setting the user agent to a mobile device can bypass MFA on https://outlook.office365.com. You can get MFASweep at dafthack’s GitHub or the updated version with fixes at joswr1ght’s GitHub.
For Microsoft 365 attack investigations, we can use the Microsoft unified audit log to find unusual access patterns, such as locked-out accounts or many failed logins from different IPs. Logs are available for 90 days (non-E5) or one year (E5). Access them at https://compliance.microsoft.com or use the Search-UnifiedAuditLog cmdlet. More info is at https://urls.sec504.org/ohdnl.
After compromising a Microsoft 365 environment, attackers often reduce logging to hide their activities. They might change user licenses from E5 to P1, which captures less logging data. Administrators can check user license settings in the Microsoft 365 admin console or use the Get-MsolUser
cmdlet in PowerShell.
Indicators of a compromised Microsoft 365 account include unauthorized changes to Conditional Access policies (like allowing MFA-free access based on IP or region), reducing audit logging on mailboxes, and modifying mailbox permissions to give extra access.
In this Cloud Spotlight lab we will implement a password spray attack against our simulated Microsoft 365 target server, using MSOLSpray and FireProx to evaluate and recover login credentials against Falsimentis Corporation.
In this lab we will use our Slingshot Linux VM to attack a simulated cloud environment consisting of a Microsoft 365 login server with the help of the AWS API Gateway. We will also use other public resources to perform reconnaissance and analysis including the Falsimentis DNS server at 172.30.0.254, the Falsimentis website, and a website that reports our public IP address at myip.sunsetisp.com.
Attackers use OSINT to find out if a target organization uses Microsoft 365 for email or cloud services. They check domain names and DNS records for clues of Microsoft 365 setup.
Let's use the dig
tool to check for Microsoft 365 by querying the mail exchange (MX) records for "falsimentis.com".
The Falsimentis DNS server has one mail exchange (MX) record, directing emails for falsimentis.com to be handled by the Microsoft 365 server at falsimentis-com.mail.protection.outlook.com.
A DNS sign that a company uses Microsoft 365 is the autodiscover CNAME entry for their domain.
The domain autodiscover.falsimentis.com points to autodiscover.outlook.com, which is typically used by email clients like Outlook to find their email server in Microsoft 365 setups. This suggests Falsimentis uses Microsoft 365 for email. Now, let's investigate login.microsoft.com further.
From Firefox, let's navigate to the http://www.falsimentis.com website. This is a typical company website with some product and offering details, along with contact information and some company leadership team information.
Let's navigate to the Team link from the website menu to see a list of the company leadership. For each person listed you can click on their name to get additional information about the person.
Let's click on any of name of anyone on the leadership team to get detailed information about the person.
Let's use the CeWL tool to collect email addresses from the falsimentis website, which we'll use for the password spray attack.
Let's break down this command:
-d 8
: Increases the spider depth from 2 to 8 to gather more data.
-w words.txt
: Save unique words to words.txt.
-e
: Instructs CeWL to gather both email addresses and words.
--email_file email.txt
: Save emails to email.txt.
We can see that, CeWL gathered several email addresses from the Falsimentis site for use in the Microsoft 365 password spray attack.
Next, we'll run MSOLSpray, a PowerShell script, using the Linux PowerShell interpreter, pwsh.
Let's run the Invoke-MSOLSpray
command with the -UserList
argument for the CeWL email list, using the password Lakers2020
for the attack.
MSOLSpray helps with password spray attacks by showing which usernames are valid but have the wrong passwords. It reveals valid Microsoft 365 usernames and flags ones with invalid passwords. For instance, if the email hiring@falsimentis.com doesn’t exist, the attacker can remove it from their list.
The error message for Jillana.Walcott@falsiments.com shows it's an incorrect email address from the www.falsimentis.com website. Microsoft 365 says this account doesn't exist, so the attacker can tell if accounts or domains are invalid.
After 10 logins, MSOLSpray shows a different error: the account is locked. Let's try the password spray attack again with a new password.
In the second try with MSOLSpray, the Microsoft 365 server shows that all accounts are locked. After 10 failed attempts, MSOLSpray will ask if we want to keep going, as further guesses will likely fail because of Smart Lockout. Choose N to stop.
In this attack, the attacker is easily spotted because all requests come from one IP address. We can check our static IP by asking our lab server at myip.sunsetisp.com.
Microsoft 365's Smart Lockout helps block attackers after 10 failed login attempts from one IP. But attackers can still get around this by using public cloud services.
Attackers can bypass Smart Lockout by using AWS API Gateway to send login requests to login.microsoft.com. FireProx makes this attack easy to set up.
To use FireProx, let's set up our AWS credentials file with the right permissions to create an API Gateway endpoint. We have already a configured AWS credentials for this lab exercise.
Next we'll create the AWS API Gateway endpoint with FireProx.
For this lab, we'll use a modified version of FireProx. Usually, FireProx doesn't need root access, but it does for this exercise. Let's run fire.py
with root privileges using sudo
.
FireProx will use default AWS credentials unless we provide different ones on the command line. To create an AWS API Gateway endpoint, we can use the --command create
argument and specify the destination URL with --url
.
To show how FireProx works, let's set up an AWS API Gateway with the URL http://myip.sunsetisp.com.
FireProx created an API endpoint at http://aarggb04qv.execute-api.us-east-1.amazonaws.com/
. The part before .execute-api
(like aarggb04qv
) is the API ID for this AWS API Gateway instance.
Next, let's run the cURL
command again to find our IP address on the myip.sunsetisp.com server, like this.
Our Slingshot Linux IP address remains the same. To use the AWS API Gateway endpoint created by FireProx, the attacker replaces the usual URL with the FireProx URL. let's run the cURL
command again, using the FireProx URL.
In this setup, the API Gateway server works like a proxy for the attacker. For example, the IP address 10.200.91.225 is the AWS API Gateway that sends the request to myip.sunsetisp.com. The myip.sunsetisp.com server only sees the IP address of the AWS API Gateway, not the attacker's IP address.
When we run this cURL command multiple times, each request uses a different IP address.
This is a big advantage for the attacker because each request uses a different IP address. This prevents services like Smart Lockout from detecting password spray attacks by tracking failed login attempts from one IP address.
Next, let's use FireProx to delete the AWS API Gateway service by running the command with the --command delete
option and the API ID specified with --api_id
.
Now that we know how to use FireProx, let's apply it to MSOLSpray.
This output shows that FireProx set up a new AWS API Gateway endpoint. Just like with the myip.sunsetisp.com example, each request to login.microsoft.com through this endpoint will come from a different IP address.
In this new MSOLSpray attempt, we don’t see account lockout messages anymore. By using the AWS API Gateway, each request appears from a different IP address, so we stay below the 10 failed logins limit per IP that causes Smart Lockout.
Let's display the content of the msolspray.txt file.
Using the -OutFile
parameter with MSOLSpray helps us easily update our list of email addresses. Instead of repeatedly trying to log in with invalid addresses, we can just use the new list from the output file after removing the first part of each line.
Let's adjust the -UserList
argument to use the ~/falsimentis-valid-users.txt file, so the spray attack only targets valid user accounts.
We're asked to experiment with several passwords, including the following suggestions for commonly-weak passwords and other keywords collected from the falsimentis.com website:
Password123
Lakers2020
Dodgers2020
Mittens2022
Falsimentis123
Summer2022
Coee2022
We have Rollins Hows' valid username and password, but logging in requires a second authentication factor. While the username and password are useful, they alone cannot access Microsoft 365.
Let's use Falsimentis123 as a password for thisattack.
We have a new valid password for Jillana Walcott.
In this lab, we found a few passwords using Microsoft 365 by attacking email addresses from a CeWL scan of the www.falsimentis.com site. We only got emails for executives listed there, but we could try more Falsimentis email addresses to recover more passwords.
Attackers often use OSINT to gather email addresses for valid user accounts. They might also use tools like MSOLSpray and FireProx to try common first and last names to find more valid accounts.
Let' examine the files firstnames.txt and lastnames.txt in the ~/labs/names directory,
We can combine names from two lists to create email addresses using PowerShell and two ForEach loops. First, let's declare two PowerShell arrays, one for each list of names.
We've created two variables, $firstnames
and $lastnames
, with names from their respective lists. To create email addresses, we need to combine each first name with each last name. Let's use nested ForEach
loops to merge them.
Let;s run Invoke-MSOLSpray
again with the new email list and set -OutFile
to ~/falsimentis-valid-users2.txt
. We'll use the password Summer2022
for this demo.
In this output, we see many messages saying the user doesn't exist. Let's check the file ~/falsimentis-valid-users2.txt
for other messages.