Creation or Modification of Domain Backup DPAPI private key
Identifies the creation or modification of Domain Backup private keys. Adversaries may extract the Data Protection API (DPAPI) domain backup key from a Domain Controller (DC) to be able to decrypt any domain user master key file.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2020/08/13"
3integration = ["endpoint", "windows", "sentinel_one_cloud_funnel", "m365_defender", "crowdstrike"]
4maturity = "production"
5updated_date = "2026/09/18"
6
7[rule]
8author = ["Elastic"]
9description = """
10Identifies the creation or modification of Domain Backup private keys. Adversaries may extract the Data Protection API
11(DPAPI) domain backup key from a Domain Controller (DC) to be able to decrypt any domain user master key file.
12"""
13from = "now-9m"
14index = [
15 "winlogbeat-*",
16 "logs-endpoint.events.file-*",
17 "logs-windows.sysmon_operational-*",
18 "endgame-*",
19 "logs-sentinel_one_cloud_funnel.*",
20 "logs-m365_defender.event-*",
21 "logs-crowdstrike.fdr*",
22]
23language = "eql"
24license = "Elastic License v2"
25name = "Creation or Modification of Domain Backup DPAPI private key"
26references = [
27 "https://www.dsinternals.com/en/retrieving-dpapi-backup-keys-from-active-directory/",
28 "https://posts.specterops.io/operational-guidance-for-offensive-user-dpapi-abuse-1fb7fac8b107",
29]
30risk_score = 73
31rule_id = "b83a7e96-2eb3-4edf-8346-427b6858d3bd"
32severity = "high"
33tags = [
34 "Domain: Endpoint",
35 "OS: Windows",
36 "Use Case: Threat Detection",
37 "Tactic: Credential Access",
38 "Data Source: Elastic Endgame",
39 "Data Source: Elastic Defend",
40 "Data Source: Sysmon",
41 "Data Source: SentinelOne",
42 "Data Source: Microsoft Defender XDR",
43 "Data Source: Crowdstrike",
44 "Resources: Investigation Guide",
45 "Noise: Low",
46 "Performance: Normal",
47 "Rule Type: Event Correlation (EQL)",
48 "Platform: Windows",
49]
50timestamp_override = "event.ingested"
51type = "eql"
52
53query = '''
54file where host.os.type == "windows" and event.type != "deletion" and file.name : ("ntds_capi_*.pfx", "ntds_capi_*.pvk")
55'''
56
57note = """## Triage and analysis
58
59### Investigating Creation or Modification of Domain Backup DPAPI private key
60
61#### Possible investigation steps
62
63- Does the alert show a new or changed domain DPAPI backup key artifact?
64 - Focus: `event.type`, `event.action`, `file.name`, `file.path`, and `file.size`; distinguish `ntds_capi_*.pfx` or `ntds_capi_*.pvk` in temp, user, share, removable, archive, or controlled recovery paths.
65 - Implication: escalate on create or modify activity in staging paths or analyst home directories because the artifact can unlock domain DPAPI-protected secrets; lower suspicion only when the path is a controlled DC recovery or IR location tied to the same case.
66
67- Is the acting process a recognized recovery tool or an export utility being abused?
68 - Why: live DC retrieval and offline AD database extraction both create domain-scale DPAPI exposure once backup keys leave controlled recovery.
69 - Focus: process-start events scoped by `host.id` and `process.entity_id`, checking `process.executable`, `process.command_line`, `process.pe.original_file_name`, `process.parent.command_line`, and `process.code_signature.subject_name`. $investigate_0
70 - Implication: escalate when a shell, script host, renamed binary, or command line expresses backup-key export outside controlled recovery; lower concern only when tool identity, parent, and output path fit one controlled recovery workflow.
71
72- Did the same process export companion key material or package the result?
73 - Focus: file events scoped to `process.entity_id`, or `host.id` plus `process.pid` in a tight time window, checking `file.name`, `file.path`, `file.Ext.original.path`, and `file.Ext.original.name`. $investigate_1
74 - Implication: escalate when the process creates multiple backup-key outputs, writes companion legacy-key material, renames the files, archives them, or stages other credential-sensitive artifacts.
75 - Hint: if `ntds_capi_*` disappears quickly, trace rename events through `file.Ext.original.path` and `file.Ext.original.name`; if those fields are absent, fall back to current `file.path` plus the same `process.entity_id` or host/PID time window.
76
77- Do the user and host telemetry fit a tightly scoped recovery operator path?
78 - Focus: `user.id`, `user.name`, `user.domain`, `host.id`, and `host.name`; separate domain recovery, backup, or IR identities from standard users and ad hoc workstations.
79 - Implication: escalate when the user or host identity is mismatched, generic, or unexplained for domain backup-key handling; treat a plausible operator and host pairing as candidate benign only after the file, process, and artifact evidence also fit the same workflow.
80
81- Did follow-on activity stage the export for off-host use?
82 - Focus: process, child-process, file, and network events for the recovered process scope, especially `process.command_line`, `process.parent.command_line`, UNC, removable-media, archive, or share values in `file.path`, and off-host connections. $investigate_4 $investigate_5
83 - Implication: escalate when copy, archive, compression, removable-media, or share-write activity follows the export, especially from a non-DC host; absence of staging evidence narrows scope but does not close the alert by itself.
84
85- If local evidence remains suspicious or unresolved and related-alert telemetry is available, does the same user or host show credential-access, staging, or tier-0 alerts?
86 - Focus: optional related-alert views for `user.id`, especially DPAPI abuse, LSASS or credential dumping, DCSync, archive or share staging, lateral movement to DCs, or tier-0 persistence. $investigate_2
87 - Hint: Pivot by `host.id` when user scope is sparse or host role changes urgency; absence of related-alert telemetry is unresolved, not benign. $investigate_3
88 - Implication: broaden to domain-compromise scoping when related alerts show credential access, DC access, or staging around the same time; absence of related alerts can narrow scope but must not close the alert without local file, process, artifact, and context alignment.
89
90- Escalate on unrecognized export path, export-tool intent, companion artifacts, mismatched user or host, staging, or corroborating tier-0 alerts; close only when telemetry and recovery, backup, or IR verification bind one controlled workflow; preserve and escalate if evidence is mixed or visibility is incomplete.
91
92### False positive analysis
93
94- AD disaster-recovery, backup validation, or IR collection can legitimately export DPAPI domain backup material. Confirm telemetry first: `process.executable`, `process.command_line`, `file.path`, `user.id`, and `host.id` must all align with the same exact workflow.
95- Use a recovery ticket, backup job, or IR case only to verify an already aligned telemetry pattern; do not close on records alone. If records are unavailable, recurring telemetry is a candidate benign pattern, not closure, until it verifies one controlled recovery path without contradictory staging.
96- Before creating an exception, validate that the same `process.executable`, `process.command_line`, `file.path`, `user.id`, and `host.id` recur across prior alerts from this rule. Build the exception from that confirmed workflow, and avoid exceptions on `file.name` alone, `.pvk` or `.pfx` extensions alone, or the host alone.
97
98### Response and remediation
99
100- If confirmed benign, reverse any temporary containment and record the process path, command-line pattern, export location, operator identity, and host role that justified closure. Create an exception only if that same workflow recurs consistently across prior alerts from this rule.
101- If suspicious but unconfirmed, preserve the exported `file.path`, rename evidence from `file.Ext.original.path` or `file.Ext.original.name`, the file-event timeline, recovered `process.entity_id` or `process.pid`, `process.command_line`, responsible `user.id`, `host.id`, and any UNC, removable-media, archive, or share paths before destructive changes. Apply reversible containment first, such as temporarily restricting share access or outbound connectivity for the affected `host.id`; escalate to host isolation or account containment only if companion staging, corroborating alerts, or other findings show broader compromise and the asset role can tolerate it.
102- If confirmed malicious, preserve the same artifacts and use endpoint response to isolate the host or terminate the responsible process. If direct response is unavailable, escalate with the preserved artifact set to the team that can act. For domain controllers, weigh service impact before isolation but do not leave the export accessible.
103- If unauthorized domain backup-key export is confirmed on a domain controller, activate the organization's Active Directory compromise response plan, preserve evidence needed to scope DPAPI-protected credential exposure, and begin privileged-account hygiene according to that plan.
104- Before deleting or rotating anything, review related `host.id` and `user.id` activity for the same exported filenames, companion legacy-key artifacts, archive names, and UNC or share paths. Then eradicate the unauthorized export files, staging archives, copy utilities, scripts, and persistence mechanisms uncovered during the investigation, and remediate the privilege path or access vector that allowed the export.
105- After containment, hunt for the same exported filenames, archive names, and UNC or share paths across other hosts.
106"""
107
108setup = """## Setup
109
110This 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.
111
112Setup instructions: https://ela.st/install-elastic-defend
113
114### Additional data sources
115
116This rule also supports the following third-party data sources. For setup instructions, refer to the links below:
117
118- [CrowdStrike](https://ela.st/crowdstrike-integration)
119- [Microsoft Defender XDR](https://ela.st/m365-defender)
120- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
121- [Sysmon Event ID 11 - File Create](https://ela.st/sysmon-event-11-setup)
122"""
123
124[rule.investigation_fields]
125field_names = [
126 "@timestamp",
127 "event.type",
128 "host.id",
129 "host.name",
130 "user.name",
131 "user.id",
132 "user.domain",
133 "process.entity_id",
134 "process.pid",
135 "process.executable",
136 "process.command_line",
137 "process.parent.command_line",
138 "process.code_signature.subject_name",
139 "file.path",
140 "file.Ext.original.path",
141]
142
143[[transform.investigate]]
144label = "Process events for the alerting process"
145description = ""
146providers = [
147 [
148 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
149 { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
150 { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
151 ],
152 [
153 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
154 { excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" },
155 { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
156 ]
157]
158relativeFrom = "now-1h"
159relativeTo = "now"
160
161[[transform.investigate]]
162label = "File activity for the alerting process"
163description = ""
164providers = [
165 [
166 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
167 { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
168 { excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" }
169 ],
170 [
171 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
172 { excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" },
173 { excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" }
174 ]
175]
176relativeFrom = "now-1h"
177relativeTo = "now"
178
179[[transform.investigate]]
180label = "Alerts associated with this user"
181description = ""
182providers = [
183 [
184 { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
185 { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
186 ]
187]
188relativeFrom = "now-48h/h"
189relativeTo = "now"
190
191[[transform.investigate]]
192label = "Alerts associated with this host"
193description = ""
194providers = [
195 [
196 { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
197 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
198 ]
199]
200relativeFrom = "now-48h/h"
201relativeTo = "now"
202
203[[transform.investigate]]
204label = "Child processes of the export process"
205description = ""
206providers = [
207 [
208 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
209 { excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
210 { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
211 ]
212]
213relativeFrom = "now-1h"
214relativeTo = "now"
215
216[[transform.investigate]]
217label = "Network activity for the export process and children"
218description = ""
219providers = [
220 [
221 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
222 { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
223 { excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" }
224 ],
225 [
226 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
227 { excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
228 { excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" }
229 ]
230]
231relativeFrom = "now-1h"
232relativeTo = "now"
233
234[[rule.threat]]
235framework = "MITRE ATT&CK"
236
237[[rule.threat.technique]]
238id = "T1003"
239name = "OS Credential Dumping"
240reference = "https://attack.mitre.org/techniques/T1003/"
241
242[[rule.threat.technique.subtechnique]]
243id = "T1003.003"
244name = "NTDS"
245reference = "https://attack.mitre.org/techniques/T1003/003/"
246
247[[rule.threat.technique]]
248id = "T1552"
249name = "Unsecured Credentials"
250reference = "https://attack.mitre.org/techniques/T1552/"
251
252[[rule.threat.technique.subtechnique]]
253id = "T1552.004"
254name = "Private Keys"
255reference = "https://attack.mitre.org/techniques/T1552/004/"
256
257[[rule.threat.technique]]
258id = "T1555"
259name = "Credentials from Password Stores"
260reference = "https://attack.mitre.org/techniques/T1555/"
261
262[rule.threat.tactic]
263id = "TA0006"
264name = "Credential Access"
265reference = "https://attack.mitre.org/tactics/TA0006/"
Triage and analysis
Investigating Creation or Modification of Domain Backup DPAPI private key
Possible investigation steps
-
Does the alert show a new or changed domain DPAPI backup key artifact?
- Focus:
event.type,event.action,file.name,file.path, andfile.size; distinguishntds_capi_*.pfxorntds_capi_*.pvkin temp, user, share, removable, archive, or controlled recovery paths. - Implication: escalate on create or modify activity in staging paths or analyst home directories because the artifact can unlock domain DPAPI-protected secrets; lower suspicion only when the path is a controlled DC recovery or IR location tied to the same case.
- Focus:
-
Is the acting process a recognized recovery tool or an export utility being abused?
- Why: live DC retrieval and offline AD database extraction both create domain-scale DPAPI exposure once backup keys leave controlled recovery.
- Focus: process-start events scoped by
host.idandprocess.entity_id, checkingprocess.executable,process.command_line,process.pe.original_file_name,process.parent.command_line, andprocess.code_signature.subject_name. $investigate_0 - Implication: escalate when a shell, script host, renamed binary, or command line expresses backup-key export outside controlled recovery; lower concern only when tool identity, parent, and output path fit one controlled recovery workflow.
-
Did the same process export companion key material or package the result?
- Focus: file events scoped to
process.entity_id, orhost.idplusprocess.pidin a tight time window, checkingfile.name,file.path,file.Ext.original.path, andfile.Ext.original.name. $investigate_1 - Implication: escalate when the process creates multiple backup-key outputs, writes companion legacy-key material, renames the files, archives them, or stages other credential-sensitive artifacts.
- Hint: if
ntds_capi_*disappears quickly, trace rename events throughfile.Ext.original.pathandfile.Ext.original.name; if those fields are absent, fall back to currentfile.pathplus the sameprocess.entity_idor host/PID time window.
- Focus: file events scoped to
-
Do the user and host telemetry fit a tightly scoped recovery operator path?
- Focus:
user.id,user.name,user.domain,host.id, andhost.name; separate domain recovery, backup, or IR identities from standard users and ad hoc workstations. - Implication: escalate when the user or host identity is mismatched, generic, or unexplained for domain backup-key handling; treat a plausible operator and host pairing as candidate benign only after the file, process, and artifact evidence also fit the same workflow.
- Focus:
-
Did follow-on activity stage the export for off-host use?
- Focus: process, child-process, file, and network events for the recovered process scope, especially
process.command_line,process.parent.command_line, UNC, removable-media, archive, or share values infile.path, and off-host connections. $investigate_4 $investigate_5 - Implication: escalate when copy, archive, compression, removable-media, or share-write activity follows the export, especially from a non-DC host; absence of staging evidence narrows scope but does not close the alert by itself.
- Focus: process, child-process, file, and network events for the recovered process scope, especially
-
If local evidence remains suspicious or unresolved and related-alert telemetry is available, does the same user or host show credential-access, staging, or tier-0 alerts?
- Focus: optional related-alert views for
user.id, especially DPAPI abuse, LSASS or credential dumping, DCSync, archive or share staging, lateral movement to DCs, or tier-0 persistence. $investigate_2 - Hint: Pivot by
host.idwhen user scope is sparse or host role changes urgency; absence of related-alert telemetry is unresolved, not benign. $investigate_3 - Implication: broaden to domain-compromise scoping when related alerts show credential access, DC access, or staging around the same time; absence of related alerts can narrow scope but must not close the alert without local file, process, artifact, and context alignment.
- Focus: optional related-alert views for
-
Escalate on unrecognized export path, export-tool intent, companion artifacts, mismatched user or host, staging, or corroborating tier-0 alerts; close only when telemetry and recovery, backup, or IR verification bind one controlled workflow; preserve and escalate if evidence is mixed or visibility is incomplete.
False positive analysis
- AD disaster-recovery, backup validation, or IR collection can legitimately export DPAPI domain backup material. Confirm telemetry first:
process.executable,process.command_line,file.path,user.id, andhost.idmust all align with the same exact workflow. - Use a recovery ticket, backup job, or IR case only to verify an already aligned telemetry pattern; do not close on records alone. If records are unavailable, recurring telemetry is a candidate benign pattern, not closure, until it verifies one controlled recovery path without contradictory staging.
- Before creating an exception, validate that the same
process.executable,process.command_line,file.path,user.id, andhost.idrecur across prior alerts from this rule. Build the exception from that confirmed workflow, and avoid exceptions onfile.namealone,.pvkor.pfxextensions alone, or the host alone.
Response and remediation
- If confirmed benign, reverse any temporary containment and record the process path, command-line pattern, export location, operator identity, and host role that justified closure. Create an exception only if that same workflow recurs consistently across prior alerts from this rule.
- If suspicious but unconfirmed, preserve the exported
file.path, rename evidence fromfile.Ext.original.pathorfile.Ext.original.name, the file-event timeline, recoveredprocess.entity_idorprocess.pid,process.command_line, responsibleuser.id,host.id, and any UNC, removable-media, archive, or share paths before destructive changes. Apply reversible containment first, such as temporarily restricting share access or outbound connectivity for the affectedhost.id; escalate to host isolation or account containment only if companion staging, corroborating alerts, or other findings show broader compromise and the asset role can tolerate it. - If confirmed malicious, preserve the same artifacts and use endpoint response to isolate the host or terminate the responsible process. If direct response is unavailable, escalate with the preserved artifact set to the team that can act. For domain controllers, weigh service impact before isolation but do not leave the export accessible.
- If unauthorized domain backup-key export is confirmed on a domain controller, activate the organization's Active Directory compromise response plan, preserve evidence needed to scope DPAPI-protected credential exposure, and begin privileged-account hygiene according to that plan.
- Before deleting or rotating anything, review related
host.idanduser.idactivity for the same exported filenames, companion legacy-key artifacts, archive names, and UNC or share paths. Then eradicate the unauthorized export files, staging archives, copy utilities, scripts, and persistence mechanisms uncovered during the investigation, and remediate the privilege path or access vector that allowed the export. - After containment, hunt for the same exported filenames, archive names, and UNC or share paths across other hosts.
References
Related rules
- NTDS Dump via Wbadmin
- Potential Veeam Credential Access Command
- Symbolic Link to Shadow Copy Created
- Active Directory Discovery using AdExplorer
- Code Signing Policy Modification Through Built-in tools