WDATP Alert detection query

%3CLINGO-SUB%20id%3D%22lingo-sub-1278500%22%20slang%3D%22en-US%22%3EWDATP%20Alert%20detection%20query%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1278500%22%20slang%3D%22en-US%22%3E%3CP%3EHi%20Community%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EI%20really%20need%20some%20help%20trying%20to%20build%20this%20query%20correct%20in%20KQL.%20The%20Query%20is%20reporting%20users%20who%20has%20created%20files%20onto%20a%20drive%20that%20is%20not%20the%20local%20C%3A%5C%3C%2FP%3E%3CP%3EI%20try%20to%20detect%20and%20alert%20if%20users%20exfiltrate%20data%20into%20an%20external%20device%20like%20USB%20or%20removeable%20harddisk.%20The%20alert%20should%20get%20triggered%20if%20more%20that%2050%20files%20are%20exfiltrated%20(can%20bechanged%20i%20know).%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EThe%20query%3A%3C%2FP%3E%3CP%3EDeviceFileEvents%3CBR%20%2F%3E%7C%20where%20InitiatingProcessAccountName%20in%20((%3CBR%20%2F%3EDeviceFileEvents%3CBR%20%2F%3E%7C%20where%20ActionType%20%3D%3D%20%22FileCreated%22%3CBR%20%2F%3E%7C%20where%20InitiatingProcessAccountName%20startswith%20%22w%22%3CBR%20%2F%3E%7C%20where%20InitiatingProcessAccountName%20!%3D%20%22webiadmin%22%3CBR%20%2F%3E%7C%20where%20FolderPath%20!startswith%20%40'C%3A%5C'%3CBR%20%2F%3E%7C%20where%20FolderPath%20!startswith%20%40'%5CDevice%5CHarddisk'%3CBR%20%2F%3E%7C%20where%20FolderPath%20!startswith%20%40'%5C%5C'%3CBR%20%2F%3E%7C%20where%20FolderPath%20!contains%20%22privat%22%3CBR%20%2F%3E%7C%20where%20FileName%20!contains%20%22privat%22%3CBR%20%2F%3E%7C%20project%20LeftInitiatingProcessAccountName%20%3D%20InitiatingProcessAccountName%2C%20LeftDeviceName%20%3D%20DeviceName%3CBR%20%2F%3E%7C%20summarize%20count()%20by%20LeftInitiatingProcessAccountName%2C%20LeftDeviceName%3CBR%20%2F%3E%7C%20where%20count_%20%26gt%3B%2050))%3CBR%20%2F%3E%7C%20distinct%20DeviceName%2C%20InitiatingProcessAccountName%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EThe%20problem%20here%20is%20the%20query%20works%20just%20fine%2C%20but%20in%20order%20to%20run%20is%20as%20a%20detection%20rule%2C%20the%20columns%20Timestamp%2C%20DeviceId%20and%20ReportId%20must%20be%20included.%20adding%20those%20to%20the%20existing%20query%20result%20in%20a%20Cartchic%20product.%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EAny%20help%20is%20much%20appreciated.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EBest%20regards%20Tim%20Gjerlufsen%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1396154%22%20slang%3D%22en-US%22%3ERe%3A%20WDATP%20Alert%20detection%20query%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1396154%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F248028%22%20target%3D%22_blank%22%3E%40DKTimGjerlufsen%3C%2FA%3E%26nbsp%3BI%20was%20able%20to%20create%20a%20detection%20rule%20based%20on%20this%20KQL%20Query%3A%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CDIV%3E%3CDIV%3E%3CSPAN%3EDeviceEvents%3C%2FSPAN%3E%3C%2FDIV%3E%3CDIV%3E%3CSPAN%3E%7C%20where%20Timestamp%20%26gt%3B%20ago(1d)%20%3C%2FSPAN%3E%3C%2FDIV%3E%3CDIV%3E%3CSPAN%3E%7C%20where%20ActionType%20%3D%3D%20%22UsbDriveMount%22%3C%2FSPAN%3E%3C%2FDIV%3E%3CDIV%3E%3CSPAN%3E%7C%20project%20USBMountTime%20%3D%20Timestamp%2C%20DeviceId%2C%20AdditionalFields%3C%2FSPAN%3E%3C%2FDIV%3E%3CDIV%3E%3CSPAN%3E%7C%20extend%20DriveLetter%20%3D%20tostring(todynamic(AdditionalFields).DriveLetter)%3C%2FSPAN%3E%3C%2FDIV%3E%3CDIV%3E%3CSPAN%3E%7C%20join%20(%3C%2FSPAN%3E%3C%2FDIV%3E%3CDIV%3E%3CSPAN%3EDeviceFileEvents%3C%2FSPAN%3E%3C%2FDIV%3E%3CDIV%3E%3CSPAN%3E%7C%20where%20Timestamp%20%26gt%3B%20ago(1d)%20%3C%2FSPAN%3E%3C%2FDIV%3E%3CDIV%3E%3CSPAN%3E%7C%20where%20ActionType%20%3D%3D%20%22FileCreated%22%3C%2FSPAN%3E%3C%2FDIV%3E%3CDIV%3E%3CSPAN%3E%7C%20parse%20FolderPath%20with%20DriveLetter%20'%5C%5C'%20*%20%3C%2FSPAN%3E%3C%2FDIV%3E%3CDIV%3E%3CSPAN%3E%7C%20extend%20DriveLetter%20%3D%20tostring(DriveLetter)%20%3C%2FSPAN%3E%3C%2FDIV%3E%3CDIV%3E%3CSPAN%3E)%3C%2FSPAN%3E%3C%2FDIV%3E%3CDIV%3E%3CSPAN%3Eon%20DeviceId%2C%20DriveLetter%3C%2FSPAN%3E%3C%2FDIV%3E%3CDIV%3E%3CSPAN%3E%7C%20where%20(Timestamp%20-%20USBMountTime)%20between%20(0min%20..%2015min)%3C%2FSPAN%3E%3C%2FDIV%3E%3CDIV%3E%3CSPAN%3E%7C%20summarize%20DistinctFilesCopied%20%3D%20dcount(SHA1)%2C%20Events%3Dmakeset(pack(%22AccountName%22%2C%20InitiatingProcessAccountName%2C%20%22Timestamp%22%2C%20Timestamp%2C%20%22ReportId%22%2C%20ReportId%2C%20%22FileName%22%2C%20FileName%2C%20%22AdditionalDriveProperties%22%2C%20AdditionalFields))%20by%20DeviceId%2C%20bin(Timestamp%2C%2015m)%20%3C%2FSPAN%3E%3C%2FDIV%3E%3CDIV%3E%3CSPAN%3E%7C%20where%20DistinctFilesCopied%20%26gt%3B%2010%3C%2FSPAN%3E%3C%2FDIV%3E%3CDIV%3E%3CSPAN%3E%7C%20mv-expand%20Events%3C%2FSPAN%3E%3C%2FDIV%3E%3CDIV%3E%3CSPAN%3E%7C%20extend%20Timestamp%20%3D%20Events.Timestamp%2C%20FileName%20%3D%20Events.FileName%2C%20AccountName%20%3D%20Events.AccountName%2C%20ReportId%20%3D%20Events.ReportId%2C%20AdditionalDriveProperties%20%3D%20Events.AdditionalDriveProperties%3C%2FSPAN%3E%3C%2FDIV%3E%3C%2FDIV%3E%3C%2FLINGO-BODY%3E
New Contributor

Hi Community

 

I really need some help trying to build this query correct in KQL. The Query is reporting users who has created files onto a drive that is not the local C:\

I try to detect and alert if users exfiltrate data into an external device like USB or removeable harddisk. The alert should get triggered if more that 50 files are exfiltrated (can bechanged i know).

 

The query:

DeviceFileEvents
| where InitiatingProcessAccountName in ((
DeviceFileEvents
| where ActionType == "FileCreated"
| where InitiatingProcessAccountName startswith "w"
| where InitiatingProcessAccountName != "webiadmin"
| where FolderPath !startswith @'C:\'
| where FolderPath !startswith @'\Device\Harddisk'
| where FolderPath !startswith @'\\'
| where FolderPath !contains "privat"
| where FileName !contains "privat"
| project LeftInitiatingProcessAccountName = InitiatingProcessAccountName, LeftDeviceName = DeviceName
| summarize count() by LeftInitiatingProcessAccountName, LeftDeviceName
| where count_ > 50))
| distinct DeviceName, InitiatingProcessAccountName

 

The problem here is the query works just fine, but in order to run is as a detection rule, the columns Timestamp, DeviceId and ReportId must be included. adding those to the existing query result in a Cartchic product. 

 

Any help is much appreciated.

 

Best regards Tim Gjerlufsen

1 Reply

@DKTimGjerlufsen I was able to create a detection rule based on this KQL Query:

 

DeviceEvents
| where Timestamp > ago(1d)
| where ActionType == "UsbDriveMount"
| project USBMountTime = Timestamp, DeviceId, AdditionalFields
| extend DriveLetter = tostring(todynamic(AdditionalFields).DriveLetter)
| join (
DeviceFileEvents
| where Timestamp > ago(1d)
| where ActionType == "FileCreated"
| parse FolderPath with DriveLetter '\\' *
| extend DriveLetter = tostring(DriveLetter)
)
on DeviceId, DriveLetter
| where (Timestamp - USBMountTime) between (0min .. 15min)
| summarize DistinctFilesCopied = dcount(SHA1), Events=makeset(pack("AccountName", InitiatingProcessAccountName, "Timestamp", Timestamp, "ReportId", ReportId, "FileName", FileName, "AdditionalDriveProperties", AdditionalFields)) by DeviceId, bin(Timestamp, 15m)
| where DistinctFilesCopied > 10
| mv-expand Events
| extend Timestamp = Events.Timestamp, FileName = Events.FileName, AccountName = Events.AccountName, ReportId = Events.ReportId, AdditionalDriveProperties = Events.AdditionalDriveProperties