Kerberos Delegation and Usage
Kerberos delegation has been around for a long time (Windows Server 2000 to be exact), but more often than not, when speaking to engineers who manage or work with Active Directory, they’re not familiar with all the various implementations of Kerberos delegation, their uses, and some ways they can be abused. What I find funny, is that most people confuse Kerberos delegation with delegated permissions.
The practical usage of Kerberos delegation is to enable an application to access resources hosted on a different server. One example is when a web server needs to access resources for the website hosted somewhere else, such as a SQL database. Instead of giving the service account running the web server access to the database directly, you can allow the web server service account to be delegated to the SQL server service. Once a user logs into the website, the web server service account will request access to the SQL server service on behalf of that user. This allows the user to get access to the content in the database that they’ve been provisioned to, without having to provision any access to the web server service account itself.
Types of Kerberos Delegation
There are a few flavors of Kerberos delegation since it has evolved over the years. The original implementation is unconstrained delegation, this was what existed in Windows Server 2000. Since then, more strict versions of delegation have come along. Constrained delegation, which was available in Windows Server 2003, and Resource-Based Constrained delegation which was made available in 2016, both have improved the security and implementation of Kerberos delegation. I’ll dive deeper into each type of delegation, and it’s usage below.
You can configure delegation on a computer or user account within Active Directory, but user accounts must have a servicePrincipalName (SPN) set. Below is a screenshot showing the Delegation tab in Active Directory Users and Computers, and an explanation of some of the options on that page.
In yellow, the first option allows you to configure an account so that it is NOT allowed to be trusted for delegation. This is most commonly used on sensitive or administrative accounts that should never be used for delegation. The second option, in green, allows you to configure an account for unconstrained delegation. The third option, in red, allows you to configure an account for constrained delegation.
This is the original implementation of delegation, and also the least secure. What does unconstrained delegation actually do? Under the covers, when unconstrained delegation is configured, the userAccountControl attribute of the object gets updated to include the “TRUSTED_FOR_DELEGATION” flag. When an object authenticates to a host with unconstrained delegation configured, the ticket-granting ticket (TGT) for that account gets stored in memory. This is so the host with unconstrained delegation configured can impersonate as that user later on if needed.
So imagine a scenario where a privileged account authenticates to a host with unconstrained delegation configured, you now can access any configured service within the domain as that privileged user. Jeff Warren does a great write-up of a similar attack here. To take it a step further, what if there were ways to force privileged accounts to authenticate to your host automatically? Using the ‘printer bug’ you can get a domain controller to authenticate to your host, leaving the TGT for that account in memory. Since mechanisms like the ‘printer bug’ exist, unconstrained delegation is very insecure and should not be leveraged, if at all possible. One thing to note is that Domain Controllers, by default, are configured with unconstrained delegation. This is required, and since your Domain Controllers should be much more secure than a random application server hosting a service, it should not be a problem.
Introduced in Windows Server 2003, constrained delegation takes it a step further by allowing you to configure which services an account can be delegated to. This, in theory, would limit the potential exposure if a compromise occurred.
One restriction to note for constrained delegation, is that it does not work cross forest. When constrained delegation is set on an account, two things happen under the covers:
- The userAccountControl attribute for the object gets updated with the “TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION” flag
- The msDS-AllowedToDelegateTo attribute gets populated with the SPN configured on the delegation tab
Abusing constrained delegation is different than abusing unconstrained delegation. One common way it can be abused is if you’re able to compromise the plaintext password or NTLM hash of a user account configured for constrained delegation. Using a tool like Kekeo, you’re able to request a TGT for the account you have the password for, execute the TGS request for any user (as long as they’re not marked ‘Sensitive’), and then inject the ticket and access the service you requested as that user. This type of abuse will be covered in a future blog.
Resource-Based Constrained Delegation
Introduced in Windows Server 2012, Resource-Based Constrained Delegation changes how you can configure constrained delegation, and it will work across a trust. Instead of specifying which object can delegate to which service, the resource hosting the service specifies which objects can delegate to it. From an administrative standpoint, this allows the resource owner to control who can access it. For example, instead of specifying with constrained delegation that the WebServer service account can delegate to the SQL Service to access the database, you can specify on the SQL server service account that the WebServer service account has permissions to delegate access to it.
Resource-based Constrained Delegation is configured by populating the msDS-AllowedToActOnBehalfOfOtherIdentity attribute on the target resource, with the SID of the object that is allowed to delegate to it. To configure Resource-based Constrained Delegation, you actually need to leverage PowerShell, there is no GUI component within Active Directory Users and Computers and the Attribute Editor page does not allow for manual modification of this attribute. You can read more about Resource-Based Constrained Delegation and ways to abuse it in my other blog here.
Identifying Existing Kerberos Delegation
Now that you understand some of the basics for the different types of delegation and some ways they can be abused, I want to share with you a method you can use to wrap your head around what types of delegation may already be configured within your environment. Specifically looking to highlight insecure scenarios, such as unconstrained delegation being configured on objects other than Domain Controllers. Microsoft actually offers a script to assist with this via their technet gallery. The script will identify accounts with unconstrained, constrained, and resource-based constrained delegation configured. It will also highlight information and potential warnings about the configurations it identifies.
Hopefully, I’ve been able to clear up any confusion around what Kerberos delegation is and how it works. In the future, I’ll be writing a blog on how to abuse constrained delegation. For now, check out some of our other STEALTHbits blogs on Kerberos delegation:
- Resource-based Constrained Delegation Abuse
- Unconstrained Delegation Exploit
- Unconstrained Delegation Permissions
Kevin Joyce is a Senior Technical Product Manager at Stealthbits Technologies. He is responsible for building and delivering on the roadmap of Stealthbits products and solutions.
Kevin is passionate about cyber-security and holds a Bachelor of Science degree in Digital Forensics from Bloomsburg University of Pennsylvania.