↳ GitHub sourceAnalytics ruleMedium

Suspicious VM Instance Creation Activity Detected

Description

'This detection identifies high-severity alerts across various Microsoft security products, including Microsoft Defender XDR and Microsoft Entra ID, and correlates them with instances of Google Cloud VM creation. It focuses on instances where VMs were created within a short timeframe of high-severity alerts, potentially indicating suspicious activity.'
Rule type
Scheduled
Version
1.0.4
Query frequency
1d
Query period
1d
Trigger
gt 0

Declared MITRE coverage

Declared sources

Metadata from the source file. No dependencies inferred from KQL.

Connectors

Data types

KQL query

Original query, unchanged.

// Filter alerts from specific Microsoft security products with medium and high severity
SecurityAlert 
| where ProductName in ("Microsoft 365 Defender", "Azure Active Directory", "Microsoft Defender Advanced Threat Protection", "Microsoft Cloud App Security", "Azure Active Directory Identity Protection", "Microsoft Defender ATP")
| where AlertSeverity has_any ("Medium", "High")
// Parse JSON entities and extend AlertTimeGenerated
| extend Entities = parse_json(Entities), AlertTimeGenerated=TimeGenerated
// Extract and process IP entities
| mv-apply Entity = Entities on 
    ( 
    where Entity.Type == 'ip' 
    | extend EntityIp = tostring(Entity.Address) 
    ) 
// Extract and process account entities
| mv-apply Entity = Entities on 
    ( 
    where Entity.Type == 'account' 
    | extend AccountObjectId = tostring(Entity.AadUserId)
    )
// Filter out records with empty EntityIp
| where isnotempty(EntityIp)
// Summarize data and create sets of entities and system alert IDs
| summarize Entitys=make_set(Entity), SystemAlertIds=make_set(SystemAlertId)
    by 
    AlertName,
    ProductName,
    AlertSeverity,
    EntityIp,
    Tactics,
    Techniques,
    ProviderName,
    AlertTime= bin(AlertTimeGenerated, 1d),
    AccountObjectId
// Join with GCPAuditLogs for VM instance creation
| join kind=inner (
    GCPAuditLogs
    | where ServiceName == "compute.googleapis.com" and MethodName endswith "instances.insert"
    | extend
        GCPUserUPN= tostring(parse_json(AuthenticationInfo).principalEmail),
        GCPUserIp = tostring(parse_json(RequestMetadata).callerIp),
        GCPUserUA= tostring(parse_json(RequestMetadata).callerSuppliedUserAgent),
        VMStatus =  tostring(parse_json(Response).status),
        VMOperation=tostring(parse_json(Response).operationType),
        VMName= tostring(parse_json(Request).name),
        VMType = tostring(split(parse_json(Request).machineType, "/")[-1])
    | where GCPUserUPN !has "gserviceaccount.com"
    | where VMOperation == "insert" and isnotempty(GCPUserIp) and GCPUserIp != "private"
    | project
        GCPOperationTime=TimeGenerated,
        VMName,
        VMStatus,
        MethodName,
        GCPUserUPN,
        ProjectId,
        GCPUserIp,
        GCPUserUA,
        VMOperation,
        VMType
    )
    on $left.EntityIp == $right.GCPUserIp 
// Join with IdentityInfo to enrich user identity details
| join kind=inner (IdentityInfo 
    | distinct AccountObjectId, AccountUPN, JobTitle
    )
    on AccountObjectId 
// Calculate the time difference between the alert and VM creation for further analysis
| extend TimeDiff= datetime_diff('day', AlertTime, GCPOperationTime),Name = split(GCPUserUPN, "@")[0], UPNSuffix = split(GCPUserUPN, "@")[1]

Declared entities

IPAccount

Related content

Links established from declared identifiers and solution manifests.

Source provenance

GitHub

Displayed values come from files in Azure/Azure-Sentinel. They describe the published template, not your workspace configuration.

Source identifier
1cc0ba27-c5ca-411a-a779-fbc89e26be83
Additional source files 1Detections/MultipleDataSources/SuspiciousVMInstanceCreationActivity.yamlsource ↗
GSTEP / CATALOG TRACKING

Added to catalog : 16 Sept 2026 · 05:49 UTC
Last change observed : 16 Sept 2026 · 05:49 UTC

GSTEP sync dates, separate from the source content’s publication dates.