Detection rules › Kusto
Rare Process as a Service
This query is looking for rarely seen processes which are launched as a service. Whiltelisted process list need to be updated based on the environment. Author: Jouni Mikkola More info: https://threathunt.blog/rare-process-launch-as-a-service/
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Persistence |
Telemetry coverage
Rule body
id: 91a451e3-178f-41b2-9e5d-da97d75b9971
name: Rare Process as a Service
description: |
This query is looking for rarely seen processes which are launched as a service. Whiltelisted process list need to be updated based on the environment.
Author: Jouni Mikkola
More info: https://threathunt.blog/rare-process-launch-as-a-service/
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
dataTypes:
- DeviceProcessEvents
- DeviceNetworkEvents
- DeviceFileEvents
- DeviceImageLoadEvents
queryFrequency: 1d
queryPeriod: 14d
triggerOperator: gt
triggerThreshold: 0
tactics:
- Persistence
relevantTechniques:
- T1543
- T1543.003
query: |
let LookupTime = 14d;
let WhiteList = pack_array(
"svchost.exe",
"mssense.exe",
"msmpeng.exe",
"searchindexer.exe",
"microsoftedgeupdate.exe"
);
let GetServices = materialize (
DeviceProcessEvents
| where TimeGenerated > ago(LookupTime)
| where InitiatingProcessParentFileName contains "services.exe"
| where InitiatingProcessFileName !in~(WhiteList)
| project TimeGenerated, DeviceName, StartedChildProcess = FileName, StartedChildProcessSHA1 = SHA1, StartedChildProcessCmdline = ProcessCommandLine, ServiceProcessSHA1 = InitiatingProcessSHA1, ServiceProcess = InitiatingProcessFileName, ServiceProcessCmdline = InitiatingProcessCommandLine, ServiceProcessID = InitiatingProcessId, ServiceProcessCreationTime = InitiatingProcessCreationTime, ServiceProcessUser = InitiatingProcessAccountName
);
GetServices
| summarize count() by ServiceProcess, DeviceName
| where count_ < 6
| join kind = inner GetServices on ServiceProcess, DeviceName
| join kind = leftouter (
DeviceNetworkEvents
| where TimeGenerated > ago(LookupTime)
| where InitiatingProcessParentFileName contains "services.exe"
| where InitiatingProcessFileName !in~(WhiteList)
| project TimeGenerated, DeviceName, ServiceProcessSHA1 = InitiatingProcessSHA1, ServiceProcess = InitiatingProcessFileName, ServiceProcessCmdline = InitiatingProcessCommandLine, ServiceProcessID = InitiatingProcessId, ServiceProcessCreationTime = InitiatingProcessCreationTime, ServiceProcessUser = InitiatingProcessAccountName, NetworkAction = ActionType, RemoteIP, RemoteUrl
) on DeviceName, ServiceProcess, ServiceProcessCmdline, ServiceProcessCreationTime, ServiceProcessID, ServiceProcessUser, ServiceProcessSHA1
| join kind = leftouter (
DeviceFileEvents
| where TimeGenerated > ago(LookupTime)
| where InitiatingProcessParentFileName contains "services.exe"
| where InitiatingProcessFileName !in~(WhiteList)
| project TimeGenerated, DeviceName, ServiceProcessSHA1 = InitiatingProcessSHA1, ServiceProcess = InitiatingProcessFileName, ServiceProcessCmdline = InitiatingProcessCommandLine, ServiceProcessID = InitiatingProcessId, ServiceProcessCreationTime = InitiatingProcessCreationTime, ServiceProcessUser = InitiatingProcessAccountName, FileAction = ActionType, ModifiedFile = FileName, ModifiedFileSHA1 = SHA1, ModifiedFilePath = FolderPath
) on DeviceName, ServiceProcess, ServiceProcessCmdline, ServiceProcessCreationTime, ServiceProcessID, ServiceProcessUser, ServiceProcessSHA1
| join kind = leftouter (
DeviceImageLoadEvents
| where TimeGenerated > ago(LookupTime)
| where InitiatingProcessParentFileName contains "services.exe"
| where InitiatingProcessFileName !in~(WhiteList)
| project TimeGenerated, DeviceName, ServiceProcessSHA1 = InitiatingProcessSHA1, ServiceProcess = InitiatingProcessFileName, ServiceProcessCmdline = InitiatingProcessCommandLine, ServiceProcessID = InitiatingProcessId, ServiceProcessCreationTime = InitiatingProcessCreationTime, ServiceProcessUser = InitiatingProcessAccountName, LoadedDLL = FileName, LoadedDLLSHA1 = SHA1, LoadedDLLPath = FolderPath
) on DeviceName, ServiceProcess, ServiceProcessCmdline, ServiceProcessCreationTime, ServiceProcessID, ServiceProcessUser, ServiceProcessSHA1
| summarize ConnectedAddresses = make_set(RemoteIP, 100000), ConnectedUrls = make_set(RemoteUrl, 100000), FilesModified = make_set(ModifiedFile, 100000),FileModFolderPath = make_set(ModifiedFilePath, 100000),FileModHA1s = make_set(ModifiedFileSHA1, 100000), ChildProcesses = make_set(StartedChildProcess, 100000), ChildCommandlines = make_set(StartedChildProcessCmdline, 100000), DLLsLoaded = make_set(LoadedDLL, 100000), DLLSHA1 = make_set(LoadedDLLSHA1, 100000) by DeviceName, ServiceProcess, ServiceProcessCmdline, ServiceProcessCreationTime, ServiceProcessID, ServiceProcessUser, ServiceProcessSHA1
| extend HostName = iff(DeviceName has '.', substring(DeviceName, 0, indexof(DeviceName, '.')), DeviceName)
| extend DnsDomain = iff(DeviceName has '.', substring(DeviceName, indexof(DeviceName, '.') + 1), "")
entityMappings:
- entityType: Host
fieldMappings:
- identifier: FullName
columnName: DeviceName
- identifier: HostName
columnName: HostName
- identifier: DnsDomain
columnName: DnsDomain
- entityType: Process
fieldMappings:
- identifier: ProcessId
columnName: ServiceProcessID
- identifier: CommandLine
columnName: ServiceProcessCmdline
version: 1.0.0
kind: Scheduled
Stages and Predicates
Parameters
let LookupTime = 14d;
let GetServices is inlined into the numbered stages below.
Let binding: WhiteList
let WhiteList = pack_array(
"svchost.exe",
"mssense.exe",
"msmpeng.exe",
"searchindexer.exe",
"microsoftedgeupdate.exe"
);
Stage 1: source
let GetServices
Stage 2: source
DeviceProcessEvents
Stage 3: where
where TimeGenerated > ago(1209600s)
Stage 4: where
where InitiatingProcessParentFileName contains "services.exe"
Stage 5: where
where not (InitiatingProcessFileName =~ "WhiteList")
Stage 6: project
project DeviceName, ServiceProcess, ServiceProcessCmdline, ServiceProcessCreationTime, ServiceProcessID, ServiceProcessSHA1, ServiceProcessUser, StartedChildProcess, StartedChildProcessCmdline, StartedChildProcessSHA1, TimeGenerated
Stage 7: summarize
summarize by ServiceProcess, DeviceName
Stage 8: where
where count_ < 6
Stage 9: join
join kind=inner (GetServices) on ServiceProcess, DeviceName
Stage 10: join
join kind=leftouter (DeviceNetworkEvents) on DeviceName, ServiceProcess, ServiceProcessCmdline, ServiceProcessCreationTime, ServiceProcessID, ServiceProcessUser, ServiceProcessSHA1
Stage 11: join
join kind=leftouter (DeviceFileEvents) on DeviceName, ServiceProcess, ServiceProcessCmdline, ServiceProcessCreationTime, ServiceProcessID, ServiceProcessUser, ServiceProcessSHA1
Stage 12: join
join kind=leftouter (DeviceImageLoadEvents) on DeviceName, ServiceProcess, ServiceProcessCmdline, ServiceProcessCreationTime, ServiceProcessID, ServiceProcessUser, ServiceProcessSHA1
Stage 13: summarize
summarize ChildCommandlines, ChildProcesses, ConnectedAddresses, ConnectedUrls, DLLSHA1, DLLsLoaded, FileModFolderPath, FileModHA1s, FilesModified by DeviceName, ServiceProcess, ServiceProcessCmdline, ServiceProcessCreationTime, ServiceProcessID, ServiceProcessUser, ServiceProcessSHA1
Stage 14: extend
extend HostName
HostName =if
DeviceName has "."substring(DeviceName, 0, indexof(DeviceName, '.'))else
DeviceNameStage 15: extend
extend DnsDomain
DnsDomain =if
DeviceName has "."substring(DeviceName, (indexof(DeviceName, '.') + 1))else
""Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
InitiatingProcessFileName | eq | WhiteList | excludes:InitiatingProcessFileName field:"InitiatingProcessFileName" value:"WhiteList" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
InitiatingProcessParentFileName | contains |
| field:"GrandParentImage" kind:contains value:"services.exe" |
count_ | lt |
| field:"count_" kind:lt value:"6" |
Output fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
ChildCommandlines | summarize |
ChildProcesses | summarize |
ConnectedAddresses | summarize |
ConnectedUrls | summarize |
DLLSHA1 | summarize |
DLLsLoaded | summarize |
DeviceName | summarize |
FileModFolderPath | summarize |
FileModHA1s | summarize |
FilesModified | summarize |
ServiceProcess | summarize |
ServiceProcessCmdline | summarize |
ServiceProcessCreationTime | summarize |
ServiceProcessID | summarize |
ServiceProcessSHA1 | summarize |
ServiceProcessUser | summarize |
HostName | extend |
DnsDomain | extend |