Skip to content

Commit 27cb036

Browse files
Merge branch 'main' into repo_sync_working_branch
2 parents 92fdc43 + 0a68a67 commit 27cb036

File tree

1 file changed

+24
-6
lines changed

1 file changed

+24
-6
lines changed

defender-xdr/advanced-hunting-best-practices.md

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,17 +201,35 @@ The [summarize operator](/azure/data-explorer/kusto/query/summarizeoperator) agg
201201
202202
Process IDs (PIDs) are recycled in Windows and reused for new processes. On their own, they can't serve as unique identifiers for specific processes.
203203
204-
To get a unique identifier for a process on a specific machine, use the process ID together with the process creation time. When you join or summarize data around processes, include columns for the machine identifier (either `DeviceId` or `DeviceName`), the process ID (`ProcessId` or `InitiatingProcessId`), and the process creation time (`ProcessCreationTime` or `InitiatingProcessCreationTime`)
204+
Usually, the only way to uniquely identify a process on a specific device was by combining its process ID with its process creation time, along with the device identifier (either `DeviceId` or `DeviceName`). While this approach is still valid, there’s a more direct method using the `ProcessUniqueId` field. Both methods yield unique process instances, but as a best practice we recommend using `ProcessUniqueId` when available, as it simplifies queries and eliminates the need to handle PID reuse scenarios.
205205
206-
The following example query finds processes that access more than 10 IP addresses over port 445 (SMB), possibly scanning for file shares.
206+
This query demonstrates how to use the `ProcessUniqueId` and `InitiatingProcessUniqueId` fields to link a specific parent process to its child processes. By matching each child’s `InitiatingProcessUniqueId` to the parent’s `ProcessUniqueId`, it isolates only those child processes launched by that exact parent instance, even if process IDs get reused over time.
207207
208208
Example query:
209209
210210
```kusto
211-
DeviceNetworkEvents
212-
| where RemotePort == 445 and Timestamp > ago(12h) and InitiatingProcessId !in (0, 4)
213-
| summarize RemoteIPCount=dcount(RemoteIP) by DeviceName, InitiatingProcessId, InitiatingProcessCreationTime, InitiatingProcessFileName
214-
| where RemoteIPCount > 10
211+
// Step 1: Select a specific parent process instance (for instance, powershell.exe).
212+
let parentProcess =
213+
DeviceProcessEvents
214+
| where FileName =~ "powershell.exe" // For your specific use case, consider modifying the FileName and adding more identifying properties to specify your query.
215+
| where isnotempty(ProcessUniqueId)
216+
| top 1 by Timestamp asc
217+
| project DeviceId, DeviceName, ParentProcessUniqueId = ProcessUniqueId, ParentFileName = FileName;
218+
// Step 2: Find all child processes started by this unique parent.
219+
DeviceProcessEvents
220+
| where isnotempty(InitiatingProcessUniqueId)
221+
| join kind=inner (
222+
parentProcess
223+
) on DeviceId
224+
| where InitiatingProcessUniqueId == ParentProcessUniqueId
225+
| project
226+
DeviceName,
227+
ParentProcessUniqueId,
228+
ParentFileName,
229+
ChildProcessName = FileName,
230+
ChildProcessId = ProcessId,
231+
ChildProcessUniqueId = ProcessUniqueId,
232+
Timestamp
215233
```
216234

217235
The query summarizes by both `InitiatingProcessId` and `InitiatingProcessCreationTime` so that it looks at a single process, without mixing multiple processes with the same process ID.

0 commit comments

Comments
 (0)