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 |
Telemetry coverage
Rule body
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 FileCreation is inlined into the numbered stages below.
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;
Stage 1: source
let UsbDriveMount
Stage 2: source
let FileCreation
Stage 3: source
DeviceFileEvents
Stage 4: where
where InitiatingProcessAccountName !~ "system"
Stage 5: where
where ActionType =~ "FileCreated"
Stage 6: where
where not (FolderPath startswith @"C:\")
Stage 7: where
where not (FolderPath startswith @"\")
Stage 8: project
project DeviceId, FileName, FolderPath, InitiatingProcessAccountDomain, InitiatingProcessAccountName, InitiatingProcessAccountUpn, IsAzureInfoProtectionApplied, ReportId, SHA256, SensitivityLabel, TimeGenerated
Stage 9: sort
sort by DeviceId, TimeGenerated
Stage 10: kusto:lookup
lookup kind=inner (UsbDriveMount) on DeviceId
Stage 11: where
where FolderPath startswith "DriveLetter"
Stage 12: where
where TimeGenerated >= MountTime
Stage 13: partition
partition
Stage 14: sort
sort by DeviceId, TimeGenerated
Stage 15: extend (3 consecutive steps)
extend DnsDomain, FileHashAlgorithm, HostName
HostName =if
DeviceName has "."substring(DeviceName, 0, indexof(DeviceName, '.'))else
DeviceNameExclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
FolderPath | starts_with | C:\ | excludes:FolderPath field:"FolderPath" value:"C:\" |
FolderPath | starts_with | \ | excludes:FolderPath field:"FolderPath" value:"\" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
ActionType | eq |
| field:"ActionType" kind:eq |
FolderPath | starts_with |
| field:"TargetFilename" kind:starts_with value:"DriveLetter" |
InitiatingProcessAccountName | ne |
| field:"user" kind:ne value:"system" |
TimeGenerated | cross_field_compare |
| field:"TimeGenerated" kind:cross_field_compare value:"MountTime" |
Output fields
These fields are emitted when the rule matches.
| 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 |