| name | detecting-azure-lateral-movement |
| description | Detect lateral movement in Azure AD/Entra ID environments using Microsoft Graph API audit logs, Azure Sentinel KQL hunting queries, and sign-in anomaly correlation to identify privilege escalation, token theft, and cross-tenant pivoting. |
| domain | cybersecurity |
| subdomain | cloud-security |
| tags | ["azure","entra-id","lateral-movement","sentinel","kql","graph-api","cloud-security","threat-hunting"] |
| version | 1.0 |
| author | mahipal |
| license | Apache-2.0 |
| nist_csf | ["PR.IR-01","ID.AM-08","GV.SC-06","DE.CM-01"] |
Detecting Azure Lateral Movement
Overview
Lateral movement in Azure AD/Entra ID differs from on-premises environments. Attackers pivot through OAuth application consent grants, service principal abuse, cross-tenant access policies, and stolen refresh tokens rather than SMB/RDP connections. Detection requires correlating Microsoft Graph API audit logs, Azure AD sign-in logs, and Entra ID protection risk events using KQL queries in Microsoft Sentinel. This skill covers building detection analytics for common Azure lateral movement techniques including application impersonation, mailbox delegation abuse, and conditional access policy bypasses.
When to Use
- When investigating security incidents that require detecting azure lateral movement
- When building detection rules or threat hunting queries for this domain
- When SOC analysts need structured procedures for this analysis type
- When validating security monitoring coverage for related attack techniques
Detection Gaps & Validation
Common evasions / false-negatives that defeat these KQL analytics:
- Watching only
SigninLogs. Refresh-token and PRT replay land in AADNonInteractiveUserSignInLogs; app-only pivots land in AADServicePrincipalSignInLogs. Interactive-only queries miss both.
- Cross-tenant B2B pivots show
ResultType == 0 with ResourceTenantId != HomeTenantId — filter on the tenant mismatch, not just location.
- Mailbox delegation abuse (
Add-MailboxPermission FullAccess/SendAs, Add delegated permission grant) is in the Office 365 / Exchange audit feed, not Entra AuditLogs.
- Credential-add detail is buried in
TargetResources[0].modifiedProperties[*].newValue (KeyDescription / KeyType) — keying only on OperationName misses cert-based persistence.
Validate the rule actually fires:
union withsource=Tbl AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs, SigninLogs
| summarize rows=count() by Tbl // any 0 = diagnostic setting missing, rule is silently dead
- Tune FP by baselining each service principal's sign-in IP/location over 14+ days before alerting on "new" location, and exclude managed-identity object IDs and known automation egress IPs.
Prerequisites
- Azure subscription with Microsoft Sentinel workspace configured