AdminSDHolder Backdoor
Detects modifications in the AdminSDHolder object. Attackers can abuse the SDProp process to implement a persistent backdoor in Active Directory. SDProp compares the permissions on protected objects with those defined on the AdminSDHolder object. If the permissions on any of the protected accounts and groups do not match, the permissions on the protected accounts and groups are reset to match those of the domain's AdminSDHolder object, regaining their Administrative Privileges.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2022/01/31"
3integration = ["system", "windows"]
4maturity = "production"
5updated_date = "2026/05/03"
6
7[rule]
8author = ["Elastic"]
9description = """
10Detects modifications in the AdminSDHolder object. Attackers can abuse the SDProp process to implement a persistent
11backdoor in Active Directory. SDProp compares the permissions on protected objects with those defined on the
12AdminSDHolder object. If the permissions on any of the protected accounts and groups do not match, the permissions on
13the protected accounts and groups are reset to match those of the domain's AdminSDHolder object, regaining their
14Administrative Privileges.
15"""
16from = "now-9m"
17index = ["winlogbeat-*", "logs-system.security*", "logs-windows.forwarded*"]
18language = "kuery"
19license = "Elastic License v2"
20name = "AdminSDHolder Backdoor"
21references = [
22 "https://adsecurity.org/?p=1906",
23 "https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/plan/security-best-practices/appendix-c--protected-accounts-and-groups-in-active-directory",
24]
25risk_score = 73
26rule_id = "6e9130a5-9be6-48e5-943a-9628bfc74b18"
27severity = "high"
28tags = [
29 "Domain: Endpoint",
30 "OS: Windows",
31 "Use Case: Threat Detection",
32 "Tactic: Persistence",
33 "Use Case: Active Directory Monitoring",
34 "Data Source: Active Directory",
35 "Data Source: Windows Security Event Logs",
36 "Resources: Investigation Guide",
37]
38timestamp_override = "event.ingested"
39type = "query"
40
41query = '''
42event.code:5136 and host.os.type:"windows" and winlog.event_data.ObjectDN:CN=AdminSDHolder,CN=System*
43'''
44
45note = """## Triage and analysis
46
47### Investigating AdminSDHolder Backdoor
48
49#### Possible investigation steps
50
51- What AdminSDHolder change did the alert preserve?
52 - Focus: confirm `winlog.event_data.ObjectDN` under AdminSDHolder, then read `winlog.event_data.AttributeLDAPDisplayName`, `winlog.event_data.OperationType`, `winlog.event_data.AttributeValue`, and `winlog.event_data.AttributeSyntaxOID`.
53 - Implication: escalate on "nTSecurityDescriptor", ownership data, or any value that can alter control of protected objects; lower concern only for non-security metadata tied to a recognized tier-0 maintenance workflow.
54
55- What did the correlated 5136 operation contain?
56 - Why: one alert document may show only part of a logical directory change; `winlog.event_data.OpCorrelationID` reconstructs the rest of the operation.
57 - Focus: review same-controller `5136` events for the same `host.id`, `winlog.computer_name`, and `winlog.event_data.OpCorrelationID`; compare attribute, value, and operation type. $investigate_0
58 - Implication: escalate when the operation adds multiple ACL changes, touches unrelated sensitive attributes, or suggests a staged AdminSDHolder template rewrite; lower concern only when bounded to one expected non-security update on the same object.
59
60- Does the recovered value grant or preserve access that SDProp can stamp onto protected identities?
61 - Why: AdminSDHolder is the ACL template for protected accounts and groups, so a small template edit can become persistent privileged access after SDProp runs.
62 - Focus: interpret attribute name, value, and syntax for a new trustee, ACE, owner reference, or delegated right rather than non-security metadata.
63 - Implication: escalate when the value adds a SID, DN, ACE, owner path, Full Control, Modify, WriteDacl, WriteOwner, or GenericAll outside the expected tier-0 admin set; truncated or opaque values keep permission impact unresolved and require preserving raw change data.
64
65- Who initiated the modification, and where did the session originate?
66 - Focus: identify the writer and controller with `user.id`, `winlog.event_data.SubjectUserSid`, `winlog.event_data.SubjectLogonId`, and `winlog.computer_name`.
67 - Hint: on the same `winlog.computer_name`, match `5136` `winlog.event_data.SubjectLogonId` to `4624` `winlog.event_data.TargetLogonId`; search `4648` for the same `winlog.event_data.SubjectLogonId` when explicit credentials matter, then read `source.ip` and `winlog.event_data.AuthenticationPackageName`. Missing linked authentication records or `source.ip` leaves origin unresolved, not benign.
68 - $investigate_1
69 - $investigate_2
70 - Implication: escalate when the writer is unexpected, source or auth method does not fit tier-0 administration, or origin remains unresolved with a security-relevant change; do not wait on auth pivots when the attribute/value and change set already prove unauthorized rights.
71
72- Did the template change propagate or get forced onto protected objects?
73 - Why: SDProp can apply the AdminSDHolder template to protected accounts and groups, so impact may appear after the initial directory-change event.
74 - Focus: on the same `winlog.event_data.DSName` or `winlog.computer_name`, review later `5136` events for object, attribute, writer, and time on protected users or groups.
75 - Hint: if the logging controller has no follow-on records, search the same `winlog.event_data.DSName` across domain controllers; absence on one controller does not clear propagation. $investigate_3
76 - Implication: escalate when later events show security-descriptor, owner, or trustee changes on protected identities after the AdminSDHolder edit; no follow-on `5136` visibility leaves propagation unresolved, not benign.
77
78- Escalate when object, security-relevant attribute/value, `winlog.event_data.OpCorrelationID`, writer/session origin, or propagation evidence shows unauthorized control; close only when the exact change, bounded `5136` set, actor/session origin, and available change or baseline record all point to one recognized tier-0 workflow; preserve directory-change evidence and escalate mixed or incomplete answers. If local answers stay suspicious or unresolved, review alerts for the modifying `user.id`; use controller `host.id` alert history only when actor evidence is sparse or controller compromise is plausible.
79 - $investigate_4
80 - $investigate_5
81
82### False positive analysis
83
84- AdminSDHolder ACL hardening, delegated-directory cleanup, security-baseline tooling, or migration automation are narrow tier-0 exceptions, not routine administration. Confirm the exact attribute/value/operation for `winlog.event_data.ObjectDN`, expected admin or service-account session, bounded `winlog.event_data.OpCorrelationID`, matching controller/template rollout, and no unrelated actor or controller alerts. If change records, automation inventory, or deployment records exist, require alignment; otherwise prove the current actor/action or service-account/template fit from telemetry first, then use prior recurrence only to support exception stability.
85- Before creating an exception, validate recurrence of the same `user.id` or `winlog.event_data.SubjectUserSid`, specific attribute, object, `winlog.event_data.DSName`, bounded operation shape, and controller pattern across prior alerts from this rule. Build the exception from that minimum confirmed workflow only after the current event is fully explained, and avoid exceptions on AdminSDHolder changes, Windows Security event "5136", or the rule name alone.
86
87### Response and remediation
88
89- If confirmed benign, reverse any temporary containment and record the exact actor, session, AdminSDHolder object, changed attribute, operation-correlation, and controller pattern that proved the recognized workflow. Do not keep a broad exception unless the same workflow recurs.
90- If suspicious but unconfirmed, preserve the triggering `5136` event, the correlated `winlog.event_data.OpCorrelationID` change set, the current AdminSDHolder security descriptor, linked `4624` or `4648` session records, and case exports before containment. Apply reversible containment first, such as temporarily restricting the modifying account's directory-write path or increasing monitoring on the recovered actor and controller. Use broader account disablement or domain-controller isolation only if related alerts or follow-on directory abuse show active compromise and the AD response owner accepts the operational impact.
91- If confirmed malicious, export the current AdminSDHolder security descriptor, recovered `5136` change set, replication context, implicated object identity, actor SID, logon session, and source-origin evidence before rollback or account action. Contain the modifying account and any recovered source endpoint or IP through identity-response or endpoint-response tooling; if direct response is unavailable, escalate that preserved evidence set to the AD or incident-response team that can act.
92- After containment, review protected users and groups for unauthorized ACEs, owner changes, or delegated rights that may have been restamped from the tampered template before removing them. Restore the AdminSDHolder ACL to a known-good state, verify clean replication across domain controllers, then reset or rotate privileged credentials exposed or newly granted through the unauthorized template.
93- Post-incident hardening: restrict AdminSDHolder write access to dedicated tier-0 administration paths, baseline the expected AdminSDHolder security descriptor, keep directory-service change auditing for `5136` and linked authentication logging enabled on domain controllers, and record telemetry gaps that limited the investigation.
94"""
95
96setup = """## Setup
97
98Audit Directory Service Changes must be enabled to generate the events used by this rule.
99Setup instructions: https://ela.st/audit-directory-service-changes
100"""
101
102[rule.investigation_fields]
103field_names = [
104 "@timestamp",
105 "user.id",
106 "winlog.event_data.SubjectUserName",
107 "winlog.event_data.SubjectUserSid",
108 "winlog.event_data.SubjectLogonId",
109 "winlog.event_data.ObjectDN",
110 "winlog.event_data.ObjectClass",
111 "winlog.event_data.AttributeLDAPDisplayName",
112 "winlog.event_data.AttributeValue",
113 "winlog.event_data.OperationType",
114 "winlog.event_data.OpCorrelationID",
115 "winlog.event_data.DSName",
116 "host.id",
117 "winlog.computer_name",
118]
119
120[transform]
121
122[[transform.investigate]]
123label = "All 5136 events in this AdminSDHolder change set"
124description = ""
125providers = [
126 [
127 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
128 { excluded = false, field = "winlog.event_data.OpCorrelationID", queryType = "phrase", value = "{{winlog.event_data.OpCorrelationID}}", valueType = "string" },
129 { excluded = false, field = "event.code", queryType = "phrase", value = "5136", valueType = "string" }
130 ]
131]
132relativeFrom = "now-24h/h"
133relativeTo = "now"
134
135[[transform.investigate]]
136label = "Linked logon for the modifying session"
137description = ""
138providers = [
139 [
140 { excluded = false, field = "winlog.computer_name", queryType = "phrase", value = "{{winlog.computer_name}}", valueType = "string" },
141 { excluded = false, field = "winlog.event_data.TargetLogonId", queryType = "phrase", value = "{{winlog.event_data.SubjectLogonId}}", valueType = "string" },
142 { excluded = false, field = "event.code", queryType = "phrase", value = "4624", valueType = "string" }
143 ]
144]
145relativeFrom = "now-24h/h"
146relativeTo = "now"
147
148[[transform.investigate]]
149label = "Explicit credential events for the modifying session"
150description = ""
151providers = [
152 [
153 { excluded = false, field = "winlog.computer_name", queryType = "phrase", value = "{{winlog.computer_name}}", valueType = "string" },
154 { excluded = false, field = "winlog.event_data.SubjectLogonId", queryType = "phrase", value = "{{winlog.event_data.SubjectLogonId}}", valueType = "string" },
155 { excluded = false, field = "event.code", queryType = "phrase", value = "4648", valueType = "string" }
156 ]
157]
158relativeFrom = "now-24h/h"
159relativeTo = "now"
160
161[[transform.investigate]]
162label = "Later 5136 changes in the same directory service"
163description = ""
164providers = [
165 [
166 { excluded = false, field = "winlog.event_data.DSName", queryType = "phrase", value = "{{winlog.event_data.DSName}}", valueType = "string" },
167 { excluded = false, field = "event.code", queryType = "phrase", value = "5136", valueType = "string" }
168 ],
169 [
170 { excluded = false, field = "winlog.computer_name", queryType = "phrase", value = "{{winlog.computer_name}}", valueType = "string" },
171 { excluded = false, field = "event.code", queryType = "phrase", value = "5136", valueType = "string" }
172 ]
173]
174relativeFrom = "now"
175relativeTo = "now"
176
177[[transform.investigate]]
178label = "Recent alerts tied to this modifying identity"
179description = ""
180providers = [
181 [
182 { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
183 { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
184 ]
185]
186relativeFrom = "now-48h/h"
187relativeTo = "now"
188
189[[transform.investigate]]
190label = "Recent alerts on this domain controller"
191description = ""
192providers = [
193 [
194 { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
195 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
196 ]
197]
198relativeFrom = "now-48h/h"
199relativeTo = "now"
200
201[[rule.threat]]
202framework = "MITRE ATT&CK"
203
204[[rule.threat.technique]]
205id = "T1078"
206name = "Valid Accounts"
207reference = "https://attack.mitre.org/techniques/T1078/"
208
209[[rule.threat.technique.subtechnique]]
210id = "T1078.002"
211name = "Domain Accounts"
212reference = "https://attack.mitre.org/techniques/T1078/002/"
213
214[[rule.threat.technique]]
215id = "T1098"
216name = "Account Manipulation"
217reference = "https://attack.mitre.org/techniques/T1098/"
218
219[rule.threat.tactic]
220id = "TA0003"
221name = "Persistence"
222reference = "https://attack.mitre.org/tactics/TA0003/"
Triage and analysis
Investigating AdminSDHolder Backdoor
Possible investigation steps
-
What AdminSDHolder change did the alert preserve?
- Focus: confirm
winlog.event_data.ObjectDNunder AdminSDHolder, then readwinlog.event_data.AttributeLDAPDisplayName,winlog.event_data.OperationType,winlog.event_data.AttributeValue, andwinlog.event_data.AttributeSyntaxOID. - Implication: escalate on "nTSecurityDescriptor", ownership data, or any value that can alter control of protected objects; lower concern only for non-security metadata tied to a recognized tier-0 maintenance workflow.
- Focus: confirm
-
What did the correlated 5136 operation contain?
- Why: one alert document may show only part of a logical directory change;
winlog.event_data.OpCorrelationIDreconstructs the rest of the operation. - Focus: review same-controller
5136events for the samehost.id,winlog.computer_name, andwinlog.event_data.OpCorrelationID; compare attribute, value, and operation type. $investigate_0 - Implication: escalate when the operation adds multiple ACL changes, touches unrelated sensitive attributes, or suggests a staged AdminSDHolder template rewrite; lower concern only when bounded to one expected non-security update on the same object.
- Why: one alert document may show only part of a logical directory change;
-
Does the recovered value grant or preserve access that SDProp can stamp onto protected identities?
- Why: AdminSDHolder is the ACL template for protected accounts and groups, so a small template edit can become persistent privileged access after SDProp runs.
- Focus: interpret attribute name, value, and syntax for a new trustee, ACE, owner reference, or delegated right rather than non-security metadata.
- Implication: escalate when the value adds a SID, DN, ACE, owner path, Full Control, Modify, WriteDacl, WriteOwner, or GenericAll outside the expected tier-0 admin set; truncated or opaque values keep permission impact unresolved and require preserving raw change data.
-
Who initiated the modification, and where did the session originate?
- Focus: identify the writer and controller with
user.id,winlog.event_data.SubjectUserSid,winlog.event_data.SubjectLogonId, andwinlog.computer_name. - Hint: on the same
winlog.computer_name, match5136winlog.event_data.SubjectLogonIdto4624winlog.event_data.TargetLogonId; search4648for the samewinlog.event_data.SubjectLogonIdwhen explicit credentials matter, then readsource.ipandwinlog.event_data.AuthenticationPackageName. Missing linked authentication records orsource.ipleaves origin unresolved, not benign.- $investigate_1
- $investigate_2
- Implication: escalate when the writer is unexpected, source or auth method does not fit tier-0 administration, or origin remains unresolved with a security-relevant change; do not wait on auth pivots when the attribute/value and change set already prove unauthorized rights.
- Focus: identify the writer and controller with
-
Did the template change propagate or get forced onto protected objects?
- Why: SDProp can apply the AdminSDHolder template to protected accounts and groups, so impact may appear after the initial directory-change event.
- Focus: on the same
winlog.event_data.DSNameorwinlog.computer_name, review later5136events for object, attribute, writer, and time on protected users or groups. - Hint: if the logging controller has no follow-on records, search the same
winlog.event_data.DSNameacross domain controllers; absence on one controller does not clear propagation. $investigate_3 - Implication: escalate when later events show security-descriptor, owner, or trustee changes on protected identities after the AdminSDHolder edit; no follow-on
5136visibility leaves propagation unresolved, not benign.
-
Escalate when object, security-relevant attribute/value,
winlog.event_data.OpCorrelationID, writer/session origin, or propagation evidence shows unauthorized control; close only when the exact change, bounded5136set, actor/session origin, and available change or baseline record all point to one recognized tier-0 workflow; preserve directory-change evidence and escalate mixed or incomplete answers. If local answers stay suspicious or unresolved, review alerts for the modifyinguser.id; use controllerhost.idalert history only when actor evidence is sparse or controller compromise is plausible.- $investigate_4
- $investigate_5
False positive analysis
- AdminSDHolder ACL hardening, delegated-directory cleanup, security-baseline tooling, or migration automation are narrow tier-0 exceptions, not routine administration. Confirm the exact attribute/value/operation for
winlog.event_data.ObjectDN, expected admin or service-account session, boundedwinlog.event_data.OpCorrelationID, matching controller/template rollout, and no unrelated actor or controller alerts. If change records, automation inventory, or deployment records exist, require alignment; otherwise prove the current actor/action or service-account/template fit from telemetry first, then use prior recurrence only to support exception stability. - Before creating an exception, validate recurrence of the same
user.idorwinlog.event_data.SubjectUserSid, specific attribute, object,winlog.event_data.DSName, bounded operation shape, and controller pattern across prior alerts from this rule. Build the exception from that minimum confirmed workflow only after the current event is fully explained, and avoid exceptions on AdminSDHolder changes, Windows Security event "5136", or the rule name alone.
Response and remediation
- If confirmed benign, reverse any temporary containment and record the exact actor, session, AdminSDHolder object, changed attribute, operation-correlation, and controller pattern that proved the recognized workflow. Do not keep a broad exception unless the same workflow recurs.
- If suspicious but unconfirmed, preserve the triggering
5136event, the correlatedwinlog.event_data.OpCorrelationIDchange set, the current AdminSDHolder security descriptor, linked4624or4648session records, and case exports before containment. Apply reversible containment first, such as temporarily restricting the modifying account's directory-write path or increasing monitoring on the recovered actor and controller. Use broader account disablement or domain-controller isolation only if related alerts or follow-on directory abuse show active compromise and the AD response owner accepts the operational impact. - If confirmed malicious, export the current AdminSDHolder security descriptor, recovered
5136change set, replication context, implicated object identity, actor SID, logon session, and source-origin evidence before rollback or account action. Contain the modifying account and any recovered source endpoint or IP through identity-response or endpoint-response tooling; if direct response is unavailable, escalate that preserved evidence set to the AD or incident-response team that can act. - After containment, review protected users and groups for unauthorized ACEs, owner changes, or delegated rights that may have been restamped from the tampered template before removing them. Restore the AdminSDHolder ACL to a known-good state, verify clean replication across domain controllers, then reset or rotate privileged credentials exposed or newly granted through the unauthorized template.
- Post-incident hardening: restrict AdminSDHolder write access to dedicated tier-0 administration paths, baseline the expected AdminSDHolder security descriptor, keep directory-service change auditing for
5136and linked authentication logging enabled on domain controllers, and record telemetry gaps that limited the investigation.
References
Related rules
- AdminSDHolder SDProp Exclusion Added
- KRBTGT Delegation Backdoor
- Account Configured with Never-Expiring Password
- Active Directory Group Modification by SYSTEM
- User Added to Privileged Group in Active Directory