Kerberos Constrained Delegation Exploitation
Kerberos Constrained Delegation (KCD) is one of the most powerful and frequently abused features in Microsoft Active Directory environments. When an administrator configures a service account or computer object to be trusted for delegation to specific services, an attacker who compromises that account can potentially impersonate any domain user — including Domain Admins — to those delegated services. This capability, known as Protocol Transition (S4U2Self + S4U2Proxy), has been exploited in real-world breaches, red-team operations, and CTF challenges alike.
Table of Contents
- Introduction
• Kerberos Delegation Overview
• S4U2Self & S4U2Proxy
• AD Attributes & Configuration
• Lab Setup
• Enumeration (NetExec)
• Exploitation (Impacket)
• Post-Exploitation
• Detection
• Mitigations
• Conclusion
This article provides a complete, step-by-step technical walkthrough of a Kerberos Constrained Delegation attack against an Active Directory lab. We cover the underlying theory, the misconfiguration setup, enumeration from an attacker machine, exploitation using Impacket, and the final objective — gaining SYSTEM-level access to a SQL Server host while fully impersonating a Administrator.
What Is Kerberos Delegation?
Kerberos delegation allows a service to act on behalf of a user when accessing a downstream resource. The classic use case is a web application (Service A) that needs to access a backend database (Service B) using the identity of the end user.
There are three types of Kerberos delegation in Active Directory:
S4U2Self and S4U2Proxy Extensions
Kerberos Constrained Delegation with Protocol Transition relies on two Kerberos extensions defined in Microsoft’s implementation:
- S4U2Self (Service-for-User-to-Self): Allows a service to obtain a Kerberos Service Ticket to itself on behalf of any user — even if that user never authenticated with Kerberos. This is the ‘protocol transition’ — it bridges non-Kerberos authentication (e.g., NTLM, form-based) into Kerberos.
- S4U2Proxy (Service-for-User-to-Proxy): Takes the forwardable ticket obtained via S4U2Self and exchanges it for a ticket to a different target service, effectively completing the delegation chain.
The combination of both extensions allows an attacker who controls an account configured for Constrained Delegation with Protocol Transition to generate service tickets impersonating any user (including Domain Admin) to the allowed target service — completely bypassing that user’s password.
The Active Directory Attribute
Constrained Delegation is configured through the attribute msDS-AllowedToDelegateTo on the account object in Active Directory. When Use any authentication protocol is selected (Protocol Transition), the AD flag TRUSTED_TO_AUTH_FOR_DELEGATION (T2A4D) is set in the userAccountControl attribute. This flag is the key indicator during enumeration
Lab Setup — Creating the Misconfiguration
Create a Domain User Account
On the Domain Controller, a new domain user named kavish is created using the net user command. This account will represent a service account used by a web application.
net user kavish Password@1 /add /domain
Register a Service Principal Name (SPN)
An SPN is a unique identifier for a service instance in Active Directory. For Kerberos delegation to function, the service account must have an SPN registered. This also makes the account a valid Kerberos service target.
setspn -A HTTP/msedgewin10.ignite.local
The SPN HTTP/msedgewin10.ignite.local is registered against the kavish account in the ignite domain. This simulates a scenario where kavish is the service account for an IIS web application hosted on MSEDGEWIN10.
Configure Constrained Delegation with Protocol Transition
Using Active Directory Users and Computers (ADUC), the administrator opens the properties of the kavish user account, navigates to the Delegation tab, and applies the following settings:
- Trust this user for delegation to specified services only — limits delegation scope
- Use any authentication protocol — enables Protocol Transition (S4U2Self)
- Add MSSQLSvc/WIN-SQL.ignite.local:1433 as the allowed service — the SQL Server on WIN-SQL
This configuration means: the kavish account can impersonate any domain user (including administrators) to the MSSQLSvc service on WIN-SQL.ignite.local:1433. This is a classic over-permissioned delegation scenario.
- Open Active Directory → Press Enter
- Find the kavish user → Press Enter
- Right-click the user → Press Enter
- Click “Properties” → Press Enter
- Make changes in tabs → Press Enter
- Click “OK” → Press Enter
- Go to Delegation tab
- Select “Trust this user for delegation to specified services only”
- Select “Use any authentication protocol”
- Click Add…
- Select service/user and click OK
- Click Users or Computers…
- Type the user/computer name
- Click Check Names
- Select the required service(s)
- Click inside Enter the object name field
- Type the computer/username (e.g., WIN-SQL)
- Click Check Names
- Verify the name gets underlined (validated)
- Click OK
Select the required service (e.g., MSSQLSvc – WIN-SQL – 1433) Click OK
Configure /etc/hosts on Kali
Before executing any attacks, the attacker (on Kali Linux) ensures that all domain hostnames are resolved correctly by adding entries to /etc/hosts. This is necessary because the Kali machine may not be using the DNS server.
Find Delegation Misconfigurations with NetExec
Using NetExec (nxc) with the –find-delegation flag, the attacker queries the Domain Controller over LDAP using the compromised kavish credentials to enumerate all delegation configurations in the domain.
nxc ldap 192.168.1.11 -u kavish -p Password@1 --find-delegation
The output confirms the misconfiguration: kavish has Constrained delegation with Protocol Transition to the MSSQLSvc service on WIN-SQL.ignite.local:1433. This is exactly what is needed to perform the S4U2Self + S4U2Proxy attack.
Exploitation
Obtain a Service Ticket Impersonating Administrator
Using Impacket’s getST.py, the attacker performs the full S4U2Self + S4U2Proxy chain in a single command. This requests a Service Ticket (ST) for the MSSQLSvc/WIN-SQL.ignite.local:1433 service but impersonating the Administrator account — all using only the kavish account credentials.
impacket-getST ignite.local/'kavish':Password@1 -spn MSSQLSvc/WIN-SQL.ignite.local:1433 -impersonate administrator -dc-ip 192.168.1.11
The attack succeeds. The ticket is saved as a .ccache file — a Kerberos credential cache file. This ticket grants access to the SQL Server as the Administrator.
Load the Kerberos Ticket into the Environment
Before using the ticket, the attacker exports the KRB5CCNAME environment variable to point to the saved ccache file. This tells Kerberos-aware tools (like Impacket) to use this ticket for authentication.
export KRB5CCNAME=administrator@MSSQLSvc_WIN-SQL.ignite.local:1433@IGNITE.LOCAL.ccache
Connect to SQL Server as Administrator
With the ticket in the environment, the attacker uses impacket-mssqlclient with the -k (Kerberos) flag to authenticate to the SQL Server on WIN-SQL. No password is supplied — the Kerberos ticket handles authentication.
impacket-mssqlclient win-sql.ignite.local -k
Success! The attacker is now connected to the SQL Server as Administrator — without ever knowing or cracking their password. The SQL Server fully trusted the Kerberos ticket.
Dump Local SAM Hashes with secretsdump
With the Kerberos ticket still loaded in the environment, the attacker uses impacket-secretsdump to remotely extract credential material from WIN-SQL. The -k and -no-pass flags instruct Impacket to use the cached Kerberos ticket rather than a password.
impacket-secretsdump -k -no-pass win-sql.ignite.local
The NT hash for the local Administrator account on WIN-SQL is extracted. This hash can be used in Pass-the-Hash attacks or cracked offline. Additionally, cached domain credentials and LSA secrets are also retrieved, potentially exposing other account credentials.
Gain Interactive Shell via PsExec
As a final demonstration of full system compromise, the attacker uses impacket-psexec with Kerberos authentication to obtain an interactive SYSTEM-level shell on WIN-SQL.ignite.local.
impacket-psexec administrator@win-sql.ignite.local -k -no-pass -dc-ip 192.168.1.11
The attacker now has an interactive SYSTEM shell on WIN-SQL — the highest privilege level on a Windows machine. From here, every file, process, and service on the target host is accessible. Combined with the credential dump from Step 6.1, the attacker can proceed to laterally move across the entire ignite.local domain.
Active Directory Enumeration Detection
- Monitor for LDAP queries with filters containing msDS-AllowedToDelegateTo or userAccountControl attribute reads from non-administrative workstations.
- Alert on large-volume LDAP queries from unexpected source IPs — tools like BloodHound and NetExec generate characteristic query patterns.
- Windows Event ID 4662 — Object Access — captures LDAP queries against sensitive attributes when auditing is enabled.
S4U2Self / S4U2Proxy Detection
- Windows Event ID 4769 (Kerberos Service Ticket Operations) — look for TGS requests where the ticket options include ‘forwardable’ and the requesting account does not match the ticket subject.
- An S4U2Self request is characterized by a TGS-REQ where the PA-FOR-USER pre-authentication data is present. This can be detected via network-level Kerberos monitoring (e.g., Zeek with Kerberos analyzers).
- Alert on service ticket requests for high-value accounts (Administrator, krbtgt) originating from service accounts.
Lateral Movement & Credential Dumping
- Windows Event ID 7045 — A new service was installed — detects PsExec’s service creation pattern. Alert on short-lived randomly named services.
- Windows Event ID 4624 (Logon) with Logon Type 3 (Network) combined with Event ID 4672 (Special Privileges) indicates privileged remote logon.
- Monitor for RemoteRegistry service being started unexpectedly — a key indicator of secretsdump activity.
- Sysmon Event ID 10 (Process Access) with TargetImage lsass.exe indicates credential dumping attempts.
Defensive Mitigations
The following controls significantly reduce the risk of Constrained Delegation abuse:
Prefer ‘Use Kerberos Only’ Over Protocol Transition
When Constrained Delegation is required, always prefer ‘Use Kerberos only’ over ‘Use any authentication protocol’. The ‘any protocol’ option grants the dangerous S4U2Self capability. Kerberos-only delegation requires the user to present a forwardable Kerberos ticket, which means the attacker must already have that user’s ticket — a much higher bar.
Mark Sensitive Accounts as ‘Account is Sensitive and Cannot Be Delegated’
For high-privileged accounts (Domain Admins, Enterprise Admins, service accounts with administrative rights), enable the Account is sensitive and cannot be delegated flag in ADUC. This prevents their tickets from being delegated even if the delegating account is configured with Protocol Transition. This is one of the most effective mitigations.
Add Privileged Accounts to the ‘Protected Users’ Group
Members of the Protected Users security group receive enhanced Kerberos protections, including a prohibition on their tickets being delegated. This provides defense in depth alongside the ‘sensitive account’ flag.
Prefer Resource-Based Constrained Delegation (RBCD)
Where possible, prefer Resource-Based Constrained Delegation over classic KCD. RBCD places the delegation configuration on the target resource (controlled by the resource owner) rather than on the source service account, providing more granular and manageable access control.
Least-Privilege Service Accounts
Avoid granting domain user accounts or service accounts more privileges than strictly necessary. Use Group Managed Service Accounts (gMSA) instead of standard user accounts for services — gMSA passwords are automatically rotated and are much harder to compromise.
Regular Delegation Audits
Periodically audit Active Directory for accounts with delegation configured using PowerShell or tools like BloodHound. Remove delegation from accounts that no longer require it.
PowerShell: Find all accounts with Constrained Delegation configured
Get-ADObject -Filter {msDS-AllowedToDelegateTo -ne “$null”} -Properties msDS-AllowedToDelegateTo,userAccountControl | Select-Object Name,userAccountControl,msDS-AllowedToDelegateTo
# Find accounts with Protocol Transition enabled (T2A4D flag = 0x1000000)
Get-ADUser -Filter {TrustedToAuthForDelegation -eq $true} -Properties TrustedToAuthForDelegation,msDS-AllowedToDelegateTo
Conclusion
Kerberos Constrained Delegation with Protocol Transition is a powerful Active Directory feature that, when misconfigured, creates a critical privilege escalation path. This walkthrough demonstrated how an attacker who gains credentials to a single low-privilege service account — kavish — could completely compromise a remote SQL Server host and extract all credential material, effectively owning the machine without ever cracking a single administrative password.
The attack chain requires only two things: knowledge of the target SPN and credentials for the delegation-enabled account. Tools like Impacket make the S4U2Self + S4U2Proxy chain trivially easy to execute once enumeration reveals the misconfiguration.
Defenders must treat Kerberos’ delegation as a highly sensitive configuration. The combination of regular auditing, adding privileged accounts to the Protected Users group, and avoiding Protocol Transition in favor of Kerberos-only delegation dramatically reduces the attack surface. Detection engineering focused on anomalous TGS requests and remote service creation can catch these attacks in progress.
Author: Sanjeet Kumar is an Information Security Analyst | Pentester | Researcher Contact Here