Adversaries may use rare processes launched as a service to evade detection and maintain persistence. SOC teams should proactively hunt for this behavior in Azure Sentinel to identify potential stealthy malware or unauthorized process execution.
KQL Query
let LookupTime = 30d;
let WhiteList = pack_array(
"svchost.exe",
"mssense.exe",
"msmpeng.exe",
"searchindexer.exe",
"microsoftedgeupdate.exe"
);
let GetServices = materialize (
DeviceProcessEvents
| where Timestamp > ago(LookupTime)
| where InitiatingProcessParentFileName contains "services.exe"
| where InitiatingProcessFileName !in~(WhiteList)
| project Timestamp, 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 Timestamp > ago(LookupTime)
| where InitiatingProcessParentFileName contains "services.exe"
| where InitiatingProcessFileName !in~(WhiteList)
| project Timestamp, 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 Timestamp > ago(LookupTime)
| where InitiatingProcessParentFileName contains "services.exe"
| where InitiatingProcessFileName !in~(WhiteList)
| project Timestamp, 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 Timestamp > ago(LookupTime)
| where InitiatingProcessParentFileName contains "services.exe"
| where InitiatingProcessFileName !in~(WhiteList)
| project Timestamp, 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), ConnectedUrls = make_set(RemoteUrl), FilesModified = make_set(ModifiedFile),FileModFolderPath = make_set(ModifiedFilePath),FileModHA1s = make_set(ModifiedFileSHA1), ChildProcesses = make_set(StartedChildProcess), ChildCommandlines = make_set(StartedChildProcessCmdline), DLLsLoaded = make_set(LoadedDLL), DLLSHA1 = make_set(LoadedDLLSHA1) by DeviceName, ServiceProcess, ServiceProcessCmdline, ServiceProcessCreationTime, ServiceProcessID, ServiceProcessUser, ServiceProcessSHA1
id: a60ac80f-dce6-43ec-b102-9ae8c094d5dc
name: Rare-process-as-a-service
description: |
This query is looking for rarely seen processes which are launched as a service.
Author: Jouni Mikkola
More info: https://threathunt.blog/rare-process-launch-as-a-service/
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
dataTypes:
- DeviceProcessEvents
- DeviceNetworkEvents
- DeviceFileEvents
- DeviceImageLoadEvents
tactics:
- Persistence
relevantTechniques:
- T1543
- T1543.003
query: |
let LookupTime = 30d;
let WhiteList = pack_array(
"svchost.exe",
"mssense.exe",
"msmpeng.exe",
"searchindexer.exe",
"microsoftedgeupdate.exe"
);
let GetServices = materialize (
DeviceProcessEvents
| where Timestamp > ago(LookupTime)
| where InitiatingProcessParentFileName contains "services.exe"
| where InitiatingProcessFileName !in~(WhiteList)
| project Timestamp, 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 Timestamp > ago(LookupTime)
| where InitiatingProcessParentFileName contains "services.exe"
| where InitiatingProcessFileName !in~(WhiteList)
| project Timestamp, 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 Timestamp > ago(LookupTime)
| where InitiatingProcessParentFileName contains "services.exe"
| where InitiatingProcessFileName !in~(WhiteList)
| project Timestamp, 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
| j
| Sentinel Table | Notes |
|---|---|
DeviceFileEvents | Ensure this data connector is enabled |
DeviceImageLoadEvents | Ensure this data connector is enabled |
DeviceNetworkEvents | Ensure this data connector is enabled |
DeviceProcessEvents | Ensure this data connector is enabled |
Scenario: Scheduled system maintenance task using schtasks.exe
Description: A legitimate scheduled task is configured to run a rare process as a service, such as schtasks.exe launching a maintenance script.
Filter/Exclusion: Exclude processes launched by schtasks.exe or filter based on the task name containing “maintenance” or “backup”.
Scenario: Windows Update service using svchost.exe
Description: The Windows Update service is hosted by svchost.exe, which is a common process that may appear rare in certain environments.
Filter/Exclusion: Exclude processes where the parent process is services.exe or filter by the service name containing “Windows Update”.
Scenario: Database backup using sqlservr.exe as a service
Description: A SQL Server instance is configured to run as a service, and during backup operations, it may be launched in a way that appears unusual.
Filter/Exclusion: Exclude processes where the command line includes backup-related arguments or filter by the service name containing “SQL”.
Scenario: Log management tool using logparser.exe as a service
Description: A log analysis tool like Microsoft Log Parser is configured as a service to process logs, which may trigger the rule due to its rare usage.
Filter/Exclusion: Exclude processes where the command line includes log file paths or filter by the service name containing “logparser”.
Scenario: Admin task using taskhostw.exe to run a rare process
Description: A system administrator may use taskhostw.exe (Task Scheduler host) to run a rare process as part of a routine administrative task.
Filter/Exclusion: Exclude processes where the parent process is taskhostw.exe or filter based on the task description containing “admin”