Unusual child processes spawned by the Exchange UM service may indicate adversarial activity leveraging legitimate service execution privileges. SOC teams should proactively hunt for this behavior in Azure Sentinel to identify potential compromise of the Exchange environment through novel process injection techniques.
KQL Query
let lookback = 14d;
let timeframe = 1d;
(union isfuzzy=true
(SecurityEvent
| where TimeGenerated > ago(lookback) and TimeGenerated < ago(timeframe)
| where EventID == 4688
| where ParentProcessName has_any ("umworkerprocess.exe", "UMService.exe")
| join kind=rightanti (
SecurityEvent
| where TimeGenerated > ago(timeframe)
| where ParentProcessName has_any ("umworkerprocess.exe", "UMService.exe")
| where EventID == 4688) on NewProcessName
),
(WindowsEvent
| where TimeGenerated > ago(lookback) and TimeGenerated < ago(timeframe)
| where EventID == 4688 and EventData has_any ("umworkerprocess.exe", "UMService.exe")
| extend ParentProcessName = tostring(EventData.ParentProcessName)
| where ParentProcessName has_any ("umworkerprocess.exe", "UMService.exe")
| extend NewProcessName = tostring(EventData.NewProcessName)
| extend Account = strcat(tostring(EventData.SubjectDomainName),"\\", tostring(EventData.SubjectUserName))
| extend IpAddress = tostring(EventData.IpAddress)
| join kind=rightanti (
WindowsEvent
| where TimeGenerated > ago(timeframe)
| where EventID == 4688 and EventData has_any ("umworkerprocess.exe", "UMService.exe")
| extend ParentProcessName = tostring(EventData.ParentProcessName)
| where ParentProcessName has_any ("umworkerprocess.exe", "UMService.exe")
| extend NewProcessName = tostring(EventData.NewProcessName)
| extend Account = strcat(tostring(EventData.SubjectDomainName),"\\", tostring(EventData.SubjectUserName))
| extend IpAddress = tostring(EventData.IpAddress)) on NewProcessName
| extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
| extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
| extend SubjectUserName = tostring(EventData.SubjectUserName), SubjectDomainName = tostring(EventData.SubjectDomainName)
| project-away DomainIndex
))
id: 95a15f39-d9cc-4667-8cdd-58f3113691c9
name: Silk Typhoon New UM Service Child Process
description: |
'This query looks for new processes being spawned by the Exchange UM service where that process has not previously been observed before.
Reference: https://www.microsoft.com/security/blog/2021/03/02/hafnium-targeting-exchange-servers/'
severity: Medium
requiredDataConnectors:
- connectorId: SecurityEvents
dataTypes:
- SecurityEvent
- connectorId: WindowsSecurityEvents
dataTypes:
- SecurityEvent
- connectorId: WindowsSecurityEvents
dataTypes:
- SecurityEvents
- connectorId: WindowsForwardedEvents
dataTypes:
- WindowsEvent
queryFrequency: 1d
queryPeriod: 14d
triggerOperator: gt
triggerThreshold: 0
tactics:
- InitialAccess
relevantTechniques:
- T1190
query: |
let lookback = 14d;
let timeframe = 1d;
(union isfuzzy=true
(SecurityEvent
| where TimeGenerated > ago(lookback) and TimeGenerated < ago(timeframe)
| where EventID == 4688
| where ParentProcessName has_any ("umworkerprocess.exe", "UMService.exe")
| join kind=rightanti (
SecurityEvent
| where TimeGenerated > ago(timeframe)
| where ParentProcessName has_any ("umworkerprocess.exe", "UMService.exe")
| where EventID == 4688) on NewProcessName
),
(WindowsEvent
| where TimeGenerated > ago(lookback) and TimeGenerated < ago(timeframe)
| where EventID == 4688 and EventData has_any ("umworkerprocess.exe", "UMService.exe")
| extend ParentProcessName = tostring(EventData.ParentProcessName)
| where ParentProcessName has_any ("umworkerprocess.exe", "UMService.exe")
| extend NewProcessName = tostring(EventData.NewProcessName)
| extend Account = strcat(tostring(EventData.SubjectDomainName),"\\", tostring(EventData.SubjectUserName))
| extend IpAddress = tostring(EventData.IpAddress)
| join kind=rightanti (
WindowsEvent
| where TimeGenerated > ago(timeframe)
| where EventID == 4688 and EventData has_any ("umworkerprocess.exe", "UMService.exe")
| extend ParentProcessName = tostring(EventData.ParentProcessName)
| where ParentProcessName has_any ("umworkerprocess.exe", "UMService.exe")
| extend NewProcessName = tostring(EventData.NewProcessName)
| extend Account = strcat(tostring(EventData.SubjectDomainName),"\\", tostring(EventData.SubjectUserName))
| extend IpAddress = tostring(EventData.IpAddress)) on NewProcessName
| extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
| extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
| extend SubjectUserName = tostring(EventData.SubjectUserName), SubjectDomainName = tostring(EventData.SubjectDomainName)
| project-away DomainIndex
))
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: SubjectAccount
- identifier: Name
columnName: SubjectUserName
- identifier: NTDomain
colum
| Sentinel Table | Notes |
|---|---|
SecurityEvent | Ensure this data connector is enabled |
WindowsEvent | Ensure this data connector is enabled |
Scenario: Scheduled System Maintenance Task
Description: A legitimate scheduled task runs a script or executable that is not commonly associated with the Exchange UM service, triggering the rule.
Filter/Exclusion: Exclude processes launched by schtasks.exe or tasks with a known name like SystemMaintenanceTask.
Scenario: Admin Performing User Management via PowerShell
Description: An administrator uses PowerShell to create or modify user accounts, which may spawn a new process not previously seen on the system.
Filter/Exclusion: Exclude processes with the parent process powershell.exe and command lines containing New-User or Set-User.
Scenario: Exchange UM Service Performing a Routine Backup
Description: The Exchange UM service initiates a backup process using a third-party tool like Veeam or Backup Exec, which is not previously observed.
Filter/Exclusion: Exclude processes launched by known backup tools or with parent process ExchangeUMService.exe.
Scenario: Antivirus or Endpoint Protection Scan
Description: A legitimate antivirus scan (e.g., by Bitdefender, Kaspersky, or Microsoft Defender) spawns a new process that is not in the system’s process history.
Filter/Exclusion: Exclude processes with known antivirus tool names or parent processes related to endpoint protection software.
Scenario: Custom Script for Email Migration
Description: A custom script (e.g., written in Python or PowerShell) is run to migrate emails, and the script spawns a new process that is not previously seen.
Filter/Exclusion: Exclude processes launched by scripts with known migration tool names or with parent process python.exe or powershell.exe and command lines containing migrate or move.