Adversaries may be persisting on a host by triggering repeated alerts within a short time window, indicating potential lateral movement or sustained activity. SOC teams should proactively hunt for this behavior in Azure Sentinel to identify and mitigate long-term compromise or stealthy persistence tactics.
KQL Query
let GetAllAlertsOnHost = (suspiciousEventTime:datetime, v_Host:string){
//-3d and +6h as some alerts fire after accumulation of events
let v_StartTime = suspiciousEventTime-3d;
let v_EndTime = suspiciousEventTime+6h;
SecurityAlert
| where TimeGenerated between (v_StartTime .. v_EndTime)
// expand JSON properties
| extend Extprop = parse_json(ExtendedProperties)
| extend Computer = iff(isnotempty(toupper(tostring(Extprop["Compromised Host"]))), toupper(tostring(Extprop["Compromised Host"])), tostring(parse_json(Entities)[0].HostName))
| where Computer contains v_Host
| extend Account = iff(isnotempty(tolower(tostring(Extprop["User Name"]))), tolower(tostring(Extprop["User Name"])), tolower(tostring(Extprop["user name"])))
| extend IpAddress = tostring(parse_json(ExtendedProperties).["Client Address"])
| project TimeGenerated, AlertName, Computer, Account, IpAddress, ExtendedProperties
| extend timestamp = TimeGenerated, AccountCustomEntity = Account, HostCustomEntity = Computer, IPCustomEntity = IpAddress
};
// change datetime value and hostname value below
GetAllAlertsOnHost(datetime('2019-01-20T10:02:51.000'), toupper("<hostname>"))
id: 61a6edc0-e71a-4084-8f3c-05a58e1b9012
name: Alerts On Host
description: |
'Any Alerts that fired on a given host during the range of +6h and -3d'
requiredDataConnectors:
- connectorId: AzureSecurityCenter
dataTypes:
- SecurityAlert
- connectorId: MicrosoftCloudAppSecurity
dataTypes:
- SecurityAlert
tactics:
- Persistence
- Discovery
- LateralMovement
- Collection
query: |
let GetAllAlertsOnHost = (suspiciousEventTime:datetime, v_Host:string){
//-3d and +6h as some alerts fire after accumulation of events
let v_StartTime = suspiciousEventTime-3d;
let v_EndTime = suspiciousEventTime+6h;
SecurityAlert
| where TimeGenerated between (v_StartTime .. v_EndTime)
// expand JSON properties
| extend Extprop = parse_json(ExtendedProperties)
| extend Computer = iff(isnotempty(toupper(tostring(Extprop["Compromised Host"]))), toupper(tostring(Extprop["Compromised Host"])), tostring(parse_json(Entities)[0].HostName))
| where Computer contains v_Host
| extend Account = iff(isnotempty(tolower(tostring(Extprop["User Name"]))), tolower(tostring(Extprop["User Name"])), tolower(tostring(Extprop["user name"])))
| extend IpAddress = tostring(parse_json(ExtendedProperties).["Client Address"])
| project TimeGenerated, AlertName, Computer, Account, IpAddress, ExtendedProperties
| extend timestamp = TimeGenerated, AccountCustomEntity = Account, HostCustomEntity = Computer, IPCustomEntity = IpAddress
};
// change datetime value and hostname value below
GetAllAlertsOnHost(datetime('2019-01-20T10:02:51.000'), toupper("<hostname>"))
version: 1.0.0
metadata:
source:
kind: Community
author:
name: Shain
support:
tier: Community
categories:
domains: [ "Security - Other" ]
| Sentinel Table | Notes |
|---|---|
SecurityAlert | Ensure this data connector is enabled |
Scenario: A system administrator runs a scheduled log analysis tool (e.g., Splunk, ELK Stack) during routine maintenance.
Filter/Exclusion: Exclude hosts where the alert was triggered by known log analysis tools (e.g., process.name = "splunkd", process.name = "logstash").
Scenario: A security tool (e.g., CrowdStrike, SentinelOne) performs a full system scan or memory dump on a host.
Filter/Exclusion: Exclude hosts where the alert was triggered by endpoint detection and response (EDR) tools (e.g., process.name = "crowdstrike", process.name = "sentinelone").
Scenario: A backup job (e.g., Veeam, Commvault) is executed and generates a large number of temporary files or alerts.
Filter/Exclusion: Exclude hosts where the alert was triggered by backup processes (e.g., process.name = "veeambackup", process.name = "commvault").
Scenario: A system update or patching task (e.g., Windows Update, Ansible playbook) is running and causes temporary alert generation.
Filter/Exclusion: Exclude hosts where the alert was triggered by patching or update processes (e.g., process.name = "wuauclt", process.name = "ansible").
Scenario: A network monitoring tool (e.g., Wireshark, PRTG) is actively capturing traffic and generates alerts for unusual patterns.
Filter/Exclusion: Exclude hosts where the alert was triggered by network monitoring tools (e.g., process.name = "wireshark", process.name = "prtg").