The USB Drive Was Never Meant To Be Found
It was lying in the staff car park.
No label. No owner. Just a black USB drive beside the driver's door. Someone picked it up. Someone plugged it in. Windows Defender stayed quiet, and nothing obvious appeared to happen.
Five minutes later PowerShell started. A scheduled task was created. Persistence had begun.
Agent Foskett was not interested in the USB drive itself. He wanted to know everything that happened after it was inserted.

Briefing summary
A suspicious USB drive does not need to drop obvious malware to create risk. The real evidence appears in the timeline: removable media activity, process execution, file writes, registry changes and persistence.
The USB was not the attack
What Defender XDR can show
Find USB related events
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
DeviceEvents
| where Timestamp > ago(30d)
| where ActionType has_any (
"Usb",
"Removable",
"PnP",
"Storage",
"Drive"
)
| project
Timestamp,
DeviceName,
ActionType,
InitiatingProcessAccountName,
InitiatingProcessFileName,
AdditionalFields
| order by Timestamp desc
Follow the first five minutes
Look for PowerShell after USB activity
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
DeviceProcessEvents
| where Timestamp > ago(30d)
| where FileName in~ ("powershell.exe", "pwsh.exe", "cmd.exe", "wscript.exe", "cscript.exe", "mshta.exe", "rundll32.exe")
| project
Timestamp,
DeviceName,
AccountName,
InitiatingProcessFileName,
InitiatingProcessCommandLine,
FileName,
ProcessCommandLine
| order by Timestamp desc
Persistence rarely announces itself
Review scheduled task creation
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
DeviceEvents
| where Timestamp > ago(30d)
| where ActionType has_any ("ScheduledTaskCreated", "ScheduledTaskUpdated")
or InitiatingProcessCommandLine has_any ("schtasks", "Schedule.Service")
| project
Timestamp,
DeviceName,
ActionType,
InitiatingProcessAccountName,
InitiatingProcessFileName,
InitiatingProcessCommandLine,
AdditionalFields
| order by Timestamp desc
Hunt for registry persistence
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
DeviceRegistryEvents
| where Timestamp > ago(30d)
| where RegistryKey has_any (
@"\Software\Microsoft\Windows\CurrentVersion\Run",
@"\Software\Microsoft\Windows\CurrentVersion\RunOnce",
@"\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run"
)
| project
Timestamp,
DeviceName,
ActionType,
RegistryKey,
RegistryValueName,
RegistryValueData,
InitiatingProcessFileName,
InitiatingProcessCommandLine
| order by Timestamp desc
What investigators should ask
Look for suspicious file writes
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
DeviceFileEvents
| where Timestamp > ago(30d)
| where ActionType in~ ("FileCreated", "FileModified", "FileRenamed")
| where FolderPath has_any ("\Users\", "\AppData\", "\Temp\", "\ProgramData\", "\Startup\")
| where FileName has_any (".ps1", ".vbs", ".js", ".lnk", ".bat", ".cmd", ".exe", ".dll")
| project
Timestamp,
DeviceName,
ActionType,
FolderPath,
FileName,
SHA256,
InitiatingProcessFileName,
InitiatingProcessCommandLine
| order by Timestamp desc
Build the endpoint timeline
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
let InvestigationDevice = "DEVICE-NAME-HERE";
let StartTime = ago(1d);
union isfuzzy=true
(
DeviceEvents
| where Timestamp > StartTime
| where DeviceName =~ InvestigationDevice
| project Timestamp, DeviceName, EvidenceType="DeviceEvent", ActionType, Detail=tostring(AdditionalFields), InitiatingProcessFileName, InitiatingProcessCommandLine
),
(
DeviceProcessEvents
| where Timestamp > StartTime
| where DeviceName =~ InvestigationDevice
| project Timestamp, DeviceName, EvidenceType="Process", ActionType, Detail=ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine
),
(
DeviceFileEvents
| where Timestamp > StartTime
| where DeviceName =~ InvestigationDevice
| project Timestamp, DeviceName, EvidenceType="File", ActionType, Detail=FolderPath, InitiatingProcessFileName, InitiatingProcessCommandLine
),
(
DeviceRegistryEvents
| where Timestamp > StartTime
| where DeviceName =~ InvestigationDevice
| project Timestamp, DeviceName, EvidenceType="Registry", ActionType, Detail=strcat(RegistryKey, " ", RegistryValueName, " ", RegistryValueData), InitiatingProcessFileName, InitiatingProcessCommandLine
)
| order by Timestamp asc
The attacker wanted behaviour, not magic
Related investigations
Final thought
The USB Drive Was Never Meant To Be Found
This Agent Foskett investigation explains how a suspicious USB drive can lead to PowerShell execution, scheduled task persistence, registry changes and endpoint compromise.
Microsoft Defender XDR USB Investigation
DeviceEvents, DeviceProcessEvents, DeviceFileEvents and DeviceRegistryEvents can help defenders reconstruct removable media investigations and identify suspicious endpoint behaviour.
KQL Hunting For USB Malware And Endpoint Persistence
Defenders can use KQL to hunt for USB activity, suspicious PowerShell, scheduled tasks, registry run keys, file writes, LOLBins and post-compromise persistence in Microsoft Defender XDR.
