<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: detecting-azure-lateral-movement
description: >-
  Detect lateral movement techniques in Azure environments including cross-subscription
  pivoting, managed identity abuse, Azure AD token theft, and service principal exploitation.
domain: cybersecurity
subdomain: cloud-security
tags:
  - azure
  - lateral-movement
  - entra-id
  - managed-identity
  - service-principal
  - sentinel
  - defender
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: ["T1021"]
---

# Detecting Azure Lateral Movement

## Overview

Azure lateral movement exploits interconnected identity systems — Entra ID (Azure AD),
managed identities, service principals, and cross-subscription RBAC. This skill covers
detection of post-compromise lateral movement through token theft, managed identity
abuse, cross-resource pivoting, and Azure-specific ATT&CK techniques with Sentinel
KQL queries and Defender for Cloud alerts.

Mode: `[MODE: PURPLE]` — Maps attack paths to detection rules.

## Prerequisites

- Azure CLI configured with Security Reader or higher
- Microsoft Sentinel workspace (recommended)
- Entra ID sign-in and audit logs enabled
- Defender for Cloud enabled
- Python 3.10+ with `azure-identity`, `azure-mgmt-authorization`

## Key Concepts

### Azure Lateral Movement Techniques

| Technique | ATT&CK | Description |
|-----------|--------|-------------|
| Managed Identity abuse | T1550.001 | Exploit VM/App Service managed identity for token |
| Service principal key theft | T1528 | Steal SP credentials for cross-resource access |
| Cross-subscription RBAC | T1078.004 | Leverage inherited permissions across subscriptions |
| Azure AD token replay | T1550.001 | Replay stolen OAuth tokens |
| Automation account abuse | T1078 | Exploit RunAs accounts in Automation |
| Key Vault secret access | T1552.007 | Access secrets for credential harvesting |
| Storage account key access | T1552 | Use storage keys to pivot to data |

### Managed Identity Token Theft Detection

```bash
# Check which resources have managed identities
az resource list --query "[?identity != null].{name:name, type:type, identity:identity.type}" --output table

# List VM managed identity assignments
az vm list --query "[].{name:name, identity:identity}" --output json

# KQL — Detect IMDS token requests from unusual processes
# AzureActivity
# | where OperationNameValue contains "MICROSOFT.COMPUTE/VIRTUALMACHINES"
# | where ActivityStatusValue == "Success"
# | where CallerIpAddress == "169.254.169.254"

# Check for OAuth token issuance anomalies
az monitor activity-log list --start-time "2026-03-10" \
  --query "[?authorization.action=='Microsoft.Authorization/roleAssignments/write']"
```

### Service Principal Monitoring

```bash
# List service principals with secrets/certificates
az ad sp list --all --query "[].{appId:appId, displayName:displayName, keyCredentials:keyCredentials}" --output json

# Find SPs with expiring credentials
az ad sp list --all --query "[?keyCredentials[?endDateTime < '2026-06-01']]" --output json

# Audit SP sign-in activity (requires Entra ID P1+)
# SigninLogs
# | where AppId in (SP_APP_IDS)
# | where ResultType != "0"
# | summarize FailedAttempts=count() by AppId, IPAddress, bin(TimeGenerated, 1h)
```

### Cross-Subscription Pivoting

```bash
# List role assignments across all subscriptions
az role assignment list --all --query "[?scope contains '/subscriptions/']" --output json

# Find users/SPs with access to multiple subscriptions
az role assignment list --all --output json | jq '
  group_by(.principalId) |
  map(select(length > 1)) |
  .[] | {
    principal: .[0].principalName,
    type: .[0].principalType,
    subscriptions: [.[].scope | split("/")[2]] | unique
  }' | jq 'select(.subscriptions | length > 1)'

# Check for Owner/Contributor on management group
az role assignment list --scope "/providers/Microsoft.Management/managementGroups/ROOT_MG" --output table
```

### Sentinel KQL Detection Rules

```kql
// Detect new role assignments at subscription level
AzureActivity
| where OperationNameValue == "Microsoft.Authorization/roleAssignments/write"
| where ActivityStatusValue == "Success"
| extend RoleDefinition = tostring(parse_json(Properties).requestbody)
| project TimeGenerated, Caller, CallerIpAddress, SubscriptionId, RoleDefinition

// Detect cross-subscription activity from single identity
AzureActivity
| where TimeGenerated > ago(7d)
| summarize Subscriptions=dcount(SubscriptionId), Operations=count() by Caller
| where Subscriptions > 2
| order by Subscriptions desc

// Detect Key Vault secret access anomalies
AzureDiagnostics
| where ResourceType == "VAULTS"
| where OperationName == "SecretGet"
| summarize SecretAccess=count() by CallerIPAddress, identity_claim_upn_s, bin(TimeGenerated, 1h)
| where SecretAccess > 20
```

## Workflow

### Step 1: Enumerate Identity Landscape

```bash
node scripts/agent.js --action enumerate --output /tmp/azure_identities.json
```

### Step 2: Detect Lateral Movement Indicators

```bash
node scripts/agent.js --action detect --days 7 --output /tmp/lateral_movement.json
```

### Step 3: Investigate

Review findings, correlate with Sentinel alerts, and trace attack path.

## Detection

```yaml
title: Azure Lateral Movement Detection
id: fafcafdb-bf53-46e3-b010-5d6d7fb22975
status: experimental
description: Detects suspicious activity related to detecting azure lateral movement techniques in cloud security context
logsource:
  product: aws
  service: cloudtrail
detection:
  selection:
    eventName: "*Unauthorized*"
  condition: selection
level: medium
tags:
  - attack.t1021
  - attack.credential_access
falsepositives:
  - Automated cloud infrastructure provisioning by approved CI/CD pipelines
```

## Verification

- [ ] Managed identity usage audited — no over-permissioned identities
- [ ] Service principal credentials rotated and monitored
- [ ] Cross-subscription RBAC follows least privilege
- [ ] Sentinel rules deployed for lateral movement detection
- [ ] Key Vault access logging and alerting enabled
- [ ] Conditional Access policies enforce location/device compliance
- [ ] No legacy authentication protocols enabled

## References

- [MITRE ATT&CK — Azure Matrix](https://attack.mitre.org/matrices/enterprise/cloud/azuread/)
- [Microsoft Sentinel Detection Rules](https://github.com/Azure/Azure-Sentinel/tree/master/Detections)
- [Azure Identity Security Best Practices](https://learn.microsoft.com/en-us/azure/security/fundamentals/identity-management-best-practices)
- [Defender for Cloud Alerts Reference](https://learn.microsoft.com/en-us/azure/defender-for-cloud/alerts-reference)
