WDAC Policy File by an Unusual Process
Identifies the creation of a Windows Defender Application Control (WDAC) policy file by an unusual process. Adversaries may use a specially crafted WDAC policy to restrict the execution of security products.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2025/02/28"
3integration = ["endpoint", "windows", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"]
4maturity = "production"
5updated_date = "2026/04/30"
6
7[rule]
8author = ["Elastic"]
9description = """
10Identifies the creation of a Windows Defender Application Control (WDAC) policy file by an unusual process. Adversaries
11may use a specially crafted WDAC policy to restrict the execution of security products.
12"""
13from = "now-9m"
14index = [
15 "winlogbeat-*",
16 "logs-endpoint.events.file-*",
17 "logs-windows.sysmon_operational-*",
18 "endgame-*",
19 "logs-m365_defender.event-*",
20 "logs-sentinel_one_cloud_funnel.*",
21 "logs-crowdstrike.fdr*",
22]
23language = "eql"
24license = "Elastic License v2"
25name = "WDAC Policy File by an Unusual Process"
26references = [
27 "https://github.com/logangoins/Krueger/tree/main",
28 "https://beierle.win/2024-12-20-Weaponizing-WDAC-Killing-the-Dreams-of-EDR/",
29]
30risk_score = 73
31rule_id = "3aaf37f3-05a1-40a5-bb6e-e380c4f92c52"
32severity = "high"
33tags = [
34 "Domain: Endpoint",
35 "OS: Windows",
36 "Use Case: Threat Detection",
37 "Tactic: Defense Evasion",
38 "Data Source: Elastic Endgame",
39 "Resources: Investigation Guide",
40 "Data Source: Elastic Defend",
41 "Data Source: Sysmon",
42 "Data Source: Microsoft Defender XDR",
43 "Data Source: SentinelOne",
44 "Data Source: Crowdstrike",
45]
46timestamp_override = "event.ingested"
47type = "eql"
48
49query = '''
50file where host.os.type == "windows" and event.action != "deletion" and
51 file.extension : ("p7b", "cip") and
52 file.path : (
53 "?:\\Windows\\System32\\CodeIntegrity\\*.p7b",
54 "?:\\Windows\\System32\\CodeIntegrity\\CiPolicies\\Active\\*.cip",
55 "\\Device\\HarddiskVolume*\\Windows\\System32\\CodeIntegrity\\*.p7b",
56 "\\Device\\HarddiskVolume*\\Windows\\System32\\CodeIntegrity\\CiPolicies\\Active\\*.cip"
57 ) and
58 not process.executable : (
59 "C:\\Windows\\System32\\poqexec.exe",
60 "\\Device\\HarddiskVolume*\\Windows\\System32\\poqexec.exe",
61 "?:\\Windows\\WinSxS\\*\\TiWorker.exe",
62 "?:\\Windows\\System32\\omadmclient.exe"
63 ) and
64 /* System / ntoskrnl.exe (PID 4) */
65 not process.pid == 4
66'''
67
68note = """## Triage and analysis
69
70### Investigating WDAC Policy File by an Unusual Process
71
72#### Possible investigation steps
73
74- Does the alert show active WDAC policy placement by a non-servicing writer?
75 - Focus: `file.path`, `file.extension`, optional rename source `file.Ext.original.path`, writer `process.executable`, and `process.entity_id`. Separate "CodeIntegrity\\SiPolicy.p7b" base-policy placement from "CodeIntegrity\\CiPolicies\\Active\\*.cip" activation.
76 - Implication: escalate when an active WDAC path is written or renamed by anything other than a recognized WDAC or Windows servicing component such as "poqexec.exe"; lower suspicion only when active path, original path when present, and writer align with one recognized WDAC rollout or servicing package.
77- Is the writer a recognized deployment component or suspicious execution host?
78 - Focus: `process.executable`, `process.command_line`, `process.hash.sha256`, `process.code_signature.subject_name`, and `process.code_signature.trusted`.
79 - Implication: escalate when a script host, LOLBin, remote administration tool, or custom .NET assembly writes the policy, especially from temp, user, or share-backed paths; lower suspicion when the signer, hash, executable path, and command line all match a recognized WDAC deployment component.
80- Does the launch chain and user context fit WDAC administration?
81 - Focus: `process.parent.executable`, `process.parent.command_line`, and `user.id`.
82 - Implication: escalate when the parent chain suggests in-memory tooling, service-control abuse, remote execution, or an unexpected admin/service identity; lower suspicion when parent context and `user.id` match the same recognized WDAC workflow for this host.
83- Was the policy staged, renamed, or rapidly replaced before activation?
84 - Focus: same-writer file events on `host.id` and `process.entity_id`: `file.path`, optional `file.Ext.original.path`, `file.size`, and `file.Ext.header_bytes` when populated. $investigate_3
85 - Hint: file telemetry does not decode WDAC policy intent; preserve the written policy artifact for offline review before cleanup.
86 - Implication: escalate when rename evidence shows the policy moving from a temp, user-writable, or share-backed location into the active Code Integrity path, or when repeated writes suggest last-minute replacement; lower suspicion when file movement stays inside one recognized rollout cache path and preserves the same writer. Missing rename or header detail is unresolved, not benign.
87- Was the write followed by reboot preparation or activation behavior?
88 - Why: Krueger-style WDAC abuse relies on the next boot to make the malicious policy block security tooling, so reboot preparation changes response urgency.
89 - Focus: later process activity from the writer or its children on `host.id`: `process.name`, `process.executable`, and `process.command_line` for "shutdown.exe", restart tooling, service-control utilities, or custom reboot helpers. $investigate_4 $investigate_5
90 - Implication: escalate when the writer or parent chain quickly prepares a reboot; absence of a visible reboot helper leaves activation timing unresolved, not benign.
91- If local evidence is suspicious or unresolved, does the same writer or host pattern repeat?
92 - Focus: related alerts for `user.id` and `host.id`, compared against `process.executable`, `process.hash.sha256`, active-policy `file.path`, and any staging `file.Ext.original.path`.
93 - Hint: review Alerts associated with the user, host, and writer process. $investigate_0 $investigate_1 $investigate_2
94 - Implication: broaden scope when the same writer, hash, user, or host pattern repeats across active WDAC placements; keep scope local only when the activity is confined to one host and one bounded change window.
95- Based on active placement, writer identity, launch context, staging, reboot behavior, and recurrence, what disposition is supported?
96 - Implication: escalate on suspicious writer identity, lineage, staging, reboot, or recurrence; close only when active path, writer, lineage, and any observed staging or reboot evidence bind one recognized WDAC rollout or servicing workflow; preserve the policy artifact and escalate when evidence stays mixed or incomplete.
97
98### False positive analysis
99
100- WDAC management, servicing, security management, OEM device-control, or endpoint-hardening products can legitimately place active "SiPolicy.p7b" or "*.cip" policies. Confirm writer identity (`process.executable`, `process.hash.sha256`, `process.code_signature.subject_name`), launch context (`process.parent.executable`, `process.parent.command_line`, `user.id`), artifact path (`file.path`, and `file.Ext.original.path` when present), cache location, and reboot behavior all align with the same rollout or product writer. External change records or product inventory can corroborate only after those telemetry anchors align; contradictory identity, lineage, staging, or reboot evidence should not close as benign.
101- Bootable media creation, disk imaging, and backup tools (e.g., Rufus, Acronis, Windows Backup Engine) writing to non-system drives or volumes can trigger the rule when copying or restoring Windows installations that include CodeIntegrity policies. Check `file.path` drive letter or volume number against the host's system drive; writes to removable, secondary, or high-numbered volumes do not affect the host's WDAC protection.
102- Before creating an exception, require recurrence for the same stable writer identity, signer, parent workflow, `user.id`, `host.id`, and bounded active `file.path`. Avoid exceptions on `file.extension`, `file.name`, or the broad "CodeIntegrity" prefix alone because those conditions would suppress malicious lookalike policies.
103
104### Response and remediation
105
106- If confirmed benign, reverse any temporary containment and document the evidence that justified closure: writer identity, parent workflow, `user.id`, `file.path`, staging path, and reboot behavior all pointed to one recognized WDAC rollout or maintenance path. Create an exception only after that bounded pattern recurs.
107- If suspicious but unconfirmed, preserve the alert file event, the written "SiPolicy.p7b" or "*.cip" artifact, any rename-source evidence, the writer identity bundle, parent command context, `user.id`, and reboot-command evidence before destructive action. Apply reversible containment first, such as delaying an imminent reboot when operationally safe or temporarily restricting the writer, `user.id`, or management channel that introduced the policy.
108- If confirmed malicious, first export the preserved policy artifact and process/file evidence set. Then isolate the host when active policy placement by an unauthorized writer, repeated placement, or reboot preparation makes containment necessary. After evidence export and containment decisions, remove only the malicious WDAC policy artifacts, restore the known-good WDAC state, and review other hosts and users for the same writer, hash, active `file.path`, or staging pattern.
109- Post-incident hardening should restrict who can write to active Code Integrity paths, limit management channels that can copy policy files and reboot hosts, require controlled WDAC deployment records, and retain process and file telemetry around "CodeIntegrity" changes.
110"""
111
112setup = """## Setup
113
114This 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.
115
116Setup instructions: https://ela.st/install-elastic-defend
117
118### Additional data sources
119
120This rule also supports the following third-party data sources. For setup instructions, refer to the links below:
121
122- [CrowdStrike](https://ela.st/crowdstrike-integration)
123- [Microsoft Defender XDR](https://ela.st/m365-defender)
124- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
125- [Sysmon Event ID 11 - File Create](https://ela.st/sysmon-event-11-setup)
126"""
127
128[rule.investigation_fields]
129field_names = [
130 "@timestamp",
131 "event.action",
132 "host.name",
133 "host.id",
134 "user.name",
135 "user.id",
136 "process.entity_id",
137 "process.executable",
138 "process.command_line",
139 "process.hash.sha256",
140 "process.code_signature.subject_name",
141 "process.code_signature.trusted",
142 "process.parent.executable",
143 "process.parent.command_line",
144 "file.path",
145]
146
147[transform]
148
149[[transform.investigate]]
150label = "Alerts associated with the user"
151description = ""
152providers = [
153 [
154 { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
155 { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
156 ]
157]
158relativeFrom = "now-48h/h"
159relativeTo = "now"
160
161[[transform.investigate]]
162label = "Alerts associated with the host"
163description = ""
164providers = [
165 [
166 { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
167 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
168 ]
169]
170relativeFrom = "now-48h/h"
171relativeTo = "now"
172
173[[transform.investigate]]
174label = "Alerts associated with the writer process"
175description = ""
176providers = [
177 [
178 { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
179 { excluded = false, field = "process.executable", queryType = "phrase", value = "{{process.executable}}", valueType = "string" }
180 ]
181]
182relativeFrom = "now-48h/h"
183relativeTo = "now"
184
185[[transform.investigate]]
186label = "File events for the writer process"
187description = ""
188providers = [
189 [
190 { excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" },
191 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
192 { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
193 ]
194]
195relativeFrom = "now-1h"
196relativeTo = "now"
197
198[[transform.investigate]]
199label = "Process events for the writer process"
200description = ""
201providers = [
202 [
203 { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
204 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
205 { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
206 ]
207]
208relativeFrom = "now-1h"
209relativeTo = "now"
210
211[[transform.investigate]]
212label = "Child process events for the writer process"
213description = ""
214providers = [
215 [
216 { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
217 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
218 { excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
219 ]
220]
221relativeFrom = "now-1h"
222relativeTo = "now"
223
224[[rule.threat]]
225framework = "MITRE ATT&CK"
226
227[[rule.threat.technique]]
228id = "T1562"
229name = "Impair Defenses"
230reference = "https://attack.mitre.org/techniques/T1562/"
231
232[[rule.threat.technique.subtechnique]]
233id = "T1562.001"
234name = "Disable or Modify Tools"
235reference = "https://attack.mitre.org/techniques/T1562/001/"
236
237[rule.threat.tactic]
238id = "TA0005"
239name = "Defense Evasion"
240reference = "https://attack.mitre.org/tactics/TA0005/"
Triage and analysis
Investigating WDAC Policy File by an Unusual Process
Possible investigation steps
- Does the alert show active WDAC policy placement by a non-servicing writer?
- Focus:
file.path,file.extension, optional rename sourcefile.Ext.original.path, writerprocess.executable, andprocess.entity_id. Separate "CodeIntegrity\SiPolicy.p7b" base-policy placement from "CodeIntegrity\CiPolicies\Active*.cip" activation. - Implication: escalate when an active WDAC path is written or renamed by anything other than a recognized WDAC or Windows servicing component such as "poqexec.exe"; lower suspicion only when active path, original path when present, and writer align with one recognized WDAC rollout or servicing package.
- Focus:
- Is the writer a recognized deployment component or suspicious execution host?
- Focus:
process.executable,process.command_line,process.hash.sha256,process.code_signature.subject_name, andprocess.code_signature.trusted. - Implication: escalate when a script host, LOLBin, remote administration tool, or custom .NET assembly writes the policy, especially from temp, user, or share-backed paths; lower suspicion when the signer, hash, executable path, and command line all match a recognized WDAC deployment component.
- Focus:
- Does the launch chain and user context fit WDAC administration?
- Focus:
process.parent.executable,process.parent.command_line, anduser.id. - Implication: escalate when the parent chain suggests in-memory tooling, service-control abuse, remote execution, or an unexpected admin/service identity; lower suspicion when parent context and
user.idmatch the same recognized WDAC workflow for this host.
- Focus:
- Was the policy staged, renamed, or rapidly replaced before activation?
- Focus: same-writer file events on
host.idandprocess.entity_id:file.path, optionalfile.Ext.original.path,file.size, andfile.Ext.header_byteswhen populated. $investigate_3 - Hint: file telemetry does not decode WDAC policy intent; preserve the written policy artifact for offline review before cleanup.
- Implication: escalate when rename evidence shows the policy moving from a temp, user-writable, or share-backed location into the active Code Integrity path, or when repeated writes suggest last-minute replacement; lower suspicion when file movement stays inside one recognized rollout cache path and preserves the same writer. Missing rename or header detail is unresolved, not benign.
- Focus: same-writer file events on
- Was the write followed by reboot preparation or activation behavior?
- Why: Krueger-style WDAC abuse relies on the next boot to make the malicious policy block security tooling, so reboot preparation changes response urgency.
- Focus: later process activity from the writer or its children on
host.id:process.name,process.executable, andprocess.command_linefor "shutdown.exe", restart tooling, service-control utilities, or custom reboot helpers. $investigate_4 $investigate_5 - Implication: escalate when the writer or parent chain quickly prepares a reboot; absence of a visible reboot helper leaves activation timing unresolved, not benign.
- If local evidence is suspicious or unresolved, does the same writer or host pattern repeat?
- Focus: related alerts for
user.idandhost.id, compared againstprocess.executable,process.hash.sha256, active-policyfile.path, and any stagingfile.Ext.original.path. - Hint: review Alerts associated with the user, host, and writer process. $investigate_0 $investigate_1 $investigate_2
- Implication: broaden scope when the same writer, hash, user, or host pattern repeats across active WDAC placements; keep scope local only when the activity is confined to one host and one bounded change window.
- Focus: related alerts for
- Based on active placement, writer identity, launch context, staging, reboot behavior, and recurrence, what disposition is supported?
- Implication: escalate on suspicious writer identity, lineage, staging, reboot, or recurrence; close only when active path, writer, lineage, and any observed staging or reboot evidence bind one recognized WDAC rollout or servicing workflow; preserve the policy artifact and escalate when evidence stays mixed or incomplete.
False positive analysis
- WDAC management, servicing, security management, OEM device-control, or endpoint-hardening products can legitimately place active "SiPolicy.p7b" or "*.cip" policies. Confirm writer identity (
process.executable,process.hash.sha256,process.code_signature.subject_name), launch context (process.parent.executable,process.parent.command_line,user.id), artifact path (file.path, andfile.Ext.original.pathwhen present), cache location, and reboot behavior all align with the same rollout or product writer. External change records or product inventory can corroborate only after those telemetry anchors align; contradictory identity, lineage, staging, or reboot evidence should not close as benign. - Bootable media creation, disk imaging, and backup tools (e.g., Rufus, Acronis, Windows Backup Engine) writing to non-system drives or volumes can trigger the rule when copying or restoring Windows installations that include CodeIntegrity policies. Check
file.pathdrive letter or volume number against the host's system drive; writes to removable, secondary, or high-numbered volumes do not affect the host's WDAC protection. - Before creating an exception, require recurrence for the same stable writer identity, signer, parent workflow,
user.id,host.id, and bounded activefile.path. Avoid exceptions onfile.extension,file.name, or the broad "CodeIntegrity" prefix alone because those conditions would suppress malicious lookalike policies.
Response and remediation
- If confirmed benign, reverse any temporary containment and document the evidence that justified closure: writer identity, parent workflow,
user.id,file.path, staging path, and reboot behavior all pointed to one recognized WDAC rollout or maintenance path. Create an exception only after that bounded pattern recurs. - If suspicious but unconfirmed, preserve the alert file event, the written "SiPolicy.p7b" or "*.cip" artifact, any rename-source evidence, the writer identity bundle, parent command context,
user.id, and reboot-command evidence before destructive action. Apply reversible containment first, such as delaying an imminent reboot when operationally safe or temporarily restricting the writer,user.id, or management channel that introduced the policy. - If confirmed malicious, first export the preserved policy artifact and process/file evidence set. Then isolate the host when active policy placement by an unauthorized writer, repeated placement, or reboot preparation makes containment necessary. After evidence export and containment decisions, remove only the malicious WDAC policy artifacts, restore the known-good WDAC state, and review other hosts and users for the same writer, hash, active
file.path, or staging pattern. - Post-incident hardening should restrict who can write to active Code Integrity paths, limit management channels that can copy policy files and reboot hosts, require controlled WDAC deployment records, and retain process and file telemetry around "CodeIntegrity" changes.
References
Related rules
- Attempt to Install or Run Kali Linux via WSL
- Script Execution via Microsoft HTML Application
- Suspicious Managed Code Hosting Process
- Unusual Executable File Creation by a System Critical Process
- Bypass UAC via Event Viewer