In this blogpost I demonstrate how an attacker could attack gMSAs that are configured with unconstrained delegation.
During the past weeks we have seen many attacks that focus on dGMSA. This is only an option to attack if you have at least a DC, that is running with 2025 OS.
In many environments there are still users or computers configured with unconstrained delegation. I have seen many blogposts describing how to evelate privileges if a computer or useraccount is configured with unconstrained delegation.
In this blogpost I want to describe how to exploit gMSA Accounts that are configured with unconstrained delegation to get elevated privileges.
tl;dr:
- Enumerate all gMSA for unconstrained delegation
- Check on which server they are installed
- Get gMSA Credentials via computeraccount
- Write DNSHostName
- Write SPNs with gMSA on the gMSA itself
- Write DNS Records
- Coercing
- Profit
This blogpost describes an attack on gMSA configured with unconstrained delegation.
gMSA unconstrained Delegation is an often overlooked attack path to compromise the complete domain.
You can enumerate all the Objects that have unconstrained delegation with the following LDAP Query:
"(userAccountControl:1.2.840.113556.1.4.803:=524288)"
Note: This ldap query lists all objects (active and inactive). You should try to clear that list, so that only domain controllers are part of that list. Every system in that list can be exploited to compromise the domain if the network conditions are met and no special hardening is in place.
This query also lists the inactive objects. They are also a danger for you.
–> You need domain admin / enterprise admins or the SE_ENABLE_DELEGATION right to enable unconstrained delegation, but you only need control over the account to make them active again and reset the passwords.
It was often described in various blogpost how to exploit unconstrained delegation on normal user accounts and computeraccounts, this is why I skip that section.
In Powershell with RSAT Tools installed, you can execute the following command to get all gMSA Accounts, that have unconstrained delegation enabled:
Get-ADServiceAccount -Ldapfilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)"
Once you have the identity of that gMSA, you can query them for more information, like which SPNs they are using and who has the ability to retrieve the password of the gMSA.
This can be done with the following command:
Get-ADServiceAccount -Identity webapppoolsrv03$ -Properties ServicePrincipalNames, PrincipalsAllowedToRetrieveManagedPassword
Once we have that information, we already have a good plan which systems need to be compromised in order to get to the password of the gMSA.
The PrincipalsAllowedToRetrieveManagedPassword we see in Powershell manages who can retrieve the Password of the gMSA.
If we have access to the credentials of one object that is part of that attribute, we can move on.
If we do not have access to any of the objects that can retrieve the passwords, we can do try the following ways.
We can check the security descriptor of the gMSA Object who else has permission on the object, for example with Write All Properties or Full Control.
If we have access to one of the users we can give us the permission to retrieve the password of the gMSA.
Depending on the configuration, the server or client, who is running the gMSA has access to retrieve the password.
We can exploit this permission also with NTLM attacks.
One out of two conditions must be met at the computer object that has access in order to be successfull:
This works only if no LDAP Channel Binding / Signing is in use.
We can coerce the computer object to us and relay it to LDAPS in order to dump the gMSA credentials.
This functionality can be exploited with ntlmrelayx.
If you run under a context that is allowed to retrieve the managed password you can read the msDS-ManagedPassword attribute.
The gMSADumper.py script comes in handy for the decoding:
In order to be successfull with kerberos we need to have a few requirements like at the user unconstrained delegation exploitation.
Short Recap: At user unconstrained delegation we need write access to the user in order to write an attacker controlled SPN or an non-existing SPN entry, that is not registered at the DNS.
But what if we have no attacker controlled account that has write access over the gMSA?
We have to find another way.
With that options in mind. We now can as the gMSA write our own SPN, that is our SAMAccountName or does fit with our DNS Host Name.
In many cases we can see that we can use the already configured DNS hostname, because it has no corresponding DNS entry.
In cases where the DNS Host entry ends with $ or is already existing, we can change the DNS Host Name and then add the SPN and then change the DNS Hostname back to the orginal value.
setspn -S HOST/mygmsa.testert01lab.local mygmsa$
With the added SPN we can now register an A DNS Record and point it to our attacker controlled machine.
Set up krbrelayx on a linux host and let it run under the gMSA with unconstrained delegation. We need to use the AES Keys, which we get from the gMSADumper Tool.
Afterwards we can then coerce a domain controller to a DNS entry, that is backed up by the SPN of the gMSA. We need to use the FQDN that kerberos works correctly at the coercing.
Warning: If you have still NTLMv1 outgoing active or a webclient running on a computer object that can access the Managed Password for a gMSA that has unconstrained delegation, this means an attacker can effectivly escalate its privileges from a normal domain user to a complete domain compromise.
Just for authorized use only.
For user unconstrained delegation you need to have control over a account that can write a SPN for your user or you need a non existing SPN already configured for the user.
For gMSA the gMSA itself has validated write permissions to the SPN and DNS HostName, meaning, he can add itself to the SPN list.
Dirk-jan Mollema Blogpost for unconstrained delegation at user and computeraccounts