Mehmet Ergene
Detecting BadSuccessor: Shorcut to Domain Admin
Yuval Gordon from Akamai recently introduced BadSuccessor, a critical attack technique that enables low-privileged users to escalate privileges to Domain Admin by abusing the Delegated Managed Service Accounts (dMSA) feature in Windows Server 2025.
This post explains the practical implications of the attack, how it evades detection in default auditing configuration, and how defenders can reliably detect such abuse by configuring targeted object-level auditing in Active Directory.
Understanding dMSA
Delegated Managed Service Accounts (dMSA) are a new feature in Active Directory, introduced in Windows Server 2025, designed to replace and modernize legacy service accounts to reduce attack surface. To leverage dMSA, all domain controllers and participating servers that want to use dMSA must be running Windows Server 2025, and the domain functional level must be Windows Server 2025.
A typical dMSA migration of a legacy service account involves three steps (the svc_account01 in the examples is the legacy service account):
1. Create the dMSA:
This creates the account under the Managed Service Accounts OU. As of now, there is no documented parameter to override this OU path. (This information will be important for detection)
2. Initiate the migration:
3. Complete the migration:
Once complete, the legacy account (svc_account01) is disabled, and the new dMSA takes over.
dMSA Telemetry with Recommended Audit Configuration
With the default recommended audit configuration (applied via GPO), a standard dMSA migration generates limited telemetry on the domain controller. For instance, Event ID 5137 (object creation) is not generated as seen in the image below.

This results from default object level auditing on the domain, which is insufficient. (Or, I had an issue on a freshly migrated domain which is less likely)
BadSuccessor: Exploiting dMSA
P.S.: I continued testing without modifying the audit settings since I wasn't aware during the test. New accounts were used: sus_dMSA and svc_account06(svcAccount06)
There are currently two public tools, SharpSucessor and BadSuccessor.ps1, to exploit the dMSA feature by:
- Creating a dMSA in an OU where the attacker(low-privileged user) has permissions.
- Linking it to a high-privilege account via msDS-ManagedAccountPrecededByLink.
- Faking migration completion by setting msDS-DelegatedMSAState to 2.
Example BadSuccessor usage:
With all recommended audit policies enabled, this activity produces no relevant events on the domain controller as seen below:

Improving Object Auditing
On top of recommended audit policies(applied via GPO), object-level auditing must be manually configured to monitor dMSA operations effectively and detect abuse:

Note that there is currently no option to enable Write operation for the msDS-ManagedAccountPrecededByLink and msDS-DelegatedManagedServiceAccount. Therefore, I enabled "Write all properties" option.

Telemetry After Object Auditing Enhancements
After adding the new auditing configuration and testing the malicious dMSA abuse (with new accounts), all telemetry is generated:

Not surprisingly, legitimate dMSA migration generates more events:

Detecting dMSA Abuse
Based on differences in telemetry between legitimate dMSA migration and malicious dMSA activity, the following detection ideas (and maybe more) can be produced:
1. dMSA Creation Outside the Managed Service Accounts OU
Legitimate dMSAs are created in the Managed Service Accounts OU. Assuming a low-privileged user wouldn't have enough permissions on this OU, we can flag any dMSA creation outside this OU.
let domain_dns_name = "otrf.local"; // replace with your domain dns name
let msa_cn = "CN=Managed Service Accounts";
// print replace_string(domain_dns_name, ".", ',DC=')
let msa_dn = strcat(msa_cn, ',DC=', replace_string(domain_dns_name, ".", ',DC='));
SecurityEvent
| where EventID == 5137
| where EventData has "msDS-DelegatedManagedServiceAccount"
| extend EventData = parse_xml(EventData)
| extend EventData = EventData.EventData.Data
| mv-apply EventData on (
project k = tostring(EventData['@Name']), v = EventData['#text']
| project p = bag_pack(k, v)
| summarize edata_p = make_bag(p)
)
| evaluate bag_unpack(edata_p, columnsConflict="replace_source")
| where ObjectDN !endswith msa_dn
2. Target (Legacy) Account Not Disabled After dMSA Linking
During a legitimate migration, the legacy account is automatically disabled. Assuming the low-privileged user not having rights on the targeted account, we can flag dMSA linking without disabling the target account.
Leaving this query as an exercise for the reader
3. Suspicious msDS-DelegatedMSAState Values
Setting this attribute to 2 is essential for BadSuccessor but is not observed in legitimate migrations. We can flag this event. Keep in mind that future hotfixes/patches on Windows Server 2025 may result in this event being generated for legitimate dMSA migrations.
SecurityEvent
| where EventID == 5136
| where EventData has_all ("msDS-DelegatedManagedServiceAccount", "msDS-DelegatedMSAState")
| extend EventData = parse_xml(EventData)
| extend EventData = EventData.EventData.Data
| mv-apply EventData on (
project k = tostring(EventData['@Name']), v = EventData['#text']
| project p = bag_pack(k, v)
| summarize edata_p = make_bag(p)
)
| evaluate bag_unpack(edata_p, columnsConflict="replace_source")
| where AttributeValue == 2
4. Malformed dMSA Security Descriptor
Currently, BadSuccessor tools that are tested omit setting the msDS-GroupMSAMembership attribute, resulting in malformed descriptors. This is a strong indicator of tool-based exploitation. However, it can easily be fixed I think. Therefore, don't rely 100% on this detection.
SecurityEvent
| where EventID == 5136
| where EventData has_all ("msDS-DelegatedManagedServiceAccount", "msDS-GroupMSAMembership")
| extend EventData = parse_xml(EventData)
| extend EventData = EventData.EventData.Data
| mv-apply EventData on (
project k = tostring(EventData['@Name']), v = EventData['#text']
| project p = bag_pack(k, v)
| summarize edata_p = make_bag(p)
)
| evaluate bag_unpack(edata_p, columnsConflict="replace_source")
| where AttributeValue == "Malformed Security Descriptor"
Conclusion
The BadSuccessor is quite a dangerous attack and can't be detected without manual audit configurations. Once the correct auditing is configured, it becomes trivial to detect this threat. Keep in mind that obect-level auditing must be configured on the domain level (targeting all OUs) for full coverage.
Share this post
Latest from our blog

Copyright © 2025
Featured Links
Subscribe to our Newsletter!
Thank you!
New Challenge Lab
We're excited to launch our first hands-on lab challenge: Threat Hunting and Incident Response Case #001!
This lab simulates a real-world breach with two investigation paths:
This lab simulates a real-world breach with two investigation paths:
1️⃣ Incident Response: Triage an initial alert and unfold the attack.
2️⃣ Threat Hunting: Start with a TTP and hunt for adversary activity.