Query Details

EEG Trace Lateral Movement

Query

# Trace Lateral Movement

## Query Information

### Description

This multi-hop query simulates an attacker moving from one compromised resource to another

#### References

- [Performing Advanced Risk Hunting in Defender for Cloud](https://techcommunity.microsoft.com/blog/microsoftdefendercloudblog/performing-advanced-risk-hunting-in-defender-for-cloud/4420633)

### Author

- **Microsoft**

## Defender XDR

```kql
// Step 1: Identify High-Risk Azure VMs with High-Severity Vulnerabilities
let HighRiskVMs =
    ExposureGraphNodes
    | where NodeLabel == "microsoft.compute/virtualmachines"
    | extend NodeProps = parse_json(NodeProperties)
    | extend RawData = parse_json(tostring(NodeProps.rawData))  // Parse rawData as JSON
    | extend VulnerabilitiesData = parse_json(tostring(RawData.hasHighSeverityVulnerabilities))  // Extract nested JSON
    | where toint(VulnerabilitiesData.data['count']) > 0  // Filter VMs with count > 0
    | project VMId = NodeId, VMName = NodeName, VulnerabilityCount = VulnerabilitiesData.data['count'], NodeProperties;
// Step 2: Identify Critical Storage Accounts with Sensitive Data
let CriticalStorageAccounts =
    ExposureGraphNodes
    | where NodeLabel == "microsoft.storage/storageaccounts"
    | extend NodeProps = parse_json(NodeProperties)
    | extend RawData = parse_json(tostring(NodeProps.rawData))  // Parse rawData as JSON
    | where RawData.containsSensitiveData == "true"  // Check for sensitive data
    | project StorageAccountId = NodeId, StorageAccountName = NodeName;
// Step 3: Find Lateral Movement Paths from High-Risk VMs to Critical Storage Accounts
let LateralMovementPaths =
    ExposureGraphEdges
    | where EdgeLabel in ("has role on", "has permissions to", "can authenticate to")  // Paths that allow access
    | project SourceNodeId, SourceNodeName, SourceNodeLabel, TargetNodeId, TargetNodeName, EdgeLabel;
// Step 4: Correlate High-Risk VMs with Storage Accounts They Can Access
HighRiskVMs
| join kind=inner LateralMovementPaths on $left.VMId == $right.SourceNodeId
| join kind=inner CriticalStorageAccounts on $left.TargetNodeId == $right.StorageAccountId
| project VMName, StorageAccountName = TargetNodeName, EdgeLabel, VulnerabilityCount
| order by VMName asc
```

Explanation

This query is designed to simulate and trace potential lateral movement by an attacker within a cloud environment, specifically focusing on Azure resources. Here's a simplified breakdown of what each step in the query does:

  1. Identify High-Risk Azure Virtual Machines (VMs):

    • The query first identifies Azure VMs that are considered high-risk due to having high-severity vulnerabilities. It extracts and counts these vulnerabilities for each VM.
  2. Identify Critical Storage Accounts:

    • Next, it identifies Azure Storage Accounts that contain sensitive data, marking them as critical.
  3. Find Potential Lateral Movement Paths:

    • It then looks for possible paths that an attacker could use to move from the high-risk VMs to the critical storage accounts. These paths are based on roles, permissions, or authentication capabilities that connect the resources.
  4. Correlate High-Risk VMs with Accessible Storage Accounts:

    • Finally, the query correlates the high-risk VMs with the critical storage accounts they can potentially access through the identified paths. It lists the VM names, the storage account names they can access, the type of access path, and the count of vulnerabilities for each VM.

The result is an ordered list of VMs and the storage accounts they can access, highlighting potential security risks and lateral movement opportunities within the cloud environment.

Details

Alex Verboon profile picture

Alex Verboon

Released: June 29, 2025

Tables

ExposureGraphNodesExposureGraphEdges

Keywords

ExposuregraphnodesMicrosoftComputeVirtualmachinesNodepropertiesRawdataVulnerabilitiesdataExposuregraphedges

Operators

letwhereextendparse_jsontostringtointprojectinjoinonorder byasc

Actions