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/04/22"
  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]
 46timestamp_override = "event.ingested"
 47type = "eql"
 48
 49query = '''
 50file where host.os.type == "windows" and event.type != "deletion" and file.name : ("ntds_capi_*.pfx", "ntds_capi_*.pvk")
 51'''
 52
 53note = """## Triage and analysis
 54
 55### Investigating Creation or Modification of Domain Backup DPAPI private key
 56
 57#### Possible investigation steps
 58
 59- Does the alert show a new or changed domain DPAPI backup key artifact?
 60  - 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.
 61  - 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.
 62
 63- Is the acting process a recognized recovery tool or an export utility being abused?
 64  - Why: live DC retrieval and offline AD database extraction both create domain-scale DPAPI exposure once backup keys leave controlled recovery.
 65  - 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
 66  - 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.
 67
 68- Did the same process export companion key material or package the result?
 69  - 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
 70  - 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.
 71  - 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.
 72
 73- Do the user and host telemetry fit a tightly scoped recovery operator path?
 74  - 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.
 75  - 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.
 76
 77- Did follow-on activity stage the export for off-host use?
 78  - 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
 79  - 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.
 80
 81- 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?
 82  - 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
 83  - 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
 84  - 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.
 85
 86- 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.
 87
 88### False positive analysis
 89
 90- 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.
 91- 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.
 92- 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.
 93
 94### Response and remediation
 95
 96- 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.
 97- 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.
 98- 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.
 99- 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.
100- 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.
101- After containment, hunt for the same exported filenames, archive names, and UNC or share paths across other hosts.
102"""
103
104setup = """## Setup
105
106This 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.
107
108Setup instructions: https://ela.st/install-elastic-defend
109
110### Additional data sources
111
112This rule also supports the following third-party data sources. For setup instructions, refer to the links below:
113
114- [CrowdStrike](https://ela.st/crowdstrike-integration)
115- [Microsoft Defender XDR](https://ela.st/m365-defender)
116- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
117- [Sysmon Event ID 11 - File Create](https://ela.st/sysmon-event-11-setup)
118"""
119
120[rule.investigation_fields]
121field_names = [
122    "@timestamp",
123    "event.type",
124    "host.id",
125    "host.name",
126    "user.name",
127    "user.id",
128    "user.domain",
129    "process.entity_id",
130    "process.pid",
131    "process.executable",
132    "process.command_line",
133    "process.parent.command_line",
134    "process.code_signature.subject_name",
135    "file.path",
136    "file.Ext.original.path",
137]
138
139[[transform.investigate]]
140label = "Process events for the alerting process"
141description = ""
142providers = [
143  [
144    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
145    { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
146    { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
147  ],
148  [
149    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
150    { excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" },
151    { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
152  ]
153]
154relativeFrom = "now-1h"
155relativeTo = "now"
156
157[[transform.investigate]]
158label = "File activity for the alerting process"
159description = ""
160providers = [
161  [
162    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
163    { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
164    { excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" }
165  ],
166  [
167    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
168    { excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" },
169    { excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" }
170  ]
171]
172relativeFrom = "now-1h"
173relativeTo = "now"
174
175[[transform.investigate]]
176label = "Alerts associated with this user"
177description = ""
178providers = [
179  [
180    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
181    { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
182  ]
183]
184relativeFrom = "now-48h/h"
185relativeTo = "now"
186
187[[transform.investigate]]
188label = "Alerts associated with this host"
189description = ""
190providers = [
191  [
192    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
193    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
194  ]
195]
196relativeFrom = "now-48h/h"
197relativeTo = "now"
198
199[[transform.investigate]]
200label = "Child processes of the export process"
201description = ""
202providers = [
203  [
204    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
205    { excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
206    { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
207  ]
208]
209relativeFrom = "now-1h"
210relativeTo = "now"
211
212[[transform.investigate]]
213label = "Network activity for the export process and children"
214description = ""
215providers = [
216  [
217    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
218    { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
219    { excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" }
220  ],
221  [
222    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
223    { excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
224    { excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" }
225  ]
226]
227relativeFrom = "now-1h"
228relativeTo = "now"
229
230[[rule.threat]]
231framework = "MITRE ATT&CK"
232
233[[rule.threat.technique]]
234id = "T1003"
235name = "OS Credential Dumping"
236reference = "https://attack.mitre.org/techniques/T1003/"
237
238[[rule.threat.technique.subtechnique]]
239id = "T1003.003"
240name = "NTDS"
241reference = "https://attack.mitre.org/techniques/T1003/003/"
242
243[[rule.threat.technique]]
244id = "T1552"
245name = "Unsecured Credentials"
246reference = "https://attack.mitre.org/techniques/T1552/"
247
248[[rule.threat.technique.subtechnique]]
249id = "T1552.004"
250name = "Private Keys"
251reference = "https://attack.mitre.org/techniques/T1552/004/"
252
253[[rule.threat.technique]]
254id = "T1555"
255name = "Credentials from Password Stores"
256reference = "https://attack.mitre.org/techniques/T1555/"
257
258[rule.threat.tactic]
259id = "TA0006"
260name = "Credential Access"
261reference = "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, and file.size; distinguish ntds_capi_*.pfx or ntds_capi_*.pvk in 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.
  • 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.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
    • 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, 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
    • 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 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.
  • Do the user and host telemetry fit a tightly scoped recovery operator path?

    • 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.
    • 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.
  • 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 in file.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.
  • 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.id when 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.
  • 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, and host.id must 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, 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.

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 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.
  • 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.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.
  • After containment, hunt for the same exported filenames, archive names, and UNC or share paths across other hosts.

References

Related rules

to-top