Persistence via Update Orchestrator Service Hijack
Identifies potential hijacking of the Microsoft Update Orchestrator Service to establish persistence with an integrity level of SYSTEM.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2020/08/17"
3integration = ["endpoint", "windows", "m365_defender", "sentinel_one_cloud_funnel", "system"]
4maturity = "production"
5updated_date = "2026/05/03"
6
7[rule]
8author = ["Elastic"]
9description = """
10Identifies potential hijacking of the Microsoft Update Orchestrator Service to establish persistence with an integrity
11level of SYSTEM.
12"""
13from = "now-9m"
14index = [
15 "endgame-*",
16 "logs-endpoint.events.process-*",
17 "logs-m365_defender.event-*",
18 "logs-sentinel_one_cloud_funnel.*",
19 "logs-system.security*",
20 "logs-windows.forwarded*",
21 "logs-windows.sysmon_operational-*",
22 "winlogbeat-*",
23]
24language = "eql"
25license = "Elastic License v2"
26name = "Persistence via Update Orchestrator Service Hijack"
27references = ["https://github.com/irsl/CVE-2020-1313"]
28risk_score = 73
29rule_id = "265db8f5-fc73-4d0d-b434-6483b56372e2"
30severity = "high"
31tags = [
32 "Domain: Endpoint",
33 "OS: Windows",
34 "Use Case: Threat Detection",
35 "Tactic: Persistence",
36 "Use Case: Vulnerability",
37 "Resources: Investigation Guide",
38 "Data Source: Elastic Endgame",
39 "Data Source: Elastic Defend",
40 "Data Source: Microsoft Defender XDR",
41 "Data Source: Sysmon",
42 "Data Source: Windows Security Event Logs",
43 "Data Source: SentinelOne",
44]
45timestamp_override = "event.ingested"
46type = "eql"
47
48query = '''
49process where host.os.type == "windows" and event.type == "start" and
50 process.parent.executable : "C:\\Windows\\System32\\svchost.exe" and
51 process.parent.args : "UsoSvc" and
52 not process.executable :
53 ("?:\\ProgramData\\Microsoft\\Windows\\UUS\\Packages\\*\\amd64\\MoUsoCoreWorker.exe",
54 "?:\\Windows\\System32\\UsoClient.exe",
55 "?:\\Windows\\System32\\MusNotification.exe",
56 "?:\\Windows\\System32\\MusNotificationUx.exe",
57 "?:\\Windows\\System32\\MusNotifyIcon.exe",
58 "?:\\Windows\\System32\\WerFault.exe",
59 "?:\\Windows\\System32\\WerMgr.exe",
60 "?:\\Windows\\UUS\\amd64\\MoUsoCoreWorker.exe",
61 "?:\\Windows\\System32\\MoUsoCoreWorker.exe",
62 "?:\\Windows\\UUS\\amd64\\UsoCoreWorker.exe",
63 "?:\\Windows\\System32\\UsoCoreWorker.exe",
64 "?:\\Program Files\\Common Files\\microsoft shared\\ClickToRun\\OfficeC2RClient.exe") and
65 not process.name : ("MoUsoCoreWorker.exe", "OfficeC2RClient.exe")
66'''
67
68note = """## Triage and analysis
69
70### Investigating Persistence via Update Orchestrator Service Hijack
71
72#### Possible investigation steps
73
74- What did UsoSvc actually launch, and does the child identity fit Windows or Office servicing?
75 - Focus: `process.executable`, `process.pe.original_file_name`, `process.code_signature.subject_name`, and `process.code_signature.trusted`.
76 - Hint: use `process.parent.command_line` to confirm svchost is hosting UsoSvc, not just sharing the name.
77 - Implication: escalate when UsoSvc launches a renamed, user-writable, unsigned, rare, or non-servicing child; lower concern only when path, signer, and parent service context match a recognized Windows Update or Click-to-Run component. Identity alone does not clear it.
78
79- Does the command line show attacker-controlled work running with service-level privilege?
80 - Why: on unpatched hosts, CVE-2020-1313 ScheduleWork can queue signed System32 or Common Files binaries with attacker-controlled arguments.
81 - Focus: `process.command_line`, `process.Ext.token.integrity_level_name`, and `user.id`.
82 - Implication: escalate when "cmd.exe", "rundll32.exe", "regsvr32.exe", a scripting host, or another signed binary runs shell, download, staging, redirection, or persistence arguments under SYSTEM or high integrity; lower concern when arguments fit the exact servicing binary workflow.
83
84- If registry telemetry is available, was matching work queued under the Update Orchestrator UScheduler path?
85 - Focus: same `host.id` registry events for `registry.path` under "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate\\Orchestrator\\UScheduler", with `registry.value`, `registry.data.strings`, and writer `process.executable`.
86 - Range: search several days before the alert; queued work can run overnight or after a multi-day service window.
87 - Hint: interpret queued strings with `registry.data.type`, then compare them to `process.command_line` and `process.executable`; missing registry telemetry is unresolved, not benign.
88 - Implication: escalate when the queue names the same unusual child or arguments, especially from a non-servicing writer; absent queue history only limits this corroborator.
89
90- Did the child stage artifacts or spawn follow-on processes that extend the abuse?
91 - Focus: child starts from `process.entity_id`; if file telemetry exists, same-process `file.path`, `file.Ext.original.path`, and `file.origin_url`.
92 - $investigate_0
93 - $investigate_1
94 - Hint: scope file pivots with `host.id` plus `process.entity_id`; use `host.id` plus `process.pid` and a tight alert window only when entity ID is absent. Missing file telemetry limits artifact review, but child-process and command evidence can justify escalation.
95 - Implication: escalate when the child writes executable or scriptable content to user-writable or deceptive paths, renames staged content, or launches written artifacts; lower concern when activity stays inside the recognized servicing path with no follow-on execution.
96
97- If network telemetry is available, does the child contact destinations consistent with servicing?
98 - Focus: process-scoped DNS `dns.question.name` and `dns.resolved_ip`, then connections by `destination.ip`, `destination.port`, and `destination.as.organization.name`. $investigate_2
99 - Hint: use "lookup_result" DNS events for populated `dns.resolved_ip`; scope with `host.id` plus `process.entity_id`, or `host.id` plus `process.pid` and a tight alert window. Infrastructure ownership is context, not a verdict; missing network telemetry is unresolved, not benign.
100 - Implication: escalate when the child reaches rare or public infrastructure unrelated to Microsoft servicing, the signer, or recovered queue; lower concern when destinations fit the signed binary's normal update or repair endpoints.
101
102- If local evidence remains suspicious or unresolved, do related alerts change scope?
103 - Focus: compare recent alerts for the same `process.executable`. $investigate_3
104 - Hint: review same `host.id` alerts only when child identity, command, queue, artifact, or destination evidence needs scope. $investigate_4
105 - Implication: broaden scope when the same child path or host shows repeated privilege-escalation, persistence, staging, or follow-on alerts; keep urgency local when isolated and no corroborating alert history appears.
106
107- Escalate on attacker-controlled UsoSvc child identity or command intent, using queue, artifact, destination, or related-alert evidence as corroboration; close only when alert-local and recovered evidence tie to one exact servicing or authorized validation workflow without contradictions; preserve artifacts and escalate when evidence is mixed, incomplete, or unavailable.
108
109### False positive analysis
110
111- Windows Update, repair, or Office Click-to-Run servicing can trigger this rule when UsoSvc queues a servicing component outside the exclusions. Close from telemetry first: child path, signer, command line, parent service context, UScheduler queue content when available, artifacts, destinations, and `host.id` cohort must align with one recognized servicing workflow. Patch-window or change records may corroborate; prior alerts only prove exception stability after current evidence fits.
112- Authorized exploit-validation or adversary-emulation tests can exercise Update Orchestrator abuse. Confirm stable payload identity such as `process.hash.sha256`, `process.command_line`, expected `host.id` or `user.id` test scope, matching queue content when available, and no spread to unrelated production hosts. Use engagement records or prior test alerts only as corroboration, and do not exception on `process.parent.executable`, "UsoSvc", or `process.name` alone.
113
114### Response and remediation
115
116- If confirmed benign:
117 - Record the exact evidence that proved the servicing or test workflow: child identity, command line, parent service context, queue content when available, same-process artifacts or destinations, and recurrence or records. Then reverse temporary containment and build any exception from that minimum pattern plus `host.id`, not from UsoSvc or a generic signed-binary condition.
118- If suspicious but unconfirmed:
119 - Preserve a case export with the alert process instance, process tree, command line, UScheduler queue values when available, writer-process details, written artifacts, destination indicators, and related-alert context before cleanup.
120 - Apply reversible containment tied to the finding, such as blocking the child hash or destination, temporarily disabling the queued work after preservation, or increasing host monitoring. Escalate to host isolation only when host criticality allows it and artifacts, destinations, or related alerts show active follow-on behavior.
121- If confirmed malicious:
122 - Preserve the case export first: child `process.entity_id` or `process.pid`, command line, queue values, writer lineage, payload hashes, artifact paths, and destination indicators. Then isolate the host when the identity, command, queue, artifact, or destination evidence confirms unauthorized UsoSvc execution.
123 - Remove the malicious queued work or restore the Update Orchestrator registry state to known-good, eradicate only payloads and persistence artifacts identified during triage, validate that UsoSvc returns to recognized servicing children, and review other hosts for the same child path or queue pattern before deleting preserved evidence.
124- Post-incident hardening:
125 - Apply the June 2020 or later Windows security updates where still applicable because the fix blocks untrusted caller queuing, retire unsupported builds, restrict write paths that can feed Update Orchestrator abuse, and retain registry/process telemetry for UScheduler queue changes.
126"""
127
128setup = """## Setup
129
130This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
131
132Setup instructions: https://ela.st/install-elastic-defend
133
134### Additional data sources
135
136This rule also supports the following third-party data sources. For setup instructions, refer to the links below:
137
138- [Microsoft Defender XDR](https://ela.st/m365-defender)
139- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
140- [Sysmon Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup)
141- [Windows Process Creation Logs](https://ela.st/audit-process-creation)
142"""
143
144[rule.investigation_fields]
145field_names = [
146 "@timestamp",
147 "host.id",
148 "user.id",
149 "process.entity_id",
150 "process.pid",
151 "process.executable",
152 "process.command_line",
153 "process.args",
154 "process.hash.sha256",
155 "process.pe.original_file_name",
156 "process.code_signature.subject_name",
157 "process.code_signature.trusted",
158 "process.Ext.token.integrity_level_name",
159 "process.parent.executable",
160 "process.parent.command_line",
161]
162
163[transform]
164
165[[transform.investigate]]
166label = "Child process starts from the launched child"
167description = ""
168providers = [
169 [
170 { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
171 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
172 { excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
173 ],
174 [
175 { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
176 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
177 { excluded = false, field = "process.parent.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" }
178 ]
179]
180relativeFrom = "now-1h"
181relativeTo = "now"
182
183[[transform.investigate]]
184label = "File events for the launched child"
185description = ""
186providers = [
187 [
188 { excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" },
189 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
190 { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
191 ],
192 [
193 { excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" },
194 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
195 { excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" }
196 ]
197]
198relativeFrom = "now-1h"
199relativeTo = "now"
200
201[[transform.investigate]]
202label = "Network events for the launched child"
203description = ""
204providers = [
205 [
206 { excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" },
207 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
208 { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
209 ],
210 [
211 { excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" },
212 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
213 { excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" }
214 ]
215]
216relativeFrom = "now-1h"
217relativeTo = "now"
218
219[[transform.investigate]]
220label = "Alerts involving the same child executable"
221description = ""
222providers = [
223 [
224 { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
225 { excluded = false, field = "process.executable", queryType = "phrase", value = "{{process.executable}}", valueType = "string" }
226 ]
227]
228relativeFrom = "now-48h/h"
229relativeTo = "now"
230
231[[transform.investigate]]
232label = "Alerts associated with the host"
233description = ""
234providers = [
235 [
236 { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
237 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
238 ]
239]
240relativeFrom = "now-48h/h"
241relativeTo = "now"
242
243[[rule.threat]]
244framework = "MITRE ATT&CK"
245
246[[rule.threat.technique]]
247id = "T1543"
248name = "Create or Modify System Process"
249reference = "https://attack.mitre.org/techniques/T1543/"
250
251[[rule.threat.technique.subtechnique]]
252id = "T1543.003"
253name = "Windows Service"
254reference = "https://attack.mitre.org/techniques/T1543/003/"
255
256[[rule.threat.technique]]
257id = "T1574"
258name = "Hijack Execution Flow"
259reference = "https://attack.mitre.org/techniques/T1574/"
260
261[[rule.threat.technique.subtechnique]]
262id = "T1574.011"
263name = "Services Registry Permissions Weakness"
264reference = "https://attack.mitre.org/techniques/T1574/011/"
265
266[rule.threat.tactic]
267id = "TA0003"
268name = "Persistence"
269reference = "https://attack.mitre.org/tactics/TA0003/"
270
271[[rule.threat]]
272framework = "MITRE ATT&CK"
273
274[[rule.threat.technique]]
275id = "T1068"
276name = "Exploitation for Privilege Escalation"
277reference = "https://attack.mitre.org/techniques/T1068/"
278
279[[rule.threat.technique]]
280id = "T1574"
281name = "Hijack Execution Flow"
282reference = "https://attack.mitre.org/techniques/T1574/"
283
284[rule.threat.tactic]
285id = "TA0004"
286name = "Privilege Escalation"
287reference = "https://attack.mitre.org/tactics/TA0004/"
Triage and analysis
Investigating Persistence via Update Orchestrator Service Hijack
Possible investigation steps
-
What did UsoSvc actually launch, and does the child identity fit Windows or Office servicing?
- Focus:
process.executable,process.pe.original_file_name,process.code_signature.subject_name, andprocess.code_signature.trusted. - Hint: use
process.parent.command_lineto confirm svchost is hosting UsoSvc, not just sharing the name. - Implication: escalate when UsoSvc launches a renamed, user-writable, unsigned, rare, or non-servicing child; lower concern only when path, signer, and parent service context match a recognized Windows Update or Click-to-Run component. Identity alone does not clear it.
- Focus:
-
Does the command line show attacker-controlled work running with service-level privilege?
- Why: on unpatched hosts, CVE-2020-1313 ScheduleWork can queue signed System32 or Common Files binaries with attacker-controlled arguments.
- Focus:
process.command_line,process.Ext.token.integrity_level_name, anduser.id. - Implication: escalate when "cmd.exe", "rundll32.exe", "regsvr32.exe", a scripting host, or another signed binary runs shell, download, staging, redirection, or persistence arguments under SYSTEM or high integrity; lower concern when arguments fit the exact servicing binary workflow.
-
If registry telemetry is available, was matching work queued under the Update Orchestrator UScheduler path?
- Focus: same
host.idregistry events forregistry.pathunder "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler", withregistry.value,registry.data.strings, and writerprocess.executable. - Range: search several days before the alert; queued work can run overnight or after a multi-day service window.
- Hint: interpret queued strings with
registry.data.type, then compare them toprocess.command_lineandprocess.executable; missing registry telemetry is unresolved, not benign. - Implication: escalate when the queue names the same unusual child or arguments, especially from a non-servicing writer; absent queue history only limits this corroborator.
- Focus: same
-
Did the child stage artifacts or spawn follow-on processes that extend the abuse?
- Focus: child starts from
process.entity_id; if file telemetry exists, same-processfile.path,file.Ext.original.path, andfile.origin_url.- $investigate_0
- $investigate_1
- Hint: scope file pivots with
host.idplusprocess.entity_id; usehost.idplusprocess.pidand a tight alert window only when entity ID is absent. Missing file telemetry limits artifact review, but child-process and command evidence can justify escalation. - Implication: escalate when the child writes executable or scriptable content to user-writable or deceptive paths, renames staged content, or launches written artifacts; lower concern when activity stays inside the recognized servicing path with no follow-on execution.
- Focus: child starts from
-
If network telemetry is available, does the child contact destinations consistent with servicing?
- Focus: process-scoped DNS
dns.question.nameanddns.resolved_ip, then connections bydestination.ip,destination.port, anddestination.as.organization.name. $investigate_2 - Hint: use "lookup_result" DNS events for populated
dns.resolved_ip; scope withhost.idplusprocess.entity_id, orhost.idplusprocess.pidand a tight alert window. Infrastructure ownership is context, not a verdict; missing network telemetry is unresolved, not benign. - Implication: escalate when the child reaches rare or public infrastructure unrelated to Microsoft servicing, the signer, or recovered queue; lower concern when destinations fit the signed binary's normal update or repair endpoints.
- Focus: process-scoped DNS
-
If local evidence remains suspicious or unresolved, do related alerts change scope?
- Focus: compare recent alerts for the same
process.executable. $investigate_3 - Hint: review same
host.idalerts only when child identity, command, queue, artifact, or destination evidence needs scope. $investigate_4 - Implication: broaden scope when the same child path or host shows repeated privilege-escalation, persistence, staging, or follow-on alerts; keep urgency local when isolated and no corroborating alert history appears.
- Focus: compare recent alerts for the same
-
Escalate on attacker-controlled UsoSvc child identity or command intent, using queue, artifact, destination, or related-alert evidence as corroboration; close only when alert-local and recovered evidence tie to one exact servicing or authorized validation workflow without contradictions; preserve artifacts and escalate when evidence is mixed, incomplete, or unavailable.
False positive analysis
- Windows Update, repair, or Office Click-to-Run servicing can trigger this rule when UsoSvc queues a servicing component outside the exclusions. Close from telemetry first: child path, signer, command line, parent service context, UScheduler queue content when available, artifacts, destinations, and
host.idcohort must align with one recognized servicing workflow. Patch-window or change records may corroborate; prior alerts only prove exception stability after current evidence fits. - Authorized exploit-validation or adversary-emulation tests can exercise Update Orchestrator abuse. Confirm stable payload identity such as
process.hash.sha256,process.command_line, expectedhost.idoruser.idtest scope, matching queue content when available, and no spread to unrelated production hosts. Use engagement records or prior test alerts only as corroboration, and do not exception onprocess.parent.executable, "UsoSvc", orprocess.namealone.
Response and remediation
- If confirmed benign:
- Record the exact evidence that proved the servicing or test workflow: child identity, command line, parent service context, queue content when available, same-process artifacts or destinations, and recurrence or records. Then reverse temporary containment and build any exception from that minimum pattern plus
host.id, not from UsoSvc or a generic signed-binary condition.
- Record the exact evidence that proved the servicing or test workflow: child identity, command line, parent service context, queue content when available, same-process artifacts or destinations, and recurrence or records. Then reverse temporary containment and build any exception from that minimum pattern plus
- If suspicious but unconfirmed:
- Preserve a case export with the alert process instance, process tree, command line, UScheduler queue values when available, writer-process details, written artifacts, destination indicators, and related-alert context before cleanup.
- Apply reversible containment tied to the finding, such as blocking the child hash or destination, temporarily disabling the queued work after preservation, or increasing host monitoring. Escalate to host isolation only when host criticality allows it and artifacts, destinations, or related alerts show active follow-on behavior.
- If confirmed malicious:
- Preserve the case export first: child
process.entity_idorprocess.pid, command line, queue values, writer lineage, payload hashes, artifact paths, and destination indicators. Then isolate the host when the identity, command, queue, artifact, or destination evidence confirms unauthorized UsoSvc execution. - Remove the malicious queued work or restore the Update Orchestrator registry state to known-good, eradicate only payloads and persistence artifacts identified during triage, validate that UsoSvc returns to recognized servicing children, and review other hosts for the same child path or queue pattern before deleting preserved evidence.
- Preserve the case export first: child
- Post-incident hardening:
- Apply the June 2020 or later Windows security updates where still applicable because the fix blocks untrusted caller queuing, retire unsupported builds, restrict write paths that can feed Update Orchestrator abuse, and retain registry/process telemetry for UScheduler queue changes.
References
Related rules
- Web Shell Detection: Script Process Child of Common Web Processes
- Persistence via TelemetryController Scheduled Task Hijack
- Unusual Child Process of dns.exe
- Adding Hidden File Attribute via Attrib
- Execution via MSSQL xp_cmdshell Stored Procedure