An adversary may be using an internal IP address to mask their activity and evade detection by blending in with legitimate internal traffic. SOC teams should proactively hunt for this behavior in Azure Sentinel to identify potential lateral movement or data exfiltration attempts hidden within internal network communications.
KQL Query
let PivotTime = datetime(2021-01-02 20:57:02); //Fill out time
let TimeRangeStart = PivotTime-15m; // 15 Minutes Prior to Pivot Time
let TimeRangeEnd = PivotTime+15m; // 15 Minutes After Pivot Time
let IPAddress = "172.16.40.8"; // internal IP address to search
// Locate DeviceIds associated with IP
let FindDeviceIdbyIP = DeviceNetworkInfo
| where Timestamp between ((TimeRangeStart) ..TimeRangeEnd)
and IPAddresses contains strcat("\"", IPAddress, "\"")
and NetworkAdapterStatus == "Up"
| project DeviceName, DeviceId, Timestamp, IPAddresses;
// Query Alerts matching DeviceIds
FindDeviceIdbyIP
| join kind=rightsemi AlertEvidence on DeviceId
| join AlertInfo on AlertId
// Summarizes alerts by AlertId with min and max event times
| summarize Title=any(Title), min(Timestamp), max(Timestamp), DeviceName=any(DeviceName) by AlertId
id: f936ddfa-58e3-4db1-834b-fb50e8bd55c5
name: Alert Events from Internal IP Address
description: |
Determines DeviceId from internal IP address and outputs all alerts in events table associated to the DeviceId.
Example use case is Firewall determines Internal IP with suspicious network activity. Query WDATP based on date/time and Internal IP and see associated alerts for the endpoint.
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
dataTypes:
- DeviceNetworkInfo
- AlertEvidence
- AlertInfo
query: |
let PivotTime = datetime(2021-01-02 20:57:02); //Fill out time
let TimeRangeStart = PivotTime-15m; // 15 Minutes Prior to Pivot Time
let TimeRangeEnd = PivotTime+15m; // 15 Minutes After Pivot Time
let IPAddress = "172.16.40.8"; // internal IP address to search
// Locate DeviceIds associated with IP
let FindDeviceIdbyIP = DeviceNetworkInfo
| where Timestamp between ((TimeRangeStart) ..TimeRangeEnd)
and IPAddresses contains strcat("\"", IPAddress, "\"")
and NetworkAdapterStatus == "Up"
| project DeviceName, DeviceId, Timestamp, IPAddresses;
// Query Alerts matching DeviceIds
FindDeviceIdbyIP
| join kind=rightsemi AlertEvidence on DeviceId
| join AlertInfo on AlertId
// Summarizes alerts by AlertId with min and max event times
| summarize Title=any(Title), min(Timestamp), max(Timestamp), DeviceName=any(DeviceName) by AlertId
| Sentinel Table | Notes |
|---|---|
AlertEvidence | Ensure this data connector is enabled |
Scenario: Scheduled system maintenance or patching using internal IP
Filter/Exclusion: Exclude events where the source IP is associated with a known maintenance window or system update job (e.g., source_ip = 10.0.0.5 and event_type = "patching")
Scenario: Internal monitoring tool (e.g., Prometheus, Nagios) sending alerts from internal IP
Filter/Exclusion: Exclude events where the source IP is associated with a monitoring tool (e.g., source_ip = 10.10.0.10 and tool_name = "Nagios")
Scenario: Log collection agent (e.g., Fluentd, Logstash) forwarding logs from internal IP
Filter/Exclusion: Exclude events where the source IP is associated with a log collection agent (e.g., source_ip = 10.20.0.20 and agent_type = "Fluentd")
Scenario: Internal backup job (e.g., Veeam, Bacula) using internal IP for data transfer
Filter/Exclusion: Exclude events where the source IP is associated with a backup job (e.g., source_ip = 10.30.0.30 and job_type = "backup")
Scenario: Internal DNS resolution or Active Directory query from internal IP
Filter/Exclusion: Exclude events where the source IP is associated with internal DNS or AD queries (e.g., source_ip = 10.40.0.40 and dns_query = true)