The Device Had No Malware — But Its DNS Requests Told the Story
The device looked clean.
No obvious malware detection.
No suspicious executable sitting in quarantine.
No dramatic endpoint alert explaining what had happened.
It would have been easy to close the investigation.
Then Agent Foskett looked at the network activity.
The device kept reaching out to a domain nobody recognised.
Again.
And again.
And again.
The malware alert was missing. The network story wasn't.
The Network Still Had Evidence
A device does not need an active malware alert for its network behaviour to deserve investigation. Defender XDR can connect remote domains and IP addresses back to the processes that initiated the traffic.
No malware detection did not mean no suspicious activity
Build the device network timeline
DeviceNetworkEvents is the starting point. Review the remote URL, remote IP, port, protocol and initiating process together. Depending on the event and telemetry available, RemoteUrl can provide hostname or domain context associated with the connection; do not assume every row represents a raw DNS query.- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
let Device = "LAPTOP-042";
DeviceNetworkEvents
| where Timestamp > ago(7d)
| where DeviceName =~ Device
| project Timestamp,
ActionType,
RemoteUrl,
RemoteIP,
RemotePort,
Protocol,
InitiatingProcessFileName,
InitiatingProcessCommandLine
| order by Timestamp asc
Which domains keep appearing?
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
let Device = "LAPTOP-042";
DeviceNetworkEvents
| where Timestamp > ago(7d)
| where DeviceName =~ Device
| where isnotempty(RemoteUrl)
| summarize Connections=count(),
FirstSeen=min(Timestamp),
LastSeen=max(Timestamp),
Processes=make_set(InitiatingProcessFileName, 20)
by RemoteUrl
| order by Connections desc
Follow the suspicious domain back to the process
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
let Device = "LAPTOP-042";
let Domain = "example-suspicious-domain.test";
DeviceNetworkEvents
| where Timestamp > ago(7d)
| where DeviceName =~ Device
| where RemoteUrl =~ Domain
| project Timestamp,
RemoteUrl,
RemoteIP,
RemotePort,
InitiatingProcessFileName,
InitiatingProcessId,
InitiatingProcessCommandLine,
InitiatingProcessSHA1
| order by Timestamp asc
The process mattered more than the domain alone
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
let Device = "LAPTOP-042";
let ProcessIdToCheck = 6420;
DeviceProcessEvents
| where Timestamp > ago(7d)
| where DeviceName =~ Device
| where ProcessId == ProcessIdToCheck
| project Timestamp,
FileName,
FolderPath,
SHA1,
ProcessCommandLine,
AccountName,
InitiatingProcessFileName,
InitiatingProcessCommandLine
| order by Timestamp asc
Now scope the destination across the environment
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
let Domain = "example-suspicious-domain.test";
DeviceNetworkEvents
| where Timestamp > ago(30d)
| where RemoteUrl =~ Domain
| summarize Connections=count(),
FirstSeen=min(Timestamp),
LastSeen=max(Timestamp),
Devices=dcount(DeviceName),
Processes=make_set(InitiatingProcessFileName, 20)
by RemoteUrl
| order by Connections desc
Rare does not mean malicious
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
DeviceNetworkEvents
| where Timestamp > ago(30d)
| where isnotempty(RemoteUrl)
| summarize Connections=count(),
Devices=dcount(DeviceName),
FirstSeen=min(Timestamp),
LastSeen=max(Timestamp),
Processes=make_set(InitiatingProcessFileName, 20)
by RemoteUrl
| where Devices <= 2
| order by Connections desc
DNS evidence needs careful wording
DeviceNetworkEvents row as a DNS lookup. If dedicated DNS telemetry is available elsewhere in the environment, correlate it. Otherwise describe exactly what Defender recorded: the destination and the process associated with the network event.
