Eliran Partush
Security Researcher, Silverfort
Kerberos Constrained Delegation is the impersonation mechanism of Kerberos, used when a service or application needs to act on behalf of a user.
In July 2025, I found interesting issues in the way Windows enforces integrity checks within the impersonation subprotocol.
Specifically, a legacy RSA-MD4 support combined with a missing cryptography validation step in the client-side of one of these integrity checks allowed the ability to manipulate fields that are intended to be protected. This includes the identity of the user being impersonated.
Under the right conditions, this behavior can be abused to bypass delegation trust assumptions, leading to unauthorized access and privilege escalation.
Kerberos and Delegation: Background
Kerberos is a network authentication protocol built around strong cryptographic primitives. Its primary goal is to provide mutual authentication, allowing both the user and the application to verify each other’s identity.
Impersonation has existed in Kerberos for a long time. The original MIT Kerberos specification introduced a delegation mechanism in RFC 4120 (2005) – which, in practice, was essentially pass-the-ticket as a feature.
Microsoft chose to implement delegation differently. With the introduction of Service-for-User (S4U) in Windows Server 2008, and later enhancements in Windows Server 2012, Microsoft added its own protocol extensions, including two distinct forms of Constrained Delegation.
Kerberos and Kerberos delegation have been extensively covered in blogs and research. Several of those works served as both inspiration and foundational references for this research:
- Wagging the Dog – Elad Shamir
- RC4 Is Still Considered Harmful – Project Zero (James Forshaw)
- S4U2Pwnage – harmj0y
In this article, I’ll intentionally skip a general Kerberos introduction and focus instead on Microsoft’s implementation of the delegation extensions.
Before diving into the vulnerability itself, we first need to understand how these features are supposed to work.
Kerberos Delegation
Delegation is the mechanism that allows a service to access resources on behalf of a user. In Active Directory, delegation is how multi-tier applications preserve authorization context without copying credentials or implementing application-level impersonation.
The basic idea is simple: A user authenticates to Service 1 (the frontend), and that service needs to access Service 2 (the backend) as the user.
What happens with “classic” Kerberos?
In a standard Kerberos flow:
- The user authenticates to the frontend and presents a service ticket.
- The frontend cannot reuse that ticket to authenticate to the backend because:
- Tickets are not forwardable by default.
- The ticket is encrypted with the frontend’s long-term key, so only the frontend can decrypt it.
An alternative would be for the frontend to request its own service ticket to the backend. However, this introduces new problems:
- The authorization context is no longer the user’s – it’s the service account’s.
- From a security perspective, this means the backend must fully trust the frontend.
- Granting a service unrestricted access to a backend resource is usually unacceptable.
- Applications should not have blanket access just to “make things work.”
Example: CA Web Enrollment
Take the CA Web Application as an example: https://learn.microsoft.com/en-us/troubleshoot/windows-server/active-directory/configure-kerberos-constrained-delegation.
First, the user authenticates to IIS hosting the Certificate Services web interface. IIS is responsible for issuing a certificate to the user by communicating with the CA backend over RPC.
At this point:
- IIS holds the user’s service ticket.
- IIS now needs to authenticate to RPCSS on the CA as the user.
But the user’s ticket cannot simply be forwarded:
- It’s encrypted with IIS’s long-term key.
- The CA needs a ticket encrypted with its own key to decrypt it and authenticate the user.
If IIS instead authenticates using its own service ticket:
- The certificate issued will belong to the service account, not the user.
- Alternatively, the application could implement its own impersonation logic, allowing IIS to decide which certificate to issue.
- This pushes sensitive authorization decisions into application logic.
- Applications should not be trusted with these kinds of privileges.
The solution for this problem is Kerberos delegation: a controlled form of impersonation where Service 1 (the frontend) is explicitly trusted to act on behalf of users when accessing Service 2 (the backend).
Kerberos Delegation types: Unconstrained / Constrained
There are two main families of Kerberos delegation: Unconstrained Delegation and Constrained Delegation. While both aim to solve the same core problem – allowing a service to act on behalf of a user – they do so in different ways with different security implications.
Unconstrained Delegation
Unconstrained delegation relies on the ok-to-delegate flag and allows a service to receive and reuse the user’s forwarded TGT. In other words, once a service is trusted for unconstrained delegation, it effectively holds the user’s TGT and can impersonate the user to any service in the domain. This makes unconstrained delegation powerful – but also dangerous if that service is compromised.
Constrained Delegation (KCD)
Constrained delegation takes a more controlled approach. Instead of handing over the user’s TGT, the frontend service is trusted to impersonate users only to specific backend services by using a forwardable Service Ticket.
Resource-based Constrained Delegation (RBCD)
RBCD is the latest evolution of KCD where the target resource controls which services may delegate to it, rather than configuring delegation permissions on the front-end service account.
KCD and RBCD significantly reduce the attack surface compared to unconstrained delegation – at least in theory.
For more details, follow this link: https://www.silverfort.com/glossary/kerberos-delegation/.
KCD and RBCD are both Microsoft implementations of the Kerberos protocol extension MS-SFU.
Microsoft Service-For-User Protocol Extension
Microsoft’s Service-for-User (S4U) protocol extensions define two related mechanisms: protocol transition and constrained delegation. In this model, a service uses its own TGT to request special Kerberos tickets that embed a user principal, while the KDC remains responsible for enforcing delegation policy based on Active Directory configuration.
The S4U extensions introduce two TGS subprotocols:
S4U2Self (Service-for-User-to-Self)
S4U2Self is a TGS-REQ subprotocol used for protocol transition. It was designed to address scenarios where the end user does not authenticate to an application using Kerberos, but the application still needs to obtain Kerberos tickets that represent the user’s identity.
S4U2Proxy (Service-for-User-to-Proxy)
S4U2Proxy is a TGS-REQ subprotocol used to perform constrained delegation. Its purpose is to obtain a forwardable service ticket to a downstream service on behalf of a user, using previously established authentication evidence.
These two subprotocols act as independent mechanisms and can be used separately. In practice, however, they are often linked together, with S4U2Self producing an evidence ticket that is subsequently consumed by S4U2Proxy to complete delegated access.
S4U2Proxy – Constrained Delegation
S4U2Proxy TGS-REQ is the actual constrained delegation message. The service requests a ticket to a downstream target SPN on behalf of that user and supplies the user’s ticket as evidence. The KDC enforces delegation policy (KCD or RBCD) and, if permitted, issues a downstream ticket whose client identity is derived from the evidence ticket.
Unlike a normal TGS request, S4U2Proxy must provide evidence that the user has already been authenticated. This evidence can be obtained in one of two ways:
- From a service ticket originally presented by the user (when Kerberos authentication was used), or
- From a service ticket obtained via S4U2Self.
S4U2Proxy is implemented as a modified TGS-REQ and TGS-REP and introduces changes in the KDC options, PA-DATA, PAC and additional-tickets.
S4U2Proxy TGS-REQ key parameters
- The KDC option constrained-delegation (also known as cname-in-addl-tkt) must be set.
- This flag instructs the KDC to extract the client principal identifier (cname) from the additional ticket, rather than from the authenticator, as in a normal TGS-REQ.
- One or more additional tickets must be included.
- This ticket represents the authenticated user.
- (Optional) The client may include PA-PAC-OPTIONS to request:
- Resource-Based Constrained Delegation (RBCD)
- Claims-based authorization
At this stage, the KDC validates both the delegation permissions of the requesting service and the integrity of the evidence ticket.
Example: S4U2Proxy TGS-REQ
S4U2Proxy TGS-REP
The resulting TGS-REP looks like a service ticket requested directly by the user. However, additional authorization metadata is injected into the PAC.
Specifically, the KDC adds an S4U_DELEGATION_INFO structure containing two critical fields:
- S4U2proxyTarget – the SPN of the target service
- S4UTransitedServices – the account that impersonated the user
This information is intended to be validated by the application receiving the ticket, allowing it to understand who is being impersonated and which service performed the delegation.
Example: S4U2Proxy TGS-REP
As mentioned earlier, if the user authenticated the application using a non-Kerberos protocol, the evidence ticket should be requested using the S4U2Self protocol
S4U2Self – Protocol Transition
S4U2Self is a TGS-REQ subprotocol used for protocol transition. It was designed to address cases where the end user did not authenticate to the application using Kerberos, but the application still needs to obtain Kerberos service tickets to downstream resources in the user’s security context.
In practical terms, once a service account is configured with the TRUSTED_TO_AUTH_FOR_DELEGATION userAccountControl flag, the domain explicitly trusts that service to authenticate users on its behalf, instead of relying on the Domain Controller to perform the initial authentication.
This trust allows the service to request an S4U2Self service ticket that represents the user’s identity, even though no Kerberos authentication took place between the user and the service.
S4U2Self TGS-REQ key parameters
An S4U2Self request differs from a normal TGS request in a few important ways:
- The sname field is set to self (for example: machineaccount1$).
- The TGT and authenticator cname identities also represent the trusted account.
At this point, the service must still specify which user it intends to impersonate. Since no Kerberos authentication occurred between the user and the service, the user identity cannot be derived from the ticket itself.
This is done using one of two Pre-Authentication Data (PA-DATA) structures:
- PA-FOR-USER – username-based identification
- PA-FOR-X509-USER – certificate-based identification
Example: S4U2Self TGS-REQ
In the following section, we’ll understand the difference between those data structures and discover the weakness.
PA-DATA TYPE 129: PA-FOR-USER – Username-based identification
This is the simple and more commonly used PA-DATA structure.
All fields are mandatory:
- userName.type – defaults to 0 (NT-UNKNOWN)
- userName.name-string – username or UPN
- userRealm – the user’s realm
- auth-package – the string “Kerberos”
The Checksum (cksum) is computed over all of the above fields in the following way:
S4UByteArray =
(LE 4-Byte int) userName.type +
userName string +
userRealm string +
“Kerberos” An HMAC-MD5 checksum is then calculated using:
- The TGT session key
- Key usage number 17 (KERB_NON_KERB_CKSUM_SALT)
- The S4UByteArray
cksum = HMAC-MD5(SessionKey, 17, S4UByteArray) This design ensures that an attacker must know the TGT session key to modify any field in the structure.
And if an attacker already has the session key, well, you have a different problem:
PA-DATA TYPE 130: PA-FOR-X509-USER – Certificate-based identification
This data structure is more complex and significantly more interesting from a security perspective.
It consists of two main components:
- User-id (S4UUserID), which carries the user identity information
- Checksum, which is intended to provide integrity protection
User-id (S4UUserID)
The S4UUserID structure contains the identity information that the KDC will ultimately trust.
Mandatory fields:
- nonce: Copied from the KDC request body
- crealm: The user’s realm
Optional fields:
cname : If omitted, a certificate must be provided. If cname is not present, the KDC extracts the user identity from the certificate extensions.
subject-certificate: DER-encoded public key X509 certificate
options: Additional flags:
Checksum
The checksum is computed over the DER-encoded user-id (S4UUserID) structure.
Unlike PA DATA 129, where the checksum is always HMAC-MD5 keyed with the TGT’s session key, here the checksum type depends on the TGT session key encryption type(!)
For example:
- If the TGT session key type is AES256-CTS-HMAC-SHA1-96 (18), the checksum type will be HMAC-SHA1-96-AES-256 (16)
- If the TGT session key type is AES128-CTS-HMAC-SHA1-96 (17), the checksum type will be HMAC-SHA1-96-AES-128 (15)
However, when an older, “not-newer” encryption type is used, a legacy checksum algorithm can be used.
For example:
- If the TGT session key type is RC4-HMAC-NT (23), then the checksum type may be RSA-MD4 (2)
HMAC-based checksums are keyed, meaning their integrity depends on secret material known only to the communicating parties. In contrast, RSA-MD4 is an unkeyed checksum.
According to RFC3961, RSA-MD4 Message Integrity Check (MIC) is simply md4(message) – no session key involved.
Unkeyed checksums do not provide tamper resistance and are not suitable for protecting plaintext structures. For this reason, their use is not recommended and only exists for legacy compatibility.
In the context of S4U, the resulting PA-DATA structures are flexible enough to support both certificate-based and username-based identity assertions for S4U2Self. In practice, these structures may coexist and, in some scenarios, are even transmitted together.
Why this matters
The key point is that no user credentials are required to obtain a Kerberos ticket on a user’s behalf. The only input needed to assert a user identity is a username string.
In one S4U flow, that string is not cryptographically protected against modification by an attacker.
This means that if an attacker can control that string, they can control the impersonation flow. The resulting ticket is then propagated to S4U2Proxy, which blindly trusts the S4U2Self result. From that point on, the delegation chain proceeds as designed.
To address this weakness, Microsoft attempted to introduce compensating security measures.
On the client (application) side:
- When a “not-newer” TGT session key is used, only PA-DATA 129 is permitted.
- PA-FOR-X509-USER is not sent.
- As a result, MD4-based checksums should not appear in the request.
On the server (KDC) side:
- When MD4 is used, both the request and reply checksum values are included inside the encrypted portion of the KDC response.
- These values are returned to the client, which is expected to verify both as a compensating integrity check.
CVE-2025-60704 Part I: Downgrade-enabled unkeyed checksum in PA-S4U-X509-USER
Primitive overview
The first primitive is the ability to force the certificate-based S4U2Self identity assertion into a legacy, unkeyed checksum mode.
This becomes security-relevant because the checksum protecting the S4UUserID structure is selected based on the encryption type negotiated for the service’s TGT session key. If that negotiation results in RC4, the checksum used by PA-S4U-X509-USER can degrade to RSA-MD4, which provides no cryptographic keying.
Once this happens, integrity protection of the asserted user identity is effectively lost.
Step 1: Downgrade the TGT encryption type via Machine-in-the-Middle (MITM)
To reach the MD4 code path, we need to inject our mutation code into the path between the application (we’ll refer to it as the “Client” from now on) and the KDC (“Server”), and downgrade the encryption type used in the Kerberos exchange. This means forcing the AS-REQ to negotiate RC4-HMAC (etype 23).
On Windows, this turns out to be straightforward:
- The default AS-REQ is sent in plaintext, with no signing or sealing.
- The client will negotiate older encryption types if allowed by policy.
After modification, the KDC responds with an AS-REP, and a new TGT is installed in the cache.
Result:
The TGT session key is now RC4-HMAC-MD5 (etype 23).
Observing client behavior: Downgrade protection against unkeyed Checksums
As expected, client behavior for S4U2Self TGS-REQ changes when RC4 is used as the session key encryption type:
- Only PA-DATA 129 (PA-FOR-USER) is sent.
- PA-DATA 129 is hardcoded to use HMAC-MD5.
At this point, Microsoft’s client-side restriction appears to be functioning as intended.
Server-side behavior and the bypass condition
To understand how this restriction can be bypassed, we need to examine the server-side implementation, specifically the KDC logic in KDCSVC!KdcFindS4UClientAndRealm.
This function follows a simple decision flow:
- It first calls KerbFindPerAuthDataEntry to locate PA-DATA type 130.
- If PA-DATA 130 is not found, it falls back to PA-DATA type 129.
- It then continues with additional validation steps.
This behavior has an important implication. If both PA-DATA types are present, PA-DATA 129 is ignored in favor of PA-DATA 130.
At this stage, the KDC performs no validation of the negotiated encryption type and does not enforce any restriction on which PA-DATA structures are acceptable when RC4 is in use. Because there is also no cryptographic binding or tamper protection between the session key type and the PA-DATA used to assert identity, an attacker can inject a crafted PA-DATA type 130 even in an RC4-based exchange.
In other words, while the client will not send PA-DATA 130, nothing prevents an attacker from adding it.
Step 2: Injecting PA-DATA 130
At this point, a man-in-the-middle adversary can inject an additional PA-S4U-X509-USER (type 130) element into the S4U2Self TGS-REQ.
The injected PA-DATA encodes an attacker-chosen identity inside the S4UUserID structure. This can be done, for example, by explicitly setting:
- cname to the target account
- crealm to the target domain
Other optional fields may be included or omitted depending on the construction mode.
Because the checksum is now unkeyed, its computation is simply:
Checksum = md4(DER(S4UUserID)) Result
When the request is processed, the KDC examines the first PA-DATA type 130 entry, selects RSA-MD4 as the checksum algorithm, and accepts the request as valid. The forged identity assertion is therefore trusted by the KDC.
Achievements of Part I
If Part I succeeds, the KDC can issue a valid S4U2Self service ticket where the client principal and PAC correspond to an attacker-chosen identity. This matters because the S4U2Self ticket becomes the ticket that is subsequently presented to the KDC during S4U2Proxy, and the downstream delegated ticket identity is derived from it.
CVE-2025-60704 Part II: Bypass client validation process
Part I produces a valid S4U2Self service ticket that represents an attacker-chosen identity. However, this result is not sufficient on its own because the ticket fails to install on the client. This is a critical barrier, since the S4U2Self ticket must be present and usable for subsequent S4U2Proxy processing.
Part II describes the client-side validation logic that prevents installation and the bypass that makes the ticket usable.
TGS-REP encrypted-pa-data
MS-SFU defines a compensating integrity mechanism for legacy or unkeyed checksum modes. When the KDC returns the relevant S4U PA-DATA inside the encrypted-pa-data field of the encrypted portion of the TGS-REP, the client MUST verify the checksum values associated with the request and the reply. The purpose of this design is to enforce request-to-reply binding using values that are only available after decrypting the response. This compensates for the fact that the outer PA-DATA structures may be attacker-modifiable when compatibility checksum algorithms are used.
TL;DR
Removing the S4U-related PA-DATA from the reply message entirely causes the client to skip the verification logic and accept the ticket.
If you do not need to understand the validation process in detail and want to proceed directly to exploitation, you can skip ahead to Step 1.
To understand why this bypass works, we first need to examine how the KDC constructs the encrypted response and how the validation data is embedded. The following sections walk through this process step by step.
Understanding the checksum Validation Process (KDC – Server Side)
On the server side, this logic is implemented across KDCSVC.DLL and CRYPTDLL.DLL.
The validation flow begins in kdcsvc!HandleTGSRequest, which, despite its name, handles both request and reply messages processing.
The request verification is performed as follows:
- HandleTGSRequest calls kdcsvc!KdcFindS4UclientAndRealm to extract the client name.
- KerbFindPreAuthDataEntry is being called to locate PA-DATA type 130.
- The structure is passed to KerbSignS4UpreauthDataEx for checksum verification.
- The checksum type is selected by first resolving the encryption type using:
- cryptdll!CDLocateCSystem
- crytdll!CDLocateCheckSum
- Based on the resolved encryption type, the appropriate checksum algorithm is selected.
- In the downgrade scenario, this resolves to MD4.
- The KDC computes the checksum over the request and compares it with the checksum supplied by the client.
If the result is valid, HandleTGSRequest calls BuildReply to construct the reply message, and proceeds with the following steps:
- KerbSignS4UPreauthDataEx is called again to compute the checksum over the reply.
- If the encryption type is not AES, the KDC invokes KdcAddEncryptedS4uPaData.
- The KDC concatenates the checksum calculated over the request with the checksum calculated over the reply.
- If the request checksum is valid, the KDC proceeds to construct the reply.
- Both checksum values (16-byte request + 16-byte reply) are placed into pa-for-x509-user under the encrypted-pa-data section of the TGS-REP.
- The encrypted portion of the response is sealed using the session key and sent back to the client.
When the client receives the TGS-REP, it is expected to decrypt the encrypted portion of the message using the session key, Locate PA-DATA type 130 and compare the plaintext checksum in the reply with the last 16 bytes of the encrypted PA-DATA, and compare the first 16 bytes with the client request
Only if all of these checks succeed, the ticket should be accepted and installed into the cache.
Checksum validation process (Client side)
On the client side, the checksum validation logic is implemented in KERBEROS.DLL, primarily within a function with a highly indicative name: kerberos!KerbCheckX509S4uReply. This function is responsible for validating the compensating integrity mechanism applied to PA-S4U-X509-USER replies.
The validation flow begins when the client receives and decrypts the encrypted portion of the TGS-REP. The processing logic then proceeds as follows:
- The client checks whether the reply message contains the expected S4U-related structures.
- KerbFindPreAuthDataEntry is called to locate PA-DATA type 130.
- If PA-DATA type 130 is found, the client computes the checksum over the reply using KerbCredIsoIum::SignS4UPreauthData.
- The computed reply checksum is compared with the checksum value supplied by the KDC.
- Now, the client checks the encryption type associated with the session key.
- If the encryption type is AES (etype 18 / 0x12), validation succeeds, and no additional verification is performed.
When the encryption type is RC4 (etype 23), the function follows a different control path:
- The client expects to find encrypted PA-DATA type 130 containing both:
- the echoed checksum of the reply, and the echoed checksum of the original request.
- The code verifies the size of the checksum buffers and attempts to extract a buffer that should contain the checksum computed over the original request.
- The client attempts to compare this value with a locally computed checksum for the request.
At this point, validation fails.
The client never computes an MD4 checksum over the request, and therefore has no local value to compare against the echoed request checksum. As a result, the function exits with an error and the ticket is not installed.
While analyzing the possible success paths, one branch stands out. If PA-DATA type 130 is not present, the code jumps to an internal branch labeled LABEL72. In this path, several flags are checked, the return value is zeroed, and the function returns success without performing the encrypted-pa-data checksum binding verification.
This behavior directly enables the bypass.
Step 1: Removing the PA-DATA object from the response
By modifying the padata-type to any other value than 130, or by removing the PA-DATA structure entirely from the reply, the client never enters the strict validation path. Instead, it follows the alternate branch and accepts the ticket’s integrity check.
In short, the presence of PA-DATA 130 determines whether the client enforces the compensating integrity check. Removing it causes the validation logic to silently succeed, allowing the forged S4U2Self ticket to continue with the installation code flow.
Step 2: Restoration of cname
At this stage, the cname of the returned ticket must be restored from the targeted identity back to the original user.
The reason for this is subtle but important. The application originally initiated impersonation for User A, but the manipulated S4U TGS-REP now contains a valid service ticket for User B. When the host that initiated the impersonation receives this ticket, the mismatch between the expected client name and the ticket’s cname causes the ticket installation to fail. This creates an additional constraint for successful exploitation.
However, the attacker can take advantage of the fact that the cname field is not integrity-protected. By modifying the cname in the returned ticket from User B back to User A, the ticket once again matches the expectations of the initiating logon session and is accepted.
This behavior also demonstrates an important secondary issue: No additional verification of the PAC is performed during ticket installation. The client accepts the ticket based on surface-level consistency checks, even though the PAC embedded in the ticket represents a different user.
Achievements of Part II
At this point, the attacker obtains a valid S4U2Self service ticket that is installed into User A’s logon session, while the embedded PAC corresponds to User B.
This removes the final client-side barrier. The ticket is now fully usable and can be presented in the next phase of the attack: S4U2Proxy, where the delegated service ticket identity will be derived from this forged S4U2Self ticket.
Exploitation and real-world examples
To demonstrate how this behavior can be exploited in practice, I built a small web application that authenticates users, performs Kerberos delegation, and accesses remote files over CIFS.
The application follows a common multi-tier pattern: an IIS frontend authenticates the user and then delegates access to a backend file server.
We’ll authenticate using a low-privilege domain account (user), use the MitM technique, and run the attack to gain administrator privileges.
The code will examine each message and modify only the necessary fields in the AS-REQ , TGS-REQ, TGS-REP messages as follows:
Using this exploit will give user1 the authorization context of ‘administrator’ (or any other non-sensitive user):
Real-world Examples
While researching practical abuse scenarios for this vulnerability, I identified two sensitive and widely deployed applications that illustrate its impact.
Certificate Authority Web Enrollment uses delegation in a classic multi-tier model. An IIS frontend authenticates the user and then delegates to a remote Certificate Authority to perform certificate issuance under the user’s identity, applying domain policy, template permissions, and issuance rules.
Entra Application Proxy uses delegation in a connector-based model. An on-premises connector performs protocol transition and constrained delegation to provide single sign-on from cloud identity to on-premises Kerberos applications.
Although these applications serve different business purposes, they share a critical commonality: both rely on delegated identity to authorize sensitive downstream operations. As a result, both represent high-impact escalation surfaces when the integrity of delegated identity is compromised.
Each of these applications can be exploited independently. More importantly, they can also be combined, amplifying the impact and demonstrating how identity confusion in one layer can propagate across trust boundaries.
CA Web Enroll
The Certification Authority (CA) Web Enrollment service is a Microsoft Active Directory Certificate Services (AD CS) service that provides a web-based interface for users and computers to interact with a Certificate Authority.
It acts as a bridge, allowing users to submit certificate requests, download certificates, and retrieve Certificate Revocation Lists (CRLs) through a web browser without needing direct, native interaction with the CA server.
Entra Application Proxy and Kerberos Delegation
Entra Application Proxy is a representative example of a hybrid identity architecture, where authentication is performed in the cloud, while authorization is enforced on-premises using Kerberos.
At a high level, Entra Application Proxy acts as a cloud-based reverse proxy for on-prem web applications. Users authenticate to the application using Microsoft Entra ID single sign-on, and the authenticated session is then tunneled through the on-premises Application Proxy Connector.
The connector is responsible for bridging these two worlds.
See here: https://learn.microsoft.com/en-us/entra/identity/app-proxy/how-to-configure-sso-with-kcd.
Once the user is authenticated in the cloud, the connector must translate that identity into something on-prem services understand. When the backend application relies on Kerberos, this translation is performed using S4U protocol transition.
The connector uses its own Kerberos context to request an S4U2Self ticket representing the authenticated user, and then uses constrained delegation (S4U2Proxy) to obtain service tickets for downstream on-prem resources.
In other words, protocol conversion is not an edge case here; it is fundamental to the design.
Figure 20: configuration example from Microsoft guide showing protocol transition by design
This is exactly the condition required for the vulnerability chain described in this research. When cloud authentication, protocol transition, and constrained delegation are combined by design, flaws in the S4U trust model become security-relevant.
Watch the example here of the Entra Proxy App to CA WebEnroll:
Key takeaways
Impersonation: Understand first, implement second. Delegation and S4U enable a service to act on behalf of a user. Any system that can request tickets “on behalf of” a user must be treated as a security boundary. Misunderstanding where identity is sourced, how it is bound, and which component enforces it is what turns delegation into an escalation surface.
Authentication is only as strong as its weakest link. Strong crypto at the ticket layer does not help if identity is introduced through a weaker path, negotiated into a weaker mode, or accepted through a weaker validation branch. End-to-end identity assurance is determined by the least protected step in the chain.
Right technique, right use:
- Hashing is used for integrity.
- Signing / MACs are used for authenticity and integrity.
- Sealing (encryption) is used for confidentiality.
In this case, integrity alone was relied upon, where integrity and authenticity were required.
Mitigations
- Apply vendor fixes and validate behavior Patch Windows systems according to the November 2025 security update guidance and validate that Kerberos behavior matches the fixed model in your environment, with priority on domain controllers and systems that perform protocol transition and delegation.
- Enable Kerberos FAST (armoring) to reduce downgrade and MITM manipulation opportunities in pre-authentication and negotiation, and to harden the integrity of the Kerberos exchange against traffic-level interference.
- Harden cryptographic posture and compatibility surfaces. Reduce exposure to legacy modes by disabling older encryption types where feasible, since these are what make weaker checksum mappings reachable through negotiation. Monitor service account and domain policy settings for drift from modern defaults.
- Treat delegation as a high-risk configuration surface. Minimize the number of service accounts trusted for protocol transition and delegation. Prefer constrained delegation and keep allowed target SPNs tightly scoped. Audit which service accounts are trusted for protocol transition, which SPNs they can delegate to, and ensure privileged accounts are marked as non-delegable unless a tightly scoped business requirement exists.
- Monitoring and detection guidance – Monitor for anomalous S4U2Self and S4U2Proxy usage patterns, unexpected target SPNs, and identity discontinuities where delegated tickets reflect principals inconsistent with the initiating session. For certificate services, monitor for unexpected enrollment of privileged identities, unusual template usage, and issuance activity originating from proxy-published application path.
References
Encryption and Checksum Specifications for Kerberos 5 RFC 3961
Implement impersonation in application
Configure constrained delegation for CA Web Enroll pages