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!
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
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.
Powerview: Get-NetComputer -Unconstrained | select dnshostname
Domain controller is always configured unconstrained delegation, but it does not help.
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!
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.
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.
Powerview: Get-NetComputer -TrustedToAuth
(Service Account) Get-NetUser -TrustedToAuth
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
If owned user or machines have GenetricWrite (Or higher permission) permission over another machine.
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
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.
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.
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.
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!