Detection rules › Kusto
Files Copied to USB Drives
This query lists files copied to USB external drives with USB drive information based on FileCreated events associated with most recent USBDriveMount events befor file creations. But be aware that Advanced Hunting is not monitoring all the file types.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Exfiltration | T1041 Exfiltration Over C2 Channel |
Event coverage
| Provider | Event/ActionType | Title |
|---|---|---|
| Sysmon | Event ID 11 | FileCreate |
| Security-Auditing | Event ID 4663 | An attempt was made to access an object. |
| Defender-DeviceFileEvents | FileCreated | File created |
Rule body kusto
id: 3ab04acf-e0e7-4f7c-8995-748ab4c848c2
name: Files Copied to USB Drives
description: |
This query lists files copied to USB external drives with USB drive information based on FileCreated events associated with most recent USBDriveMount events befor file creations. But be aware that Advanced Hunting is not monitoring all the file types.
severity: High
status: Available
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
dataTypes:
- DeviceEvents
- DeviceFileEvents
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- Exfiltration
relevantTechniques:
- T1041
query: |
let UsbDriveMount = DeviceEvents
| where ActionType=="UsbDriveMounted"
| extend ParsedFields=parse_json(AdditionalFields)
| project DeviceId, DeviceName, DriveLetter=ParsedFields.DriveLetter, MountTime=TimeGenerated,
ProductName=ParsedFields.ProductName,SerialNumber=ParsedFields.SerialNumber,Manufacturer=ParsedFields.Manufacturer
| order by DeviceId asc, MountTime desc;
let FileCreation = DeviceFileEvents
| where InitiatingProcessAccountName != "system"
| where ActionType == "FileCreated"
| where FolderPath !startswith "C:\\"
| where FolderPath !startswith "\\"
| project ReportId,DeviceId,InitiatingProcessAccountDomain,
InitiatingProcessAccountName,InitiatingProcessAccountUpn,
FileName, FolderPath, SHA256, TimeGenerated, SensitivityLabel, IsAzureInfoProtectionApplied
| order by DeviceId asc, TimeGenerated desc;
FileCreation | lookup kind=inner (UsbDriveMount) on DeviceId
| where FolderPath startswith DriveLetter
| where TimeGenerated >= MountTime
| partition hint.strategy=native by ReportId ( top 1 by MountTime )
| order by DeviceId asc, TimeGenerated desc
| extend HostName = iff(DeviceName has '.', substring(DeviceName, 0, indexof(DeviceName, '.')), DeviceName)
| extend DnsDomain = iff(DeviceName has '.', substring(DeviceName, indexof(DeviceName, '.') + 1), "")
| extend FileHashAlgorithm = 'SHA256'
entityMappings:
- entityType: Host
fieldMappings:
- identifier: FullName
columnName: DeviceName
- identifier: HostName
columnName: HostName
- identifier: DnsDomain
columnName: DnsDomain
- entityType: File
fieldMappings:
- identifier: Name
columnName: FileName
- identifier: Directory
columnName: FolderPath
- entityType: FileHash
fieldMappings:
- identifier: Algorithm
columnName: FileHashAlgorithm
- identifier: Value
columnName: SHA256
version: 1.0.0
kind: Scheduled
Stages and Predicates
Let binding: UsbDriveMount
let UsbDriveMount = DeviceEvents
| where ActionType=="UsbDriveMounted"
| extend ParsedFields=parse_json(AdditionalFields)
| project DeviceId, DeviceName, DriveLetter=ParsedFields.DriveLetter, MountTime=TimeGenerated,
ProductName=ParsedFields.ProductName,SerialNumber=ParsedFields.SerialNumber,Manufacturer=ParsedFields.Manufacturer
| order by DeviceId asc, MountTime desc;
The stages below define let FileCreation (the rule's main pipeline source).
Stage 1: source
DeviceFileEvents
Stage 2: where
| where InitiatingProcessAccountName != "system"
Stage 3: where
| where ActionType == "FileCreated"
Stage 4: where
| where FolderPath !startswith "C:\\"
Stage 5: where
| where FolderPath !startswith "\\"
Stage 6: project
| project ReportId,DeviceId,InitiatingProcessAccountDomain,
InitiatingProcessAccountName,InitiatingProcessAccountUpn,
FileName, FolderPath, SHA256, TimeGenerated, SensitivityLabel, IsAzureInfoProtectionApplied
Stage 7: sort
| order by DeviceId asc, TimeGenerated desc
The stages below run on FileCreation (the outer pipeline).
Stage 8: kusto:lookup
FileCreation
| lookup kind=inner (UsbDriveMount) on DeviceId
Stage 9: where
| where FolderPath startswith DriveLetter
Stage 10: where
| where TimeGenerated >= MountTime
Stage 11: partition
| partition hint.strategy=native by ReportId ( top 1 by MountTime )
Stage 12: sort
| order by DeviceId asc, TimeGenerated desc
Stage 13: extend (3 consecutive steps)
| extend HostName = iff(DeviceName has '.', substring(DeviceName, 0, indexof(DeviceName, '.')), DeviceName)
| extend DnsDomain = iff(DeviceName has '.', substring(DeviceName, indexof(DeviceName, '.') + 1), "")
| extend FileHashAlgorithm = 'SHA256'
HostName =DeviceName has "."substring(DeviceName, 0, indexof(DeviceName, '.'))DeviceNameExclusions
Top-level NOT(...) conjuncts: predicates this rule actively suppresses.
| Field | Kind | Excluded values |
|---|---|---|
FolderPath | starts_with | C:\\ |
FolderPath | starts_with | \\ |
Indicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
ActionType | eq |
|
FolderPath | starts_with |
|
InitiatingProcessAccountName | ne |
|
TimeGenerated | ge |
|
Output fields
Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.
| Field | Source |
|---|---|
DeviceId | project |
FileName | project |
FolderPath | project |
InitiatingProcessAccountDomain | project |
InitiatingProcessAccountName | project |
InitiatingProcessAccountUpn | project |
IsAzureInfoProtectionApplied | project |
ReportId | project |
SHA256 | project |
SensitivityLabel | project |
TimeGenerated | project |
HostName | extend |
DnsDomain | extend |
FileHashAlgorithm | extend |