Enumeration
Quick Checks
After compromising a new user means you should immediately check your privileges:
Get-AzResourceGet-AzRoleAssignmentAssigned Entra Roles
Administrative Units
Owned Entra Objects
Group Memberships
Automated Tools
ROADTools and AzureHound are popular tools to help automate enumeration of Azure tenants. AzureHound features attack mapping and a node-based GUI. ROADTools is more useful for a general overview of the tenant and user policies such as consent granting.
# ROADTools
roadrecon auth
roadrecon gather
roadrecon gui
# AzureHound with creds
./azurehound list -u jotter@jotter-labs.com -p 'jotter' -o azure.json
.\azurehound.exe -u jotter@jotter-labs.com -p password list --tenant jotter-labs.com -o azure.jsonMicrosoft Graph
The Microsoft Graph API handles interactions with Entra ID/Azure AD. The token audience is graph.microsoft.com.
# Authenticate
Connect-MgGraph
Connect-MgGraph -AccessToken ($GraphToken | ConvertTo-SecureString -AsPlainText -Force)
# Users
Get-MgUser -All
Get-MgUser -UserID jotter@jotter.onmicrosoft.com
Get-MgUser -All |{$_.Displayname -match "admin"}
Get-MgUser -All | ?{$_.OnPremisesSecurityIdentifier -ne $null}
Get-MgUserLicenseDetail -UserId jotter@jotter.onmicrosoft.com
# Groups
Get-MgGroup | ?{$_.GroupTypes -eq 'DynamicMembership'}
Get-MgGroupMember -GroupId ****
(Get-MgUserMemberOf -UserId jotter@jotter.onmicrosoft.com).AdditionalProperties
# Roles
Get-MgDirectoryRole
$RoleId = (Get-MgDirectoryRole -Filter "DisplayName eq 'Global Administrator'").Id
(Get-MgDirectoryRoleMember -DirectoryRoleId $RoleId).AdditionalProperties
# Objects
Get-MgUserCreatedObject -UserId jotter@jotter.onmicrosoft.com | fl *
Get-MgUserOwnedObject -UserId jotter@jotter.onmicrosoft.com | fl *
# Devices
$ids = (Get-MgDevice -All).Id; foreach ($i in $ids){ (Get-MgDeviceRegisteredOwner -DeviceId $i).AdditionalProperties.userPrincipalName }
$ids = (Get-MgDevice -All).Id; foreach ($i in $ids){ (Get-MgDeviceRegisteredUser -DeviceId $i).AdditionalProperties.userPrincipalName }It is worth taking a closer look at the owners of Entra Applications (App Registrations) - owners and administrators of Applications may add secrets and authenticate as the associated service principal. If the service principal has a privileged role, you may impersonate the role:
# Application owners
(Get-MgApplicationOwner -ApplicationId IDIDID).AdditionalProperties.userPrincipalName
# Applications with existing credentials (opsec)
Get-MgApplication -All | ?{$_.PasswordCredentials -ne $null}
# Service principal properties and roles
Get-MgServicePrincipal -ServicePrincipalId IDIDID | fl *
Get-MgServicePrincipalMemberOf -ServicePrincipalId IDIDID
Get-MgDirectoryRole -DirectoryRoleId 6b83e066-a070-4a2d-82c9-fcf55b76ccf4Entirely separate from existing IAMs is Administrative Units. These are groups of users that may be administered through various permission by a select few users. RoadRecon will only show you the AU scope - NOT the users permitted to perform the actions or the associated privileges!
# List units
Get-MgDirectoryAdministrativeUnit | fl
# Retrieve membership and privileges for unit
Get-MgDirectoryAdministrativeUnitScopedRoleMember -AdministrativeUnitId 47e4803e-a5ef-4ebc-b967-691815870abd | Select-Object roleMemberInfo,roleId -ExpandProperty roleMemberInfo | fl
# Retrieve role information
Get-MgDirectoryRole -DirectoryRoleId 'ccb673b7-ab87-4fc0-87c5-39751a049539' | flAzure
The Azure API handles interactions with the Azure Resource Manager and requires a different token audience - management.azure.com. Keep in mind that this token audience only permits access to the management plane, not the data plane (you may not read key vault secrets, for instance).
# Authentication
az login
Connect-AzAccount -Tenant jotter.onmicrosoft.com
Connect-AzAccount -AccessToken $AzureToken -MicrosoftGraphAccessToken $GraphToken -AccountId jotter@jotter.onmicrosoft.com
# Whoami/Tokens
Get-AzContext
Get-AzAccessToken
# List ALL readable resources and role assignments
Get-AzResource
Get-AzRoleAssignmentCode execution on Azure applications can allow for the abuse of a service principal's role:
# Look for ManagedServiceIdentities
(Get-AzWebApp).Identity
(Get-AzFunctionApp).IdentityLast updated