Adversaries may be using a specific IP address to establish persistent access or exfiltrate data over an extended period. SOC teams should proactively hunt for this behavior in Azure Sentinel to identify potential long-term compromise and mitigate lateral movement risks.
KQL Query
let GetAllAlertsWithIp = (suspiciousEventTime:datetime, v_ipAddress: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(Entities)
| mv-expand Extprop
| extend Extprop = parse_json(Extprop)
| extend IpAddress = iff(Extprop["Type"] == "ip",Extprop['Address'], '')
| where IpAddress == v_ipAddress
| extend Account = Extprop['Name']
| extend Domain = Extprop['UPNSuffix']
| extend Account = iif(isnotempty(Domain) and Extprop['Type']=="account", tolower(strcat(Account, "@", Domain)), iif(Extprop['Type']=="account", tolower(Account), ""))
| extend Computer = iff(Extprop['Type']=="host", Extprop['HostName'], '')
| project StartTimeUtc = StartTime, EndTimeUtc = EndTime, AlertName, Computer, Account, IpAddress, ExtendedProperties, Entities
| extend timestamp = StartTimeUtc, AccountCustomEntity = Account, HostCustomEntity = Computer, IPCustomEntity = IpAddress
};
// change datetime value and <ipaddress> value below
GetAllAlertsWithIp(datetime('2019-02-05T10:02:51.000'), ("<ipaddress>"))
id: 0b520385-6a16-4e6f-ba89-c320d857695f
name: Alerts related to IP
description: |
'Any Alerts that fired related to a given IpAddress during the range of +6h and -3d'
requiredDataConnectors:
- connectorId: AzureSecurityCenter
dataTypes:
- SecurityAlert
- connectorId: MicrosoftCloudAppSecurity
dataTypes:
- SecurityAlert
tactics:
- Persistence
- Discovery
- LateralMovement
- Collection
query: |
let GetAllAlertsWithIp = (suspiciousEventTime:datetime, v_ipAddress: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(Entities)
| mv-expand Extprop
| extend Extprop = parse_json(Extprop)
| extend IpAddress = iff(Extprop["Type"] == "ip",Extprop['Address'], '')
| where IpAddress == v_ipAddress
| extend Account = Extprop['Name']
| extend Domain = Extprop['UPNSuffix']
| extend Account = iif(isnotempty(Domain) and Extprop['Type']=="account", tolower(strcat(Account, "@", Domain)), iif(Extprop['Type']=="account", tolower(Account), ""))
| extend Computer = iff(Extprop['Type']=="host", Extprop['HostName'], '')
| project StartTimeUtc = StartTime, EndTimeUtc = EndTime, AlertName, Computer, Account, IpAddress, ExtendedProperties, Entities
| extend timestamp = StartTimeUtc, AccountCustomEntity = Account, HostCustomEntity = Computer, IPCustomEntity = IpAddress
};
// change datetime value and <ipaddress> value below
GetAllAlertsWithIp(datetime('2019-02-05T10:02:51.000'), ("<ipaddress>"))
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: Scheduled System Maintenance Job
Description: A legitimate scheduled job (e.g., task scheduler or cron job) runs a maintenance script that connects to an external IP address (e.g., a cloud provider’s API) during the 6-hour window.
Filter/Exclusion: Exclude IP addresses associated with known cloud providers (e.g., AWS, Azure, GCP) or IPs used by internal maintenance scripts.
Scenario: Log Collection from SIEM Tools
Description: The SIEM tool (e.g., Splunk, ELK Stack, or QRadar) periodically connects to an external IP to sync logs or receive updates.
Filter/Exclusion: Exclude IPs used by SIEM tools or known log aggregation services.
Scenario: Admin Task with Remote Access
Description: An admin uses Remote Desktop Protocol (RDP) or SSH to connect to a server from a remote IP, which is logged as an alert.
Filter/Exclusion: Exclude IPs that belong to known admin workstations or use a whitelist of trusted admin IPs.
Scenario: Automated Patching or Update Process
Description: A patching tool (e.g., Windows Update, Ansible, or Chef) connects to an external IP to download updates.
Filter/Exclusion: Exclude IPs associated with known update servers or use a whitelist of trusted update sources.
Scenario: Internal Monitoring Tool Communication
Description: An internal monitoring tool (e.g., Nagios, Zabbix, or Prometheus) communicates with a remote IP to fetch metrics or status information.
Filter/Exclusion: Exclude IPs used by internal monitoring tools or use a whitelist of internal monitoring services.