Skip to content

Instantly share code, notes, and snippets.

@reprise99
Created May 12, 2023 23:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save reprise99/872ce722228bd1fda36363fafd4bb437 to your computer and use it in GitHub Desktop.
Save reprise99/872ce722228bd1fda36363fafd4bb437 to your computer and use it in GitHub Desktop.
//Look for low prevalance SHA256's associated with service creation that are new to your environment in the last day
//credit to mRr3b00t @UK_Daniel_Card for the idea and starting point and @lawndoc for the updates
let PrevalenceThreshold = 1000;
let knownSHA=
//Find all the existing SHA256s associated with service creation events in the last 30 days (excluding the last day)
DeviceEvents
| where Timestamp > ago(30d) and Timestamp < ago(1d)
| where ActionType == "ServiceInstalled"
| join (DeviceFileEvents) on FileName
| project-away SHA256
| project-rename SHA256=SHA2561
| where isnotempty(SHA256)
| distinct SHA256;
//Find any new SHA256s associated with service creation events that are low global prevalance AND aren't in the above list of known SHA256s in your environment
DeviceEvents
| where Timestamp > ago (1d)
| where ActionType == "ServiceInstalled"
| extend AdditionalFields = todynamic(AdditionalFields)
| extend ServiceName = tostring(AdditionalFields.["ServiceName"])
| extend ServiceAccount = tostring(AdditionalFields.["ServiceAccount"])
| extend ServiceStartType = tostring(AdditionalFields.["ServiceStartType"])
| join (DeviceFileEvents
| where Timestamp > ago (1d)
) on FileName
| project-away SHA256
| project-rename SHA256=SHA2561
| where isnotempty(SHA256) and SHA256 !in (knownSHA)
| summarize Count = count(), LastSeenTimestamp = max(Timestamp), Devices = make_set(DeviceName) by FileName, FolderPath, SHA256, ServiceName, ServiceAccount, ServiceStartType
| invoke FileProfile("SHA256")
| project-reorder LastSeenTimestamp, ServiceName, GlobalPrevalence
| where GlobalPrevalence < PrevalenceThreshold
| sort by GlobalPrevalence asc
//Use right antijoin to find a combination of new service + device combination not seen before prior to the last day and again check prevalance
//credit to mRr3b00t @UK_Daniel_Card for the idea and starting point and @lawndoc for the updates
let PrevalenceThreshold = 1000;
//right antijoin will show us new events from the last 1 day where the combination of deviceid + servicename was not seen in the prior 29 days
DeviceEvents
| where Timestamp > ago(30d) and Timestamp < ago(1d)
| where ActionType == "ServiceInstalled"
| extend AdditionalFields = todynamic(AdditionalFields)
| extend ServiceName = tostring(AdditionalFields.["ServiceName"])
| project DeviceId, ServiceName
| join kind=rightanti (
DeviceEvents
| where Timestamp > ago(1d)
| where ActionType == "ServiceInstalled"
| extend AdditionalFields = todynamic(AdditionalFields)
| extend ServiceName = tostring(AdditionalFields.["ServiceName"])
| extend ServiceAccount = tostring(AdditionalFields.["ServiceAccount"])
| extend ServiceStartType = tostring(AdditionalFields.["ServiceStartType"])
) on DeviceId, ServiceName
| join (DeviceFileEvents
| where Timestamp > ago (1d)
) on FileName
| project-away SHA256
| project-rename SHA256=SHA2561
| where isnotempty(SHA256)
| summarize Count = count(), LastSeenTimestamp = max(Timestamp), Devices = make_set(DeviceName) by FileName, FolderPath, SHA256, ServiceName, ServiceAccount, ServiceStartType
| invoke FileProfile("SHA256")
| project-reorder LastSeenTimestamp, ServiceName, GlobalPrevalence
| where GlobalPrevalence < PrevalenceThreshold
| sort by GlobalPrevalence asc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment