Listen to this Post

Introduction:
For years, security teams struggled to gain visibility into legacy Azure Active Directory Graph API interactions, leaving a critical blind spot in identity-based threat detection. With Microsoft finally releasing Azure AD Graph activity logs (now in public preview), both red and blue teamers can monitor, detect, and exploit API calls that were previously invisible – enabling full-spectrum identity attack surface management.
Learning Objectives:
- Query Azure AD Graph activity logs using KQL to detect suspicious app consent grants and privilege escalation attempts.
- Simulate red team techniques (e.g., token replay, Graph API enumeration) and build detection rules for blue team defense.
- Implement cloud hardening controls and automate remediation workflows using Azure Monitor and Logic Apps.
You Should Know:
- Understanding Azure AD Graph Activity Logs – What’s Actually Being Tracked
Microsoft has extended diagnostic settings in Azure Monitor to include `AADGraphActivity` logs. These capture all HTTP requests to the legacy Azure AD Graph endpoint (graph.windows.net), including caller IP, user agent, application ID, requested URI, and response status codes.
Step‑by‑step guide to enable and query these logs:
- Azure Portal: Navigate to Azure AD → Diagnostic settings → Add diagnostic setting. Select `AADGraphActivity` and send to Log Analytics workspace.
- PowerShell (Azure module):
$workspace = Get-AzOperationalInsightsWorkspace -ResourceGroupName "RG-Security" $setting = New-AzDiagnosticSetting -ResourceId "/providers/Microsoft.AAD/domainServices/your-tenant" -Name "GraphLogs" -WorkspaceId $workspace.ResourceId -Category "AADGraphActivity" -Enabled $true
- Azure CLI:
az monitor diagnostic-settings create --resource /providers/Microsoft.AAD/domainServices/your-tenant --name GraphLogs --workspace /subscriptions/{sub}/resourceGroups/RG/providers/Microsoft.OperationalInsights/workspaces/LA --logs '[{"category":"AADGraphActivity","enabled":true}]'
KQL query to detect anomalous app enumeration:
AADGraphActivity | where OperationName == "Get applications" | summarize Count=count() by CallerIpAddress, UserAgent, AppId | where Count > 100 | order by Count desc
- Red Team Playbook: Abusing Graph API Visibility for Recon & Privilege Escalation
With logs now available, red teamers can test detection coverage. However, during an engagement, attackers will try to evade logging or blend in. Common techniques:
- Token replay from legacy applications: Use a stolen refresh token for a service principal that still calls
graph.windows.net. The log will show the app ID but not the original user. - Directory enumeration: Scripted calls to
/users,/groups, `/servicePrincipals` – now visible, but you can throttle to mimic legitimate sync tools.
Linux command to simulate low‑and‑slow enumeration (using `curl` and jq):
TOKEN="eyJ0eX..." OAuth token for legacy app
for i in {1..500}; do
curl -s -H "Authorization: Bearer $TOKEN" "https://graph.windows.net/myorganization/users?api-version=1.6" | jq '.value[].userPrincipalName'
sleep $(shuf -i 10-30 -n 1) random delay
done
Blue team countermeasure: Create anomaly detection rule in Microsoft Sentinel:
AADGraphActivity
| where UserAgent contains "curl" or UserAgent contains "python-requests"
| where OperationName in ("Get users", "Get groups")
| extend RequestCount = count() by CallerIpAddress, bin(TimeGenerated, 5m)
| where RequestCount > 20
- API Security Hardening: Migrate Off Legacy Graph to Microsoft Graph
The availability of logs highlights that Azure AD Graph is deprecated. Hardening steps:
- Discover all apps using Azure AD Graph: Run this PowerShell script:
Get-AzureADServicePrincipal -All $true | ForEach-Object { $perms = Get-AzureADServicePrincipalOAuth2PermissionGrant -ObjectId $<em>.ObjectId if ($perms.ResourceId -like "graph.windows.net") { $</em> } } - Block legacy authentication (including Azure AD Graph) via Conditional Access policy – set “Grant” control to “Require authenticated session” and exclude legacy client protocols.
- Replace endpoints: Update code from `https://graph.windows.net` to `https://graph.microsoft.com` (v1.0 or beta). Test with:
Old endpoint (being logged) curl -H "Authorization: Bearer $TOKEN" "https://graph.windows.net/tenant/users?api-version=1.6" New endpoint (preferred) curl -H "Authorization: Bearer $TOKEN" "https://graph.microsoft.com/v1.0/users"
- Building a Detection Engineering Lab with Azure AD Graph Logs
Use Azure Free Tier or a developer tenant to practice.
Step‑by‑step lab setup:
- Deploy a Log Analytics workspace and enable `AADGraphActivity` as above.
- Simulate a red team tool – e.g., using Stormspotter (Azure service principal enumeration) or ROADtools (Azure AD reconnaissance). Run `roadrecon gather –graph` to execute legacy calls.
3. Create Sentinel analytic rules:
- Rule name: “Excessive Azure AD Graph User enumeration”
- KQL query:
AADGraphActivity | where OperationName == "Get users" | summarize UserCount = dcount(TargetResources) by CallerIpAddress, bin(TimeGenerated, 5m) | where UserCount > 50
- Set alert frequency 5 minutes, threshold 1.
- Automate response: Use Logic App to isolate the suspicious app or block IP.
-
Vulnerability Mitigation: Misconfigured App Permissions & Consent Grants
Many organizations unknowingly granted “Read all users’ full profiles” to legacy apps via Azure AD Graph. Attackers exploit these to harvest email addresses for phishing.
Step‑by‑step mitigation workflow:
- List all OAuth2 permission grants for Azure AD Graph (run in PowerShell as Global Admin):
Connect-AzureAD $graphResources = Get-AzureADServicePrincipal -SearchString "Microsoft Graph" | Where-Object {$<em>.AppDisplayName -like "Graph"} $grants = Get-AzureADOAuth2PermissionGrant -All $true $grants | Where-Object {$</em>.ClientId -in $graphResources.AppId} | Format-Table ClientId, ConsentType, Scope - Review and revoke unnecessary grants using:
Remove-AzureADOAuth2PermissionGrant -ObjectId "<grant-id>"
- Enforce admin consent workflow in Azure AD → Enterprise applications → Consent and permissions.
- Monitor for new consent grants with KQL:
AADGraphActivity | where OperationName == "Consent to application" or OperationName == "OAuth2PermissionGrant" | extend GrantDetails = parse_json(Properties) | where GrantDetails.Scope contains "Directory.Read.All"
What Undercode Say:
- Azure AD Graph activity logs close a decade‑long visibility gap – every red team engagement must now assume legacy API calls are monitored.
- Blue teams can finally build deterministic detections for identity‑based attacks that previously went silent; start by alerting on high‑volume user enumeration and legacy user agents.
- The logs also serve as a wake‑up call: migrate off Azure AD Graph before Microsoft fully retires it (planned for 2026). Combine logging with conditional access policies to block legacy endpoints entirely.
Prediction:
Over the next 12 months, threat actors will shift to abusing newer Microsoft Graph APIs but with more sophisticated obfuscation (e.g., using delegated tokens from compromised mailboxes). Simultaneously, cloud detection engineering will standardize KQL hunting queries for Graph activity logs, leading to a new wave of community‑driven detection rules. Organizations that fail to enable and monitor Azure AD Graph logs will remain blind to a wide range of privilege escalation and reconnaissance techniques – making this feature a mandatory control for any mature identity security program.
▶️ Related Video (68% Match):
🎯Let’s Practice For Free:
IT/Security Reporter URL:
Reported By: Mehmetergene Historical – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅


