Identify Patient Zero (First Compromised System)
Trace the earliest indicators back to the first compromised host or account. This anchors the investigation and determines the initial attack vector.
Actions
- 1
Pivot from the earliest IOC timestamp to identify the originating host: correlate source IPs, user accounts, and process trees across EDR telemetry.
- 2
Run Velociraptor artifact `Windows.EventLogs.Evtx` with a time filter around T-start on candidate hosts to find logon events (4624 Type 3/10), service installations (7045), and scheduled task creation (4698).
- 3
Check email logs for the earliest malicious delivery if phishing is suspected: `sourcetype=o365:messageTrace | search directionality=Inbound status=Delivered | where _time >= T_start | stats earliest(_time) by sender, recipient, subject`.
- 4
Examine DNS query logs for the earliest callback to known C2 infrastructure: `sourcetype=dns query IN (ioc_domain_list) | stats earliest(_time) as first_beacon by src_ip, query`.
- 5
Build a process execution timeline on the candidate patient-zero host using KAPE: `kape.exe --tsource C: --tdest \\share\case\host01 --tflush --target !SANS_Triage`.
- 6
Examine UserAssist registry keys on candidate hosts for evidence of GUI-based program execution: parse `NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist` with `UserAssistParser`. Entries record run count, focus time, and last execution timestamp -- useful for identifying attacker interaction via RDP.
- 7
Check Windows Defender detection history for early alerts that may have been auto-remediated and overlooked: parse `C:\ProgramData\Microsoft\Windows Defender\Scans\History\DetectionHistory\` and review MPLog at `C:\ProgramData\Microsoft\Windows Defender\Support\MPLog-*.log` for timestamps of blocked threats.
Queries
DeviceLogonEvents | where Timestamp between (datetime(T_START) .. datetime(T_END)) | where LogonType in ("RemoteInteractive", "Network", "NewCredentials") | summarize FirstLogon=min(Timestamp), LogonCount=count() by DeviceName, AccountName, RemoteIP, LogonType | order by FirstLogon asc | take 50index=proxy sourcetype=bluecoat OR sourcetype=zscaler dest IN (ioc_ip_list) OR url IN (ioc_url_list) | stats earliest(_time) as first_contact count by src_ip, dest, url, user | sort first_contact
EmailEvents | where Timestamp > ago(30d) | where DeliveryAction == "Delivered" | join kind=inner (EmailAttachmentInfo | where FileType in ("exe","dll","js","vbs","hta","iso","img")) on NetworkMessageId | summarize Earliest=min(Timestamp) by SenderFromAddress, RecipientEmailAddress, Subject, FileName | order by Earliest ascindex=wineventlog sourcetype=WinEventLog:Security EventCode=4624 Logon_Type IN (3,10) earliest=T_START latest=T_END | stats earliest(_time) as first_logon count by src_ip, Account_Name, ComputerName, Logon_Type | sort first_logon | head 50
Notes
Patient zero may not be the most visibly compromised host -- attackers often pivot quickly. Look for the quietest host with the earliest timestamp.
If multiple hosts show near-simultaneous compromise, suspect a supply chain or watering hole vector rather than lateral movement.
Check SRUM (System Resource Usage Monitor) at `C:\Windows\System32\sru\SRUDB.dat` for network usage spikes correlated with initial compromise. SRUM records hourly app-level network bytes sent/received for 30-60 days, even if the process has been deleted.