How to mitigate DnsAdmins privilege escalation ?12 May 2021
Glad to see you in this second part of this post. In our previous article we showed which rights were involved in the DnsAdmins privilege escalation. Now let’s talk about how to properly mitigate this.
First of all, a few words about the Security Descriptor Propagator (SDProp) ;
Within Active Directory, a default set of highly privileged accounts and groups are considered protected accounts and groups.
With protected accounts and groups, the objects' permissions are set and enforced via an automatic process that ensures the permissions on the objects remains consistent even if the objects are moved the directory. Even if somebody manually changes a protected object's permissions, this process ensures that permissions are returned to their defaults quickly.
Additionally, permissions inheritance is disabled on protected groups and accounts, which means that even if the accounts and groups are moved to different locations in the directory, they do not inherit permissions from their new parent objects.
Inheritance is disabled on the AdminSDHolder object so that permission changes to the parent objects do not change the permissions of AdminSDHolder.
This last sentence makes sense because the security descriptor used as a template to protect sensitive groups and users is stored in the
nTSecurityDescriptor attribute from the
AdminSDHolder object in Active Directory. The AdminSDHolder object is of class
container and has a DN of
CN=AdminSDHolder,CN=System,<Domain NC DN>.
Even if this is not a post about detailing the SDProp mechanism, why is this important ? Because this security mechanism called Security Descriptor Propagator (SDProp) aims at cutting any potential control paths to these Protected Users and Groups as they are highly privileged.
Unfortunately, DnsAdmins is not targeted by this security mechanism .
What is the algorithm to define which object deserves to be protected by the SDProp ? (taken from the ADTS - 22.214.171.124.1.2 Protected Objects) ;
d = domain; o = protected security principal object if ( (o!objectClass = group AND attribute o!groupType & GROUP_TYPE_SECURITY_ENABLED != 0) OR (o!objectClass = user) ) AND ( o!objectSid = d!objectSid + RID ) AND ( o is a member, directly or transitively, of any group in the set: built-in well-known group with RID = DOMAIN_ALIAS_RID_ADMINS built-in well-known group with RID = DOMAIN_ALIAS_RID_ACCOUNT_OPS built-in well-known group with RID = DOMAIN_ALIAS_RID_SYSTEM_OPS built-in well-known group with RID = DOMAIN_ALIAS_RID_PRINT_OPS built-in well-known group with RID = DOMAIN_ALIAS_RID_BACKUP_OPS built-in well-known group with RID = DOMAIN_ALIAS_RID_REPLICATOR account domain well-known group with RID = DOMAIN_GROUP_RID_ADMINS account domain well-known group with RID = DOMAIN_GROUP_RID_SCHEMA_ADMINS account domain well-known group with RID = DOMAIN_GROUP_RID_ENTERPRISE_ADMINS ) OR ( is one of the following well-known security principals: of class user with RID = DOMAIN_USER_RID_ADMIN of class user with RID = DOMAIN_USER_RID_KRBTGT of class group with RID = DOMAIN_GROUP_RID_CONTROLLERS of class group with RID = DOMAIN_GROUP_RID_READONLY_CONTROLLERS )
No mention to DnsAdmins here, even if we know that being member of DnsAdmins compromised domain.
At least we can manually set ACEs as restricted as the AdminSDHolder ones thanks to the cmdlet
Set-ADSyncRestrictedPermissions from the
AdSyncConfig.psm1 module. This is part of the recommendations shared by this Active Directory guide.
The AzureADConnect.msi package can be downloaded from https://go.microsoft.com/fwlink/?LinkId=615771.
The AdSyncConfig.psm1 module may be extracted from the Azure AD Connect installer with msiexec:
msiexec /a "AzureADConnect.msi" /qb TARGETDIR=c:\temp\
Keep the DnsAdmins group empty, prefer a delegation group to manage your DNS service and to allow DNS zone updates. This is done thanks to the two following steps ;
- STEP 1: ALLOW ACCESS TO RPC USED BY DNS MANAGEMENT MMC SNAP-INS
In the domain naming context, under the
CN=System container, set the following access rights on the
CN=MicrosoftDNS container for your trustee delegation group ;
- STEP 2: ALLOW DNS ZONE MODIFICATIONS
DC=DomainDnsZones naming context, on every zone you wish to delegate management, enable inheritance and set the following access rights on the
CN=MicrosoftDNS container for your trustee delegation group ;
DnsAdmins security descriptor
This is an overview of the DnsAdmins security descriptor ;
The group should be changed, DnsAdmins should be owned by Domain Admins ;
Set rights at least as strict as the AdminSDHolder ones ;
Import-Module "C:\Program Files\Microsoft Azure Active Directory Connect\AdSyncConfig\AdSyncConfig.psm1" $credential = Get-Credential Set-ADSyncRestrictedPermissions -ADConnectorAccountDN "CN=DnsAdmins,CN=Users,DC=phackt,DC=local" -Credential $credential
You can check that the DnsAdmins security descriptor is blocking inheritable ACEs ;
Get-ADSyncObjectsWithInheritanceDisabled -SearchBase "CN=DnsAdmins,CN=Users,DC=phackt,DC=local" -ObjectClass '*' DistinguishedName : CN=DnsAdmins,CN=Users,DC=phackt,DC=local Name : DnsAdmins ObjectClass : group ObjectGUID : 54d747e8-f9c2-461b-b8f2-5cc0b99249cc ObjectSID : S-1-5-21-3816950244-2414788102-2833019223-1101 sAMAccountName : DnsAdmins
You should get a security descriptor which should look like this ;
DACL_PROTECTED parameter shows that the descriptor is blocking inheritable ACEs
As you see it is a way more restrictive than the original AdminSDHolder security descriptor shown below ;
Also you can set, on the DnsAdmins group, a
Deny ACE forbidding
Everyone for the
WRITE_OWNER right (remember that being owner of an object provides the
READ_CONTROL over the object).
However if you do this remember that replaying the
Set-ADSyncRestrictedPermissions cmdlet will reset the DACL and delete this ACE (on the other hand you could update the AdSyncConfig.psm1 module to match your needs).
MicrosoftDNS security descriptor
As seen previously, deleting the DnsAdmins
RIGHT_DS_WRITE_PROPERTY_EXTENDED right for the MicrosoftDNS container will prevent an attacker from writing the registry key to set the path of an arbitrary DLL to be loaded by the DNS service.
However i don’t know what is the impact if you benefits from the Microsoft support and if they need to exceptionally perform a maintenance operation, from DnsAdmins, which needs this right (nevertheless i never faced this situation).
Firstly i thought it was possible to add a new security group to be targeted by the SDProp mechanism but no, it’s not (and as i was said, it’s not for tomorrow). At least we can manually set some restricted rights on it. Also i’m having a look at creating a routine which will frequently override the DnsAdmins
ntSecurityDescriptor based on the AdminSDHolder one to simulate the SDProp mechanism for custom groups.
DnsAdmins is one of the so many ways an attacker can gain control of your Active Directory. If you are looking for a complete Active Directory security assessment checklist : https://www.cert.ssi.gouv.fr/uploads/guide-ad.html.
[UPDATE 2021/12/06]: According to this article, it seems that the issue has been finally fixed by Microsoft.
Thanks folks for reading,