Attack-path data collection
Collect the Entra ID and Azure identity / resource graph for offline attack-path analysis in BloodHound. Our tool of choice is AzureHound, which enumerates tenants, subscriptions, users, groups, role assignments, applications, service principals, devices, key vaults, virtual machines, and the relationships between them, and writes a JSON file that can be ingested into BloodHound CE / Enterprise.
AzureHound
AzureHound needs a token (or refresh token) for the target tenant. The recommended approach during an engagement is the device code flow. We authenticate interactively as the assessment account on their own browser/device, then hand the resulting refresh token to azurehound.exe. No password is ever typed into the host running the collector.
Prerequisites
- A user account in the target tenant with at least standard directory read permissions (Global Reader is ideal).
- Outbound HTTPS to
login.microsoftonline.comandgraph.microsoft.comfrom the host running AzureHound. - AzureHound binary. Pull a release from the GitHub repo.
Authentication: device code flow
We use the public Azure PowerShell client ID (1950a258-227b-4e31-a9cf-717495945fc2), which already has the directory-read scopes pre-consented in most tenants, so we don't have to admin-consent a fresh app.
Device code flow is also a known phishing primitive. The same three steps below, sent to a victim, are the basis of device code phishing. When using it for legitimate enumeration, only ever paste the device code into a browser you control.
Step 1: Request a device code
$body = @{
"client_id" = "1950a258-227b-4e31-a9cf-717495945fc2"
"resource" = "https://graph.microsoft.com"
}
$Headers = @{
"User-Agent" = "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"
}
$authResponse = Invoke-RestMethod `
-UseBasicParsing `
-Method Post `
-Uri "https://login.microsoftonline.com/common/oauth2/devicecode?api-version=1.0" `
-Headers $Headers `
-Body $body
$authResponseThe response contains a user_code and a verification_url (https://microsoft.com/devicelogin). Browse to the URL, enter the code, and sign in as the assessment user.
Step 2: Poll for tokens
After completing sign-in in the browser, exchange the device code for 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
$TokensExpected (truncated) response:
token_type : Bearer
scope : Application.ReadWrite.All AppRoleAssignment.ReadWrite.All
AuditLog.Read.All DelegatedPermissionGrant.ReadWrite.All
Directory.AccessAsUser.All Group.ReadWrite.All User.Read.All
expires_in : 4212
ext_expires_in : 4212
resource : https://graph.microsoft.com
access_token : <jwt>
refresh_token : <refresh-token>
id_token : <jwt>Step 3: Save the refresh token
AzureHound takes a refresh token so it can mint fresh access tokens as collection runs.
$token = "<refresh-token>"Run AzureHound
.\azurehound.exe -r $token list --tenant "example.onmicrosoft.com" -o output.json-r $token: refresh token from step 3.--tenant: the target tenant's verified domain (e.g.example.onmicrosoft.com) or tenant ID GUID.-o output.json: collector output, ready to ingest into BloodHound.
Collection time scales with directory size, it may take longer if there are many subscriptions / resource groups to walk.
Ingest into BloodHound
- BloodHound CE: drop
output.jsoninto the file ingest UI. - For attack-path queries combining on-prem AD + Entra (e.g. on-prem admins synced to a Global Admin cloud role), make sure both the SharpHound and AzureHound datasets are imported into the same instance. See AD enumeration / BloodHound.