# Pass-the-Hash to Pass-the-PRT: Twenty-Nine Years of Windows Credential Replay in One Family Tree

> Pass-the-Hash, Pass-the-Ticket, Overpass-the-Hash, Pass-the-Certificate, and Pass-the-PRT are one architectural lineage. Each defense bought years; none closed the family.

*Published: 2026-05-28*
*Canonical: https://paragmali.com/blog/pass-the-hash-to-pass-the-prt-twenty-nine-years-of-windows-c*
*License: CC BY 4.0 - https://creativecommons.org/licenses/by/4.0/*

---
<TLDR>
Twenty-nine years of Windows credential-replay attacks -- Pass-the-Hash, Pass-the-Ticket, Overpass-the-Hash, Pass-the-Certificate, Pass-the-PRT -- are a single lineage, not five techniques. Each generation finds the next long-term authentication artefact that lives outside the latest Microsoft isolation boundary, then commoditises extraction in tooling that runs anywhere with local administrator. Credential Guard (2015) and KB5014754 (2022) bought years but not closure; Pass-the-PRT (Mollema + Delpy, 2020) already defeats both because the Primary Refresh Token lives in the CloudAP plug-in, which is not inside any current isolation scope. The next decade of Windows credential theft turns on whether Microsoft extends hypervisor-based isolation to CloudAP before commodity offensive tooling makes the attack universal.
</TLDR>

## 1. Two Afternoons, Twenty-Nine Years Apart

On the afternoon of Tuesday, April 8, 1997, between 5:27 p.m. and 8:57 p.m. -- a window we can narrow to about three and a half hours from the file timestamps preserved in the patch he posted -- a researcher named Paul Ashton sat down with the Samba source tree and made the smallest possible change to `smbclient`.<Sidenote>The bracketing mtimes `Tue Apr  8 17:27:29 1997` and `Tue Apr  8 20:57:43 1997` are preserved verbatim in the unified diff's `***` and `---` header lines on Exploit-DB advisory 19197 [@ashton-exploitdb-19197]. You can still download the diff today and confirm the timestamps yourself.</Sidenote> Where the unpatched client computed a network response from a typed-in password, his version read the password's LM hash from `smbpasswd` on disk and fed it straight to the same encryption primitive, skipping the password entirely.

He posted the diff to NTBugtraq the same evening with a five-line advisory: "A modified SMB client can mount shares on an SMB host by passing the username and corresponding LanMan hash of an account that is authorized to access the host and share. The modified SMB client removes the need for the user to 'decrypt' the password hash into its clear-text equivalent." [@ashton-exploitdb-19197]

Twenty-nine years later, every Windows credential-replay attack in commodity offensive tooling is a direct descendant of that afternoon.

Fast-forward to 2026. A Windows 11 23H2 laptop, hardened to Microsoft's published baseline. [Credential Guard](/blog/the-empty-hash-credential-guard-the-lsaiso-trustlet-and-the-/) on. KB5014754 strong certificate mapping in full enforcement. Conditional Access enabled, with Token Protection where supported. An attacker has local admin -- the same starting position the 1997 attack assumed.

Two commands run on that machine, in the same paragraph. Mimikatz `sekurlsa::logonpasswords` returns empty NT hash and TGT buffers; Credential Guard has done its job. Then Mimikatz `dpapi::cloudapkd /unprotect` returns a valid Primary Refresh Token session key and proof-of-possession material [@mollema-prt-digging]. On a *different* machine across the internet, the attacker pastes that material into Dirk-jan Mollema's `roadtx prt`, mints an `x-ms-RefreshTokenCredential` cookie, and authenticates to Entra ID as the laptop's user [@mollema-prt-abusing] [@roadtools-github]. Every Microsoft defense shipped in 2015, 2022, and 2024 is running. The attack still wins.

> **Note:** The empty buffer from `sekurlsa::logonpasswords` is the artefact of twenty-nine years of architectural lessons. The PRT extraction from `dpapi::cloudapkd` is the architecture of the *next* five-to-ten years. Both scenes are the same attack class. The credential changed; the protocol that consumes it changed; the long-term storage location changed; the lineage did not.

You will meet seven people in this article. Paul Ashton (1997, the patch). Hernan Ochoa (2008, the toolkit that put the technique inside Windows itself). Benjamin Delpy (2011, Mimikatz; and the Kerberos generations that followed). Sean Metcalf (2014, who named Overpass-the-Hash and wrote the practitioner reference that taught a generation of red and blue teams).

Will Schroeder and Lee Christensen (2021, "Certified Pre-Owned," the AD CS catalog that became Pass-the-Certificate). Oliver Lyak (2022, Certifried, the CVE that forced Microsoft to ship KB5014754). And Dirk-jan Mollema (2020, the Primary Refresh Token research this article argues is the most consequential credential-theft work since 2008). The cast is small. The lineage they built is the load-bearing structure of every Windows penetration test in 2026.

How is it possible that the same attack works in 1997 and 2026? The answer is structural, not coincidental -- and once you see it, you cannot unsee it.

## 2. The Architectural Property the Family Shares

NTLM authentication never asks for the password as a string. It asks for a function of the hash. The hash *is* the password.

That sentence is the article's load-bearing claim, and the rest of this section is its proof.

The Microsoft specification for the NTLM protocol -- `[MS-NLMP]`, sections 3.3.1 and 3.3.2 -- writes the response computation in pseudocode. For NTLMv1, the server sends an 8-byte challenge; the client computes `NtChallengeResponse = DESL(ResponseKeyNT, challenge)`, where `ResponseKeyNT = NTOWFv1(password) = MD4(UNICODE(password))` [@ms-nlmp-3-3-1]. `DESL` is a variant of DES that pads the 16-byte NT hash to 21 bytes with five zero bytes, splits the result into three 7-byte sub-keys, runs DES on the 8-byte challenge under each sub-key, and concatenates the three 8-byte ciphertexts to form a 24-byte response.

NTLMv2 is more elaborate -- the response key is `NTOWFv2 = HMAC_MD5(MD4(UNICODE(password)), UNICODE(Uppercase(User) + UserDom))`, and the proof string is `HMAC_MD5` of the challenge concatenated with a target-info structure -- but the structural property is identical: the cleartext password appears in exactly one place in the entire protocol, the input to the hash function on the client. The verifier performs the same computation against the stored NT hash from the SAM or NTDS.dit, and compares. Neither side ever transmits the password [@ms-nlmp-3-3-2].

This is what Microsoft means when its institutional documentation says Pass-the-Hash "cannot be patched at the protocol level." There is nothing to patch.<MarginNote>The same property holds for any challenge-response protocol whose verifier stores a determinable function of the password rather than the password itself: Kerberos with stored long-term keys, CHAP with shared secrets, OAuth client_credentials with shared secrets, every HMAC-based proof-of-possession scheme.</MarginNote>

The protocol takes a stored hash and produces a response. Swap the user's hash for the attacker's hash, and the protocol still produces a valid response, signed by the substituted key. The bug is not a bug; it is a documented property.

<Definition term="NTLM challenge-response">
A family of Windows authentication protocols (NTLMv1 and NTLMv2) in which a server sends a random challenge and the client returns a response computed by applying a keyed cryptographic primitive (DES or HMAC-MD5) to that challenge under a key derived from the user's password. The verifier holds the same key and recomputes the response to confirm. The cleartext password is never transmitted [@ms-nlmp-3-3-1] [@ms-nlmp-3-3-2].
</Definition>

<Definition term="NT hash">
The 16-byte MD4 of the user's password as UTF-16 little-endian (`MD4(UNICODE(Passwd))` in the NLMP pseudocode). Unsalted by design, because NT was originally specified for an offline domain controller that has to verify against a fixed reference value. The NT hash is the long-term symmetric Windows authentication secret for every account, stored locally in the SAM and centrally in the NTDS.dit Active Directory database [@ms-nlmp-3-3-1].
</Definition>

<Definition term="Pass-the-Hash">
The technique of authenticating to a service that uses NTLM (or any protocol descended from the same family) by feeding a stolen NT hash directly to the response-construction function, instead of typing a password the function would then hash. The terminology and the first working demonstration are due to Paul Ashton, NTBugtraq, April 1997 [@ashton-exploitdb-19197].
</Definition>

<Mermaid caption="NTLM challenge-response: the protocol consumes a function of the hash, never the password. Pass-the-Hash substitutes the stored hash; the verifier accepts the response because it matches.">
sequenceDiagram
    participant Client
    participant Server
    participant Verifier as SAM or NTDS.dit
    Client->>Server: NTLM_NEGOTIATE
    Server->>Client: NTLM_CHALLENGE with 8-byte nonce
    Note over Client: ResponseKeyNT equals NTOWFv1 of stored NT hash
    Note over Client: NtChallengeResponse equals DESL of ResponseKeyNT and nonce
    Client->>Server: NTLM_AUTHENTICATE with response
    Server->>Verifier: Look up stored NT hash for user
    Verifier-->>Server: Stored NT hash
    Note over Server: Recompute DESL of stored hash and nonce
    Server->>Client: Authentication succeeds if responses match
</Mermaid>

> **Key idea:** The hash is the password. Any long-term authentication artefact reachable by the process that uses it is replayable -- and every credential type the rest of this article discusses (Kerberos TGT, certificate private key, Primary Refresh Token session key) is a different instance of this same property. Defenses can isolate one artefact at a time; the property is intrinsic to the architecture.

Ashton's 1997 patch was the protocol-disclosure proof. He swapped a single function call -- `SMBencrypt(pass, cryptkey, pword)` became `E_P24(p21, cryptkey, pword)`, where `p21` is the user's LM hash read directly from `smbpasswd` -- and Samba's `smbclient` authenticated to NT 3.51 and NT 4.0 file servers without ever knowing the user's password [@ashton-exploitdb-19197]. You can read the patch in five minutes. It is also, in a precise sense, the first proof that NTLM's response computation is hash-equivalent: if substituting the hash works, then mathematically the hash is what the protocol wanted all along.

And then nothing happened for eleven years.

That gap deserves its own explanation, because the eleven-year interregnum is the cleanest failure mode in the lineage.

Wikipedia's modern summary of the pre-2008 limitation reads: "even after performing NTLM authentication successfully using the pass the hash technique, tools like Samba's SMB client might not have implemented the functionality the attacker might want to use. This meant that it was difficult to attack Windows programs that use DCOM or RPC. Also, because attackers were restricted to using third-party clients when carrying out attacks, it was not possible to use built-in Windows applications, like Net.exe or the Active Directory Users and Computers tool amongst others, because they asked the attacker or user to enter the cleartext password to authenticate, and not the corresponding password hash value." [@wikipedia-pass-the-hash]

<Aside label="Why this did not catch on for eleven years">
Inside Microsoft the 1997 patch was treated as confirming a known property of LSASS-resident credentials, not as a new attack class. The institutional position was that any compromise yielding the hash already implied SYSTEM-equivalent access, and that the realistic chain was "exfiltrate the hash and crack it offline," not "replay the hash." The architectural counter-claim -- that *replaying* the hash from inside a Windows process bypasses every native-tool obstacle -- took a decade to land in the practitioner literature. The 2012 Duckwall + Campbell Black Hat USA paper named the lag in its title: "Still Passing the Hash 15 Years Later." [@duckwall-campbell-bh2012]
</Aside>

If the obstacle is "built-in Windows tools ask for cleartext," the architectural answer is to put the substituted hash *inside* the Windows process that those tools rely on. That insight took eleven years to operationalise. The person who operationalised it was Hernan Ochoa, in 2008.

## 3. From Patch to Toolkit: The Windows-Native Pivot

By 2008, Ashton's 1997 patch had been sitting on NTBugtraq for eleven years. Hernan Ochoa had a different idea: instead of patching the client, patch the *credential cache*.

The artefact Ochoa shipped at CanSecWest 2008 and Black Hat USA 2008 was called the *Pass-the-Hash Toolkit*, distributed through Core Security Technologies' open-source projects page [@corelabs-pshtoolkit-wayback]. It contained two executables. `IAM.EXE` opened the LSASS process with `PROCESS_VM_WRITE`, located the cached credential block for the current interactive logon session, and overwrote the NT hash and username fields with attacker-supplied values. `PTH.EXE` spawned a target process under a substituted hash.

Once the substitution was in place, every native Windows SSO consumer -- `net.exe`, `wmic`, `mstsc` once Restricted Admin RDP shipped years later, SMB, RPC, DCOM -- transparently picked up the attacker-supplied hash, because the OS handed them what it believed were the legitimate user's credentials.

Wikipedia summarises the architectural pivot in one paragraph: "It allowed the user name, domain name, and password hashes cached in memory by the Local Security Authority to be changed at runtime *after* a user was authenticated -- this made it possible to 'pass the hash' using standard Windows applications, and thereby to undermine fundamental authentication mechanisms built into the operating system." [@wikipedia-pass-the-hash] The eleven-year limitation was gone. Pass-the-Hash was now a Windows-native attack that worked against any tool that read its credentials from LSASS -- which in practice meant *every* Windows tool.

<Definition term="LSASS (Local Security Authority Subsystem Service)">
The user-mode Windows process (`lsass.exe`) that handles interactive logon, owns the Security Reference Monitor's policy decisions, and -- relevant to this article -- caches the in-memory credential material that supports Single Sign-On for the duration of each logon session: NT hashes for NTLM, Kerberos TGTs and session keys, certificate handles, and (since Azure AD / Entra ID device join) Primary Refresh Token material in the CloudAP plug-in. Every credential-replay technique in this article reaches its target by reading LSASS in some form.
</Definition>

The 2012 retrospective is where the security industry stopped pretending Pass-the-Hash was solved. Alva Duckwall and Christopher Campbell shipped a Black Hat USA 2012 paper titled, unambiguously, "Still Passing the Hash 15 Years Later." [@duckwall-campbell-bh2012] The title is the load-bearing pull-quote: it named Ashton 1997 as the origin, Ochoa 2008 as the Windows-native pivot, and the industry's continued failure to ship a structural fix as the central fact. From this point onwards Microsoft itself acknowledged Pass-the-Hash as a structural property of NTLM rather than a fixable bug.

<Sidenote>Hernan Ochoa's Windows Credentials Editor (WCE), released a year after the Pass-the-Hash Toolkit, developed the same LSASS-injection primitive on a separate code base. Two independent implementations converging on the same memory-access pattern in the same window is the clearest indication that the architectural insight -- "the credential is sitting in a process you can write to" -- was overdetermined once anyone went looking for it.</Sidenote>

What did Ashton's 1997 patch leave on the table? The other long-term credentials that LSASS held. The NT hash was the first. There would be more.

If you can read the NT hash from LSASS, you can read the Kerberos TGT from LSASS. The same memory-access primitive that animates `IAM.EXE` is one commit away from animating `sekurlsa::tickets`. That commit shipped in May 2011. Its author was a twenty-five-year-old French programmer named Benjamin Delpy.

## 4. Mimikatz and the Kerberos Turn

In May 2011, Benjamin Delpy posted his first public release of a program he had been writing as a side project to learn C. He was twenty-five, working as an IT manager at an institution he has never publicly named. Andy Greenberg's Wired profile records the date: "He released it publicly in May 2011, but as a closed source program." [@wired-greenberg-mimikatz] Wikipedia corroborates: "He released the first version of the software in May 2011 as closed source software." [@wikipedia-mimikatz] The program was called Mimikatz.

What made Mimikatz architecturally different from Ochoa's toolkit was that it was *modular*. The credential-extraction primitives lived in named command groups: `sekurlsa::logonpasswords` dumped NT hashes from LSASS; `sekurlsa::tickets` dumped Kerberos tickets from LSASS; `kerberos::ptt` injected a stolen ticket into the current Kerberos cache via the documented `LsaCallAuthenticationPackage` API with the `KerbSubmitTicketMessage` message [@ms-lsa-call-auth-package]; `lsadump::dcsync` (added August 2015, in collaboration with Vincent Le Toux) impersonated a domain controller and asked another DC for the krbtgt hash via the IDL_DRSGetNCChanges replication RPC [@adsec-dcsync-p1729].

Same LSASS, different artefact, different protocol surface. The architectural property section 2 named had two artefacts to work with on Windows: the NT hash, and the Kerberos TGT.

This is **Pass-the-Ticket** (Generation 2). The stolen TGT plus its session key authenticates the holder as the original principal for the ticket's lifetime, which on a default AD deployment is ten hours, renewable for seven days. Time complexity per replay: O(1). The TGT session key is the load-bearing piece -- without it, the ticket is opaque encrypted bytes that the holder cannot decrypt, sign, or present back to the KDC. Mimikatz's `sekurlsa::tickets /export` writes the ticket as a `.kirbi` file on disk; `kerberos::ptt <file>` re-injects on any machine where the user has a Kerberos credentials cache.

<Definition term="Kerberos TGT (Ticket Granting Ticket)">
The long-lived Kerberos credential issued by the KDC's Authentication Service (AS-REP) in response to a successful AS-REQ. The TGT is encrypted under the KDC's own krbtgt-account long-term key and contains a session key that the client uses to subsequently request service tickets from the Ticket Granting Service (TGS). Specification: RFC 4120, section 3 [@rfc-4120]. On a Windows Active Directory deployment the default TGT lifetime is 10 hours with renewal up to 7 days.
</Definition>

<Definition term="Pass-the-Ticket">
The technique of extracting a Kerberos TGT (and its session key) from one machine's LSASS-resident Kerberos cache and injecting it into another machine's cache, so that subsequent service-ticket requests authenticate as the ticket's original principal. Tool of record: Mimikatz `sekurlsa::tickets` + `kerberos::ptt`; equivalent functionality in Rubeus and Impacket.
</Definition>

<Mermaid caption="Pass-the-Ticket: extract from one machine's LSASS-resident Kerberos cache, inject into another machine's cache via LsaCallAuthenticationPackage, then request service tickets normally.">
sequenceDiagram
    participant Victim as Victim host
    participant Attacker as Attacker host
    participant KDC
    Note over Victim: User logged in, TGT cached in LSASS Kerberos package
    Attacker->>Victim: mimikatz sekurlsa::tickets export
    Victim-->>Attacker: TGT.kirbi (ticket plus session key)
    Note over Attacker: mimikatz kerberos::ptt TGT.kirbi
    Attacker->>KDC: TGS-REQ presenting injected TGT
    KDC-->>Attacker: TGS-REP service ticket
    Attacker->>Attacker: Authenticate to any Kerberos service as the victim
</Mermaid>

> **Note:** A common shorthand says that Microsoft's Credential Guard isolated NT hashes, so attackers shifted to TGTs. That arrow runs backwards in time. Pass-the-Ticket predates Credential Guard by years -- the Mimikatz Kerberos primitives developed between the May 2011 closed-source release and the April 6, 2014 open-source commit (the earliest verifiable source-level evidence for `sekurlsa::tickets` and `kerberos::ptt`), and were presented in detail at Black Hat USA 2014 by Duckwall and Delpy [@infocondb-bh2014-duckwall] [@duckwall-delpy-bh2014-wp]. Pass-the-Ticket exists because TGTs are also in LSASS, not as a defensive response. The shift to a new artefact happened because the *architectural property* of credential extraction generalised, not because Credential Guard pushed attackers there.

The third generation followed shortly. **Overpass-the-Hash** observes that for the RC4-HMAC Kerberos encryption type -- the Windows default from Windows 2000 through November 2022 -- the user's long-term Kerberos key is the unchanged NT hash.

RFC 4757, authored by K. Jaganathan, L. Zhu, and J. Brezak of Microsoft and published as informational in December 2006, specifies the RC4-HMAC enctype's long-term key as the existing NT hash without modification [@rfc-4757]. An attacker who holds the NT hash can drive a legitimate Kerberos AS-REQ to the KDC, encrypt the timestamp pre-auth blob with the NT hash as the RC4-HMAC key, and receive a real TGT signed by the real krbtgt.

The economic effect is large. Pass-the-Hash gets you NTLM-based services -- SMB, RPC, and any protocol over them. Overpass-the-Hash gets you the entire Kerberos surface: Kerberos-only services, services that require Kerberos for delegation, services with NTLM disabled at the GPO level. Same NT hash. Different downstream protocol. Strictly larger attack surface.

<Definition term="Overpass-the-Hash">
The technique of presenting a stolen NT hash to the KDC as the user's long-term RC4-HMAC Kerberos key (per RFC 4757 [@rfc-4757]), obtaining a real TGT signed by the real krbtgt, and operating as a real Kerberos client for the ticket's lifetime. Tool of record: Mimikatz `sekurlsa::pth /user: /domain: /ntlm: /run:` and Rubeus `asktgt /user: /rc4:`. Per Sean Metcalf's adsecurity.org reference, the technique is named "over" because the hash is promoted one notch up the protocol stack from NTLM into Kerberos [@adsec-mimikatz-p556] [@adsec-kerberos-p2293].
</Definition>

<Mermaid caption="Overpass-the-Hash: a captured NT hash is the RC4-HMAC long-term Kerberos key, so it drives a legitimate AS-REQ to the KDC and yields a real TGT.">
sequenceDiagram
    participant Attacker
    participant KDC
    participant Service as Kerberos service
    Note over Attacker: Holds NT hash for user (e.g. from sekurlsa::logonpasswords)
    Attacker->>KDC: AS-REQ with PA-ENC-TIMESTAMP encrypted under RC4-HMAC(NT hash)
    KDC->>KDC: Verify PA-ENC-TIMESTAMP decrypts cleanly
    KDC-->>Attacker: AS-REP with real TGT signed by krbtgt
    Attacker->>KDC: TGS-REQ for Service
    KDC-->>Attacker: TGS-REP service ticket
    Attacker->>Service: AP-REQ authenticate as user
    Service-->>Attacker: Access granted
</Mermaid>

The naming has its own story. The Mimikatz capability is Delpy's; the term "Overpass-the-Hash" and the taxonomic framing that distinguishes it from straight Pass-the-Hash spread through the practitioner community via Sean Metcalf's adsecurity.org reference [@adsec-mimikatz-p556] and the Duckwall + Delpy Black Hat USA 2014 talk and whitepaper [@infocondb-bh2014-duckwall] [@duckwall-delpy-bh2014-wp]. The earliest archived snapshot of the adsecurity.org reference is October 1, 2014; the talk timestamp is August 7, 2014. The two sources are essentially contemporaneous, and Metcalf's later "Red vs. Blue" Black Hat USA 2015 whitepaper consolidates the practitioner taxonomy [@metcalf-bh2015-red-vs-blue].

<Sidenote>The "Overpass" coinage is a deliberate semantic argument that the technique is one notch *above* Pass-the-Hash on the protocol stack: the NT hash, which began life as an NTLM response key, is being promoted into Kerberos as a long-term encryption key. The naming credit is socially distributed -- Metcalf, Delpy, Duckwall, and Mimikatz's own command group all carry traces of it -- so this article uses Metcalf's reference as the canonical practitioner explainer rather than as a single inventor citation.</Sidenote>

The DigiNotar incident in September 2011 is the first publicly attributed criminal use of Mimikatz, four months after Delpy's first public release. The Dutch certificate authority DigiNotar -- founded 1998, acquired by VASCO in January 2011, hacked in June 2011, declared bankrupt in September 2011 [@wikipedia-diginotar] -- was used to issue hundreds of fraudulent certificates that were then used in man-in-the-middle attacks on Iranian Gmail users [@wikipedia-diginotar] [@fox-it-operation-black-tulip].

Greenberg's Wired profile records that Delpy was told by the breach investigators that Mimikatz had been used during the intrusion [@wired-greenberg-mimikatz]. The single-source attribution warrants a hedge -- Greenberg's source is Delpy himself, quoting investigators -- but the underlying breach timeline is solid.

<Aside label="The Moscow hotel">
The decision to open-source Mimikatz on April 6, 2014 is dated by the GitHub repository banner: `mimikatz 2.0 alpha (x86) release "Kiwi en C" (Apr  6 2014 22:02:03)` [@mimikatz-github]. The precipitating event, as Delpy told Wired, was a trip to Moscow: he returned to his hotel room to find a stranger at his laptop; a second man approached him in the lobby that evening and demanded source code on a USB stick. He decided defenders needed the source as much as the attackers already did, and pushed it to GitHub when he got home [@wired-greenberg-mimikatz].
</Aside>

By 2014, the credential-replay family had three generations -- Pass-the-Hash, Pass-the-Ticket, Overpass-the-Hash -- and Microsoft's only documented response was a forty-page PDF. The next section is what that PDF said, and why documentation alone cannot end an attack class.

## 5. Documentation Is Not Defense

By December 2012, Microsoft had a problem. Duckwall and Campbell had just shipped a Black Hat USA paper titled "Still Passing the Hash 15 Years Later" [@duckwall-campbell-bh2012]. Mimikatz was eighteen months old. The institutional position that Pass-the-Hash was a "post-compromise issue" -- the line Microsoft had held since 1997 -- was no longer survivable in public.

The institutional response came in two waves. *Mitigating Pass-the-Hash Attacks and Other Credential Theft*, version 1, shipped in late 2012 (most practitioner secondaries place it in December 2012; no primary Microsoft URL with a verifiable v1 timestamp survives today).

Version 2 followed in July 2014, extending the v1 playbook with the new defensive surfaces that shipped in Windows 8.1 and Windows Server 2012 R2: [Protected Users](/blog/who-is-allowed-to-log-in-where-the-kdc-side-answer-to-creden/) as a deployable security group, Restricted Admin RDP as a default-available feature, LSA Protection (RunAsPPL) as a registry-toggleable defense, and Authentication Policies and Silos as KDC-side restrictions [@ms-download-mitigating-pth-v2]. The two whitepapers are the closest thing the industry got to an institutional Microsoft acknowledgment that Pass-the-Hash was a load-bearing operational problem requiring a defensive playbook rather than a patch.

What did the playbook recommend? Three orthogonal stopgaps, each with a published bypass.

**Protected Users** (Windows Server 2012 R2). A security group whose membership bans, on the DC side, NTLM authentication, DES and RC4 Kerberos pre-authentication, and Kerberos unconstrained delegation; and, on the device side, NTLM caching of the user's plaintext credentials or NTOWF and Kerberos DES/RC4 long-term keys. Member TGTs are capped at 240 minutes (four hours) with no renewal [@ms-protected-users]. Documented bypasses: requires explicit opt-in per account, breaks any service that depended on unconstrained delegation, does not apply to computer accounts or service accounts by default, and has no effect on Kerberos AES-key extraction from LSASS (since AES keys are not banned; only RC4 is).

**Restricted Admin RDP** (introduced in Windows 8.1 / Server 2012 R2 RTM, October 2013; backported to Windows 7 / Server 2008 R2 / Windows 8 / Server 2012 by KB2871997 on May 13, 2014 [@ms-kb2871997-may2014]). An opt-in RDP mode that authenticates to the target without sending credentials, so a compromised target cannot harvest the RDP user's hash from its own LSASS. Documented bypass: opt-in per session, applies only to RDP, leaves SMB, WMI, and RPC unprotected. And it *enables* Pass-the-Hash for RDP -- the BloodHound `CanRDP` edge documents the abuse path with the exact Mimikatz command for injecting a stolen NT hash into `mstsc.exe /restrictedadmin` [@bloodhound-canrdp].

**LSA Protection / RunAsPPL** (Windows 8.1). A registry toggle that marks LSASS as a [Protected Process Light](/blog/protected-process-light-when-the-administrator-isnt-enough/), so non-PPL processes (including unsigned admin tools) cannot open it with `PROCESS_VM_READ`. Documented bypass: any signed kernel driver -- including loadable third-party drivers -- can still read PPL memory, and an attacker with local admin can load such a driver. The itm4n analysis includes the verbatim Mimikatz output where `sekurlsa::logonpasswords` returns access-denied against a PPL-marked LSASS, and shows that an attacker who loads a signed driver via the BYOVD pattern ("bring your own vulnerable driver") or escalates to kernel mode bypasses the marking. itm4n's framing -- "Credential Guard and LSA Protection are actually complementary" [@itm4n-lsass-runasppl] -- is also the prediction: PPL is part of the answer, but only when paired with the architectural pivot still to come.

<Definition term="Protected Users security group">
A Windows Server 2012 R2 security group whose membership applies a set of restrictions, enforced jointly by the device and the domain controller, that block the most commonly extracted long-term credential material: no NTLM, no Kerberos RC4 or DES pre-auth, no unconstrained delegation, no NT-hash caching, and a 240-minute TGT lifetime with no renewal [@ms-protected-users].
</Definition>

The structural point is this. Documentation tells administrators *what to do*. It does not prevent the underlying LSASS-resident credential extraction. Every defense documented in v1 and v2 of the Mitigating-PtH whitepapers is bypassable, with a known and published technique, on any system where the attacker already has local administrator -- and local administrator is exactly what Pass-the-Hash exploitation *already implies*. The defender's win condition is to keep the attacker from ever getting to local admin in the first place; once they have it, every documented mitigation is a speed bump rather than a wall.

> **Note:** The 2012-2014 era's load-bearing failure mode was assuming that telling administrators where credentials *should* live would prevent extraction from where they *do* live. Protected Users, Restricted Admin RDP, RunAsPPL, and Authentication Silos are all useful, and stacked together they raise the cost of post-admin exploitation. None of them moves the credential out of the address space the attacker can read.

<Aside label="The Mitigating-PtH v3 that never shipped">
A common secondary characterisation cites a "v3 2017" of the whitepaper alongside v1 and v2. That document does not exist in Microsoft Download Center ID 36036; the page lists Version 2.0; the 2023 Wayback snapshot of the same Download Center page records Date Published 7/7/2014, while the live page now shows a 2024 republication date for the same Version 2.0 PDF without a version bump [@ms-download-mitigating-pth-v2]. The Download Center page carries v2 metadata only -- v1's late-2012 date is sourced through contemporary practitioner literature rather than a primary Microsoft timestamp. After 2014 the post-v2 institutional documentation moves to the Microsoft Learn Credential Guard page rather than to a third whitepaper revision -- a structural choice, because by 2015 the architectural answer has shifted from prose to code.
</Aside>

By mid-2014 Microsoft's institutional position was that the protocol-level fix was unavailable and the architectural answer would need to *relocate the credentials*. If credentials cannot stay in LSASS where every admin process can read them, the credentials have to be moved to a place admin processes cannot read. That insight produces Credential Guard.

## 6. Credential Guard and the Architectural Pivot

On July 29, 2015, Microsoft shipped Windows 10 Enterprise [@ms-lifecycle-w10-enterprise]. Hidden in the RTM build was the first defense in the credential-replay lineage that wasn't documentation: hardware-rooted isolation. They called it Credential Guard.

The architecture is worth unpacking carefully, because every later generation of the family is best read as "what does this attack do to the assumptions Credential Guard makes?"

Credential Guard runs on top of Virtualization-Based Security. The Windows hypervisor partitions user mode into two virtual trust levels. VTL0 is the normal user partition: normal user-mode processes, including the normal LSASS, and the normal kernel. VTL1 is the isolated user partition: a small set of *trustlets*, signed user-mode processes the hypervisor protects from VTL0 inspection. Credential Guard's trustlet is LSAISO ("LSA Isolated"), a stripped-down clone of the LSA credential cache holding the material Microsoft wants out of VTL0. Hypervisor-enforced Code Integrity (HVCI) below enforces W^X on the VTL0 kernel, blocking kernel-mode bypasses that would otherwise read VTL1 memory directly.

<Definition term="Virtualization-Based Security (VBS)">
The Windows architecture that runs a Type-1 hypervisor below the normal Windows kernel and partitions user mode into VTL0 (the normal partition) and VTL1 (the isolated partition). VTL1 hosts trustlets that the hypervisor protects from VTL0 inspection, even from kernel-mode VTL0 code. VBS is the substrate for Credential Guard, HVCI, the System Guard secure-launch chain, and the secure kernel.
</Definition>

<Definition term="Credential Guard">
The Windows feature that relocates NT hashes, Kerberos TGT session keys, and "credentials stored by applications as domain credentials" from the in-VTL0 LSASS to the in-VTL1 LSAISO trustlet, so that the credential cache is unreadable from any VTL0 process or driver. Shipped in Windows 10 RTM (July 2015); default-enabled on hardware-eligible domain-joined non-DC systems in Windows 11 22H2 (September 2022) [@ms-learn-credential-guard].
</Definition>

<Definition term="LSAISO trustlet">
The isolated-user-mode LSA process (`lsaiso.exe`) that holds Credential Guard's protected credential material. Runs in VTL1, unreadable from VTL0 kernel or user processes. Communicates with the VTL0 LSASS through a small RPC surface for authorised authentication operations only.
</Definition>

What does Credential Guard isolate? The Microsoft Learn page is unambiguous: "Credential Guard prevents credential theft attacks by protecting NTLM password hashes, Kerberos Ticket Granting Tickets (TGTs), and credentials stored by applications as domain credentials." [@ms-learn-credential-guard] Those three categories are also the three categories the previous three generations of the family targeted. Pass-the-Hash hits NTLM password hashes. Pass-the-Ticket hits Kerberos TGTs. Overpass-the-Hash hits NTLM password hashes promoted into Kerberos. Credential Guard moves all three out of VTL0 LSASS into VTL1 LSAISO. On a hardware-eligible domain-joined Windows 10/11 system with Credential Guard enabled, all three attacks return empty buffers.

The institutional importance of the change is that under Microsoft's own *Windows Security Servicing Criteria*, Credential Guard is a *security boundary* -- which means a bypass is a CVE-class vulnerability rather than a documentation gap.

The criteria's load-bearing definitions: "A security boundary provides a logical separation between the code and data of security domains with different levels of trust" and "Does the vulnerability violate the goal or intent of a security boundary or a security feature?" [@msrc-windows-servicing-criteria] Pre-2015 Pass-the-Hash defenses were documentation; Credential Guard is the first defense the criteria treats as CVE-class under the boundary "admin -> VBS (LSAISO trustlet)."

<Mermaid caption="Credential Guard architecture: NT hashes and TGT session keys move from LSASS in VTL0 to the LSAISO trustlet in VTL1; the hypervisor enforces the boundary, and even kernel-mode VTL0 code cannot read VTL1 memory.">
flowchart TD
    subgraph VTL0[VTL0 normal partition]
        A[User processes]
        B[LSASS]
        K[VTL0 kernel]
    end
    subgraph VTL1[VTL1 isolated partition]
        L[LSAISO trustlet]
        SK[Secure kernel]
    end
    H[Hypervisor]
    A --> B
    K --> B
    B -- authorised RPC only --> L
    H --> VTL0
    H --> VTL1
    SK --> L
    K -. blocked by HVCI .-> L
</Mermaid>

What does Credential Guard *not* isolate? This is the load-bearing question for the rest of the article. The same Microsoft Learn page enumerates four caveats, each verbatim.

First, the Active Directory database and the SAM. "Credential Guard doesn't provide protections for the Active Directory database or the Security Accounts Manager (SAM)." [@ms-learn-credential-guard] This is the [DCSync](/blog/two-checkmarks-and-the-keys-to-the-kingdom-how-active-direct/) gap: an attacker with the right replication privileges can ask a DC to hand over every hash in the directory, and Credential Guard cannot intervene because the data is being released through a legitimate, authorised API rather than being read from LSASS.

Second, domain controllers. "Enabling Credential Guard on domain controllers isn't recommended. Credential Guard doesn't provide any added security to domain controllers." [@ms-learn-credential-guard] The KDC must read the krbtgt account's long-term key in cleartext to issue tickets; the architectural exception is intrinsic to Kerberos rather than a Microsoft oversight.

Third, application credentials outside the "domain credentials" scope. Certificate private keys held by CryptoAPI key containers, third-party authentication package secrets, and -- the one this article eventually argues is the most consequential -- the Primary Refresh Token material held by the CloudAP authentication plug-in, are all out of scope by construction.

Fourth, and most importantly, the institutional acknowledgment of the supersession pattern. Microsoft Learn reproduces it verbatim on the same page, the prophecy the rest of this article spends its time documenting being fulfilled:

<PullQuote>
"While Credential Guard is a powerful mitigation, persistent threat attacks will likely shift to new attack techniques, and you should also incorporate other security strategies and architectures." -- Microsoft Learn, *Credential Guard overview* [@ms-learn-credential-guard]
</PullQuote>

That sentence, written about the 2015 Credential Guard architecture, accurately predicts the 2021-2022 shift to Pass-the-Certificate and the 2020-present shift to Pass-the-PRT. It is Microsoft's own structural prediction that the family will continue to evolve to the next artefact Credential Guard's verbatim scope does not cover. The rest of this article reads as the unfolding of that prediction.

<Aside label="Why DCs do not get Credential Guard">
The Kerberos KDC must read the krbtgt account's long-term key to encrypt the TGT issued in every AS-REP. That key has to be available to the LSA process in cleartext, on every DC, on every ticket issuance, by protocol. Putting krbtgt behind LSAISO would mean issuing every TGT through an inter-trust-level RPC call -- a non-trivial performance penalty on every authentication in an Active Directory forest -- and would not actually close the architectural gap, because the trustlet itself would still need to do the cleartext work that LSASS does today. The exception is honest about an architectural reality rather than concealing it.
</Aside>

PPL and Credential Guard are *complementary*, not alternatives. itm4n's analysis [@itm4n-lsass-runasppl] makes the case carefully: RunAsPPL raises the bar from "any admin process can read LSASS" to "any signed driver can read LSASS," and Credential Guard closes the signed-driver bypass with hardware-rooted hypervisor isolation. They stack. The 2026 best-practice Windows endpoint has both turned on.

The default-enablement window shows how long this took to land. Credential Guard shipped enabled-by-policy in Windows 10 RTM in 2015, but did not become *default-enabled on hardware-eligible domain-joined non-DC systems* until Windows 11 22H2 in September 2022 [@ms-learn-credential-guard]. Seven years of uneven deployment.

> **Note:** Four residuals from the Microsoft Learn page: the Active Directory database and the SAM are out of scope; domain controllers are out of scope by recommendation; application credentials outside the "domain credentials" category (certificates, CloudAP material, third-party authentication packages) are out of scope by construction; and persistent threats are *expected* to shift to new attack techniques. Each residual maps to a later generation of this article: AD database -> DCSync; certificates -> Pass-the-Certificate; CloudAP -> Pass-the-PRT.

Each new credential type needs its own isolation boundary. Credential Guard isolates NT hashes and TGT session keys. It does not isolate certificate private keys, because in 2015 nobody was replaying certificates at scale. And it does not isolate the Primary Refresh Token, because in 2015 the Primary Refresh Token did not yet exist.

> **Key idea:** Each new credential type needs its own isolation boundary. The pattern is reusable but does not transfer automatically -- and the gap between "what fits in the boundary" and "what credentials Windows actually uses" is exactly the territory where the next attack generation grows.

## 7. Pass-the-Certificate: The Predictable Response

If the NT hash is isolated and RC4-HMAC is banned, what is the next long-term credential Windows accepts? The answer was hiding in plain sight: every Active-Directory-integrated enterprise had been running Microsoft's PKI since 2008, and almost every PKI deployment had at least one template-level catastrophe.

On June 17, 2021, Will Schroeder and Lee Christensen posted "Certified Pre-Owned" on Medium, with the accompanying 143-page whitepaper [@specterops-certified-pre-owned] [@specterops-certified-pre-owned-pdf]. The post named ESC1 through ESC8 in a single document, with paired DETECT and PREVENT recommendations, and shipped three pieces of tooling at the same Black Hat USA 2021 cycle: Certify (offensive enrollment), ForgeCert (golden-certificate forging using a stolen CA private key), and PSPKIAudit (defensive enumeration). The Medium post's tone was unsubtle:

<PullQuote>
"Of note, nearly every environment with AD CS that we've examined for domain escalation misconfigurations has been vulnerable. It's hard for us to overstate what a big deal these issues are." -- Will Schroeder and Lee Christensen, *Certified Pre-Owned* [@specterops-certified-pre-owned]
</PullQuote>

The [ESC catalog](/blog/certified-pre-owned-ad-cs-and-active-directorys-second-trust/) organises certificate misconfigurations by the abuse primitive they enable. ESC1 is the canonical example: a published certificate template that allows the enrollee to supply the Subject Alternative Name, contains a client-authentication Extended Key Usage, has permissive enrollment rights, and has no effective approval gates.

An attacker who can enroll for such a template requests a certificate naming a victim principal -- say, the domain administrator -- in the SAN. The certificate's private key is now the attacker's. PKINIT-authenticate to the KDC with that certificate, and the KDC issues a TGT for the named principal. Domain escalation, in three commands.

<Definition term="Active Directory Certificate Services (AD CS)">
Microsoft's enterprise PKI. Issues X.509 certificates from administrator-defined templates that pin a certificate's permitted uses (Extended Key Usages), its enrollment authorisation rules, its subject and SAN generation policy, and its revocation behaviour. Ships as a Windows Server role; deployed in essentially every Active-Directory-integrated enterprise.
</Definition>

<Definition term="PKINIT">
Kerberos pre-authentication using a certificate's private key in place of a long-term symmetric key. Specified by RFC 4556 (L. Zhu and B. Tung, Microsoft and Aerospace, June 2006) [@rfc-4556]. The certificate's UPN SAN (or its dNSHostName for computer accounts) maps the certificate to the principal whose TGT the KDC will issue. PKINIT is the protocol surface most commonly exercised by Pass-the-Certificate against domain controllers that support certificate-based authentication.
</Definition>

<Definition term="Schannel">
The Windows TLS implementation. Supports TLS client-certificate authentication, which authenticated LDAPS uses. When a domain controller does not support PKINIT (Schroeder + Christensen documented this case in the original catalog; AlmondOffSec built tooling for it), an attacker can authenticate to LDAPS over Schannel with a stolen client certificate and perform high-privilege LDAP operations without traversing the KDC.
</Definition>

<Definition term="Pass-the-Certificate">
The technique of authenticating to Active Directory with a stolen X.509 certificate's private key, via PKINIT to the KDC or via Schannel client-certificate authentication to LDAPS. Named in this form by Yannick Méheut's PassTheCert tool and blog post (May 2022) [@almondoffsec-passthecert-github] [@almondoffsec-passthecert-blog], though the technique class was catalogued by Schroeder and Christensen eleven months earlier [@specterops-certified-pre-owned]. Tool of record: Certify (C#), Certipy (Python, ESC1-ESC16 [@certipy-wiki-privesc]), and Rubeus PKINIT mode.
</Definition>

<Mermaid caption="ESC1 / Certifried: enrol for a template-misconfigured certificate naming a victim principal in the SAN, then PKINIT-authenticate to the KDC and receive a TGT for that principal.">
sequenceDiagram
    participant Atk as Attacker (user)
    participant CA as Enterprise CA
    participant KDC
    Atk->>CA: Enrol for template ESC1, SAN field set to Domain Administrator
    CA-->>Atk: X.509 certificate plus private key
    Note over Atk: Now holds a certificate naming the victim principal
    Atk->>KDC: AS-REQ with PKINIT pre-auth using the stolen private key
    KDC->>KDC: Validate certificate, map SAN to victim principal
    KDC-->>Atk: AS-REP with TGT for victim principal
    Atk->>KDC: TGS-REQ for any service
    KDC-->>Atk: TGS-REP service ticket
</Mermaid>

The CVE-class case lands on May 10, 2022. Oliver Lyak of IFCR discloses Certifried, CVE-2022-26923, an Active Directory Domain Services elevation-of-privilege vulnerability in which the combination of three Microsoft defaults -- `ms-DS-MachineAccountQuota = 10` (any authenticated user can add up to 10 computer accounts to the domain), the default Machine template (which a computer account can enroll for), and the KDC's permissive `dNSHostName`-to-SAN binding logic -- lets any authenticated user obtain a certificate for any computer account in the forest, including domain controllers.

PKINIT-authenticate as a domain controller, and the KDC issues you a TGT for the DC; from there, DCSync extracts the krbtgt key and the domain is yours. Domain escalation from any authenticated user, with the only required misconfiguration being *Microsoft's defaults* [@nvd-cve-2022-26923] [@semperis-cve-2022-26923].

The defensive response shipped the same day. Microsoft published KB5014754 on May 10, 2022 -- coordinated disclosure, with the patch shipping in the same window as the CVE -- introducing a new X.509 extension `szOID_NTDS_CA_SECURITY_EXT` (OID `1.3.6.1.4.1.311.25.2`) that carries the requesting principal's SID at certificate issuance.

The KDC's new strong-mapping logic refuses certificates that fail one of four conditions: the SID extension is present and matches; an issuer-serial mapping is present; a Subject Key Identifier mapping is present; or a SHA1-public-key mapping is present. The KB's load-bearing sentence: "In Full Enforcement mode, if a certificate fails the strong (secure) mapping criteria (see Certificate mappings), authentication will be denied." [@ms-kb5014754]

<Sidenote>The KB5014754 change-log preserves a forensic artefact of the coordinated-disclosure timeline that is easy to miss. The current change-log row reads, verbatim: "9/10/2025 - Corrected the Enforcement mode date from September 10, 2025, to September 9, 2025." [@ms-kb5014754] An off-by-one date correction, captured in the public KB. The kind of detail that only shows up when a small team has had to ship a date repeatedly against a multi-year audit-to-enforcement schedule.</Sidenote>

The enforcement timeline tells you how long even a CVE-class fix took to drive through deployment. Audit mode (May 10, 2022). Enforcement mode with a registry escape that admins could use to revert to compatibility (February 11, 2025). Final cutover with no escape (September 9, 2025) [@ms-kb5014754]. Three years and four months between the patch and the day Microsoft stopped accepting non-strong certificate mappings. Faster than the Credential Guard default-enablement window, but still measured in years.

The naming history deserves a disambiguation. The *catalog* -- ESC1 through ESC8, the full taxonomy of AD CS misconfigurations -- is Schroeder and Christensen, June 2021 [@specterops-certified-pre-owned]. The *wire-level technique name* "Pass-the-Certificate" is popularised by AlmondOffSec's PassTheCert PoC (Yannick Méheut, May 4, 2022), which targets LDAP/S via Schannel client-cert authentication when PKINIT is unavailable, as a fallback path for environments where domain controllers do not support certificate-based Kerberos pre-authentication [@almondoffsec-passthecert-github] [@almondoffsec-passthecert-blog]. The blog post documents the `KDC_ERR_PADATA_TYPE_NOSUPP` error path that diverts the PKINIT-blocked attacker into Schannel.

<Sidenote>The AlmondOffSec blog post acknowledges the social attribution of the term: "Note for Googlers: this tool extends the notion of Pass the Certificate, thus dubbed by @\_nwodtuhs in his Twitter thread on AD CS and PKINIT." [@almondoffsec-passthecert-blog] The technique name is socially attributed; the catalog framing is editorial.</Sidenote>

> **Note:** A common shorthand says that KB5014754 bound NTOWFs to Kerberos, and that this is what forced attackers to shift to certificates. That arrow runs backwards in time. KB5014754 is the *response* to Certifried, not the cause of Pass-the-Certificate. The technique class was catalogued by Schroeder and Christensen in June 2021, eleven months before KB5014754 shipped, and the PassTheCert tool that gave the technique its wire-level name appeared six days before Certifried's disclosure. The shift to certificates happened because certificates were the next long-term credential type Credential Guard did not isolate.

What does KB5014754 actually close? Three specific CVEs in the Certifried family: CVE-2022-26923 (the original SID-spoof Certifried disclosure), CVE-2022-26931 (UPN / sAMAccountName collision spoof), and CVE-2022-34691 (the certificate-pre-dating-account-creation case) [@ms-kb5014754]. What does it *not* close? The broader ESC2 through ESC8 catalog, which is administrative hardening rather than CVE-class control. And it does not close ESC9 through ESC16, which were enumerated *after* KB5014754 shipped and include cases like the `CT_FLAG_NO_SECURITY_EXTENSION` template flag that *exempts* a template from the very SID extension the patch introduced [@specterops-certs-patches-2022] [@certipy-wiki-privesc].

The current state of the catalog: as of the 2025 Certipy 5.x documentation, ESC1 through ESC16 is the practitioner enumeration, with each technique characterised by a template-level, ACL-level, CA-administrator-level, NTLM-relay-level, SID-extension-level, or mapping-level abuse primitive [@certipy-wiki-privesc]. Microsoft Defender for Identity's certificates posture assessment tracks nine distinct ESC numbers as of the 2025 documentation -- ten posture assessments, because ESC4 owner and ESC4 ACL are tracked as separate sub-cases (ESC1, ESC2, ESC3, ESC4 owner, ESC4 ACL, ESC6 preview, ESC7, ESC8, ESC11, ESC15) [@ms-defender-id-certs]. Same pattern as Pass-the-Hash in 2012-2014: documentation tells administrators what to do; the structural exposure is downstream of how each enterprise built its templates years earlier.

| ESC ID | Class | Closed by KB5014754 |
| --- | --- | --- |
| ESC1 | Template -- enrollee supplies SAN, client-auth EKU, permissive enrollment | Partial: SID extension binds requester at issuance; ESC1 still works if the SID extension is absent |
| ESC2 | Template -- enrollee supplies SAN, Any-Purpose or no EKU | No -- administrative hardening |
| ESC3 | Template -- Certificate Request Agent enrollment-agent abuse | No -- administrative hardening |
| ESC4 | ACL -- writeable template configuration | No -- administrative hardening |
| ESC6 | CA -- `EDITF_ATTRIBUTESUBJECTALTNAME2` flag set on the CA | No -- CA-level hardening (was MS22-23, separately patched) |
| ESC8 | NTLM relay -- HTTP enrolment endpoints reachable from low-privilege contexts | No -- relay-defence hardening |
| ESC9 | Template -- `CT_FLAG_NO_SECURITY_EXTENSION` exempts template from the SID extension | No -- by design |
| ESC11 | NTLM relay -- ICPR RPC endpoint without sign / seal | No -- relay-defence hardening |
| ESC16 | CA -- security-extension disabled at the CA level | No -- CA-level hardening |

*Table 1. A representative slice of the ESC1-ESC16 catalog showing what KB5014754 closes and what remains administrative hardening [@specterops-certify-wiki] [@certipy-wiki-privesc] [@specterops-certs-patches-2022].*

KB5014754 is a CVE-class fix for one sub-case. The broader ADCS catalog is administrative hardening. And the *next* credential type -- the one that defeats Credential Guard, Protected Users, and KB5014754 simultaneously -- was already shipping in commodity Mimikatz code by August 2020.

## 8. Pass-the-PRT: The CloudAP Frontier

By August 2020, Microsoft had two architectural defenses against credential replay that the security industry actually trusted: Credential Guard for local Active Directory credentials, and (eighteen months later) KB5014754 for the certificate-replay class. Then a Dutch security researcher named Dirk-jan Mollema published a 21-minute read that broke both, in the same paragraph, by stealing a different credential type.

The credential is the [Primary Refresh Token](/blog/inside-the-primary-refresh-token-the-cryptographic-seam-betw/). The two foundational write-ups are Mollema's "Abusing Azure AD SSO with the Primary Refresh Token" [@mollema-prt-abusing] and its follow-on "Digging further into the Primary Refresh Token" [@mollema-prt-digging], both posted in August 2020. The second post is the single most-cited primary source in the fifth generation of the family. Read it once and you understand why Pass-the-PRT is structurally different from everything that came before.

A PRT is a JSON Web Token refresh token issued by Microsoft Entra ID (formerly Azure AD) to Entra-joined or Hybrid-joined Windows devices, paired with a session key (HMAC-SHA256 secret) and bound to a device key registered at device join.

The Microsoft Entra documentation describes the artefact precisely: "A Primary Refresh Token (PRT) is a key artifact of Microsoft Entra authentication ... Once issued, a PRT is valid for 90 days and is continuously renewed as long as the user actively uses the device." [@ms-entra-concept-prt] On Windows the PRT is renewed every four hours during sign-in. The device-key registration binds the PRT to the device that owns it -- and is what an attacker has to work around to use a stolen PRT on a different device.

<Definition term="Primary Refresh Token (PRT)">
The Microsoft Entra-issued long-lived refresh token for SSO on Entra-joined or Hybrid-joined Windows devices. Carries a session key (HMAC-SHA256) used to sign per-request `x-ms-RefreshTokenCredential` cookies, and binds to a device transport key registered at device join. Default lifetime is 90 days with sliding renewal as long as the user actively uses the device; an inactivity timeout governs when an idle PRT must be re-acquired [@ms-entra-concept-prt]. The PRT is the load-bearing artefact for Single Sign-On to every Entra-integrated resource the device's user can reach.
</Definition>

<Sidenote>The PRT default lifetime is 90 days per the Microsoft Entra documentation, with renewal every four hours during Windows sign-in [@ms-entra-concept-prt]. The 14-day figure that sometimes appears in secondary references is the inactivity timeout on certain device states, not the PRT lifetime itself; this article uses the Microsoft Entra documentation's value to avoid the conflation.</Sidenote>

Where the PRT *lives* is what makes the rest of the architecture work -- and what makes it vulnerable. The PRT is *hybrid*: issued and revoked cloud-side by Entra ID, stored and used client-side via the **CloudAP** authentication plug-in, which is loaded into LSASS like any other Windows authentication package.

The load-bearing structural fact is that CloudAP is *in LSASS*, not behind the LSAISO trustlet. Credential Guard's classical isolation does not extend to the CloudAP plug-in's working memory, because Credential Guard's scope is the three credential categories its design predates -- NT hashes, Kerberos TGTs, and "domain credentials" -- and the PRT is none of those [@mollema-prt-abusing].

<Definition term="CloudAP (Cloud Authentication Provider)">
The Windows authentication package (`cloudap.dll`, loaded into LSASS) that handles authentication against Microsoft Entra ID for Entra-joined and Hybrid-joined devices. Holds the device's Primary Refresh Token, its session key, and the derived material used to sign per-request PRT cookies. Sits inside LSASS in VTL0, *not* inside the LSAISO trustlet in VTL1; Credential Guard does not currently extend its isolation to CloudAP's working memory.
</Definition>

The mechanism, as Mollema and Delpy developed it through the second half of 2020, runs as follows. Mimikatz `dpapi::cloudapkd /unprotect` extracts the PRT (the encrypted-by-Entra refresh-token blob) and the session key from CloudAP's working memory.

The attacker constructs an `x-ms-RefreshTokenCredential` JWT carrying the PRT in the `refresh_token` claim, `is_primary: true`, and a `request_nonce` obtained by an unauthenticated POST against the Entra ID v1 token endpoint at `https://login.microsoftonline.com/common/oauth2/token` with form-encoded body `grant_type=srv_challenge` (the server-challenge nonce pattern used by the ROADtools `roadtx prt` reference implementation; the response is a JSON object with a `Nonce` field). The signature is HMAC-SHA256 over the JWT under the session key. The completed cookie is presented to `login.microsoftonline.com` from any machine, and Entra ID returns access and refresh tokens for any resource the original user can reach. Mollema's second post describes the collaboration that built the tooling:

<PullQuote>
"Around the same time Benjamin Delpy took up my 'challenge' of recovering PRT data from `lsass` with mimikatz. We combined forces and ended up with tooling that is not only able to extract the PRT and associated cryptographic keys (such as the session key) from memory, but can also use these keys to create new SSO cookies or modify existing ones." -- Dirk-jan Mollema, *Digging further into the Primary Refresh Token* [@mollema-prt-digging]
</PullQuote>

The operational tooling closed quickly. Mollema's `roadtx prt` (part of ROADtools [@roadtools-github]) automates the full chain end-to-end -- extract the material, mint the cookie, complete the OAuth dance, hand the attacker an access token. The Mimikatz `dpapi::cloudapkd` command landed in the open-source repository the same window. Pass-the-PRT moved from research artefact to commodity tooling in months, not years.

<Mermaid caption="Pass-the-PRT cookie minting: extract PRT and session key from the CloudAP plug-in in LSASS, sign an x-ms-RefreshTokenCredential JWT, present to Entra ID from any device.">
sequenceDiagram
    participant Victim as Victim device (Entra-joined)
    participant Attacker as Attacker device
    participant Entra as login.microsoftonline.com
    Note over Victim: PRT plus session key held by CloudAP in LSASS
    Attacker->>Victim: mimikatz dpapi::cloudapkd /unprotect
    Victim-->>Attacker: PRT (encrypted blob) plus session key
    Attacker->>Entra: POST /common/oauth2/token grant_type=srv_challenge (unauthenticated)
    Entra-->>Attacker: request_nonce
    Note over Attacker: Build x-ms-RefreshTokenCredential JWT
    Note over Attacker: Sign HMAC-SHA256 with extracted session key
    Attacker->>Entra: POST /token with PRT cookie
    Entra-->>Attacker: Access and refresh tokens
    Attacker->>Attacker: Authenticate to any Entra resource as victim user
</Mermaid>

Now the analytical core. Pass-the-PRT defeats three Microsoft defenses *simultaneously*.

First, **Credential Guard** is out of scope. The CloudAP material is not an NT hash, not a Kerberos TGT, and not "credentials stored by applications as domain credentials" in the verbatim sense the Credential Guard documentation uses. Credential Guard's VBS-based isolation does not extend to CloudAP. The defense was designed in 2015 against the three credential types the family had then; the PRT is a credential type the family had not yet evolved into [@ms-learn-credential-guard].

Second, **KB5014754** is out of scope. The PRT cookie does not traverse the KDC's certificate-mapping logic at all; it is a JWT signed by an HMAC and authenticated at the Entra ID token endpoint. The strong certificate mapping that Microsoft drove through five years of audit-to-enforcement timeline has no relevance to a credential that never touches the KDC [@ms-kb5014754].

Third, **Protected Users** is out of scope. Protected Users is an Active-Directory-only construct, enforced on Windows Server domain controllers and on AD-joined member devices. Entra ID is a separate identity provider with separate enforcement; the 240-minute TGT cap, the NTLM ban, and the RC4 ban that Protected Users enforces simply do not apply [@ms-protected-users].

The TPM-sealing finding is where the architectural pattern becomes most precise. Microsoft began sealing the PRT session key to a [TPM-bound key](/blog/the-tpm-in-windows-one-primitive-twenty-five-years-and-the-c/) on TPM-2.0-eligible hardware -- a defense that, in principle, makes the raw session key cryptographically non-exportable. Mollema's finding in the August 2020 second post is that the seal does not close the attack, because CloudAP holds *derived* PRT-cookie-signing material in its own working memory in LSASS, and the attacker only needs the derived material:

<PullQuote>
"despite the session key of the PRT is stored in the TPM whenever possible, this doesn't prevent us from extracting the PRT and the required information to create SSO cookies. The result of this is that regardless of whether the PRT is protected by the TPM or not, with Administrator access it is possible to extract the PRT from LSASS and use the PRT on a different device than it was issued to." -- Dirk-jan Mollema, *Digging further into the Primary Refresh Token* [@mollema-prt-digging]
</PullQuote>

The structural reason the standard hardware-rooted defense pattern does not transfer: the attacker does not need the raw session key out of the TPM. They need only the in-memory derived material CloudAP itself uses to sign the cookies, and that derived material lives in the same address space Credential Guard does not isolate.

The TPM seals the key. CloudAP uses the key. Whatever CloudAP can read, an attacker with administrator and a memory-access primitive can also read. The defense pattern that worked for NT hashes (move them out of the address space) has not been applied to CloudAP -- and until it is, the TPM seal is a speed bump rather than a wall.

<RunnableCode lang="js" title="Anatomy of a Pass-the-PRT cookie (x-ms-RefreshTokenCredential JWT)">{`
// Pedagogical demonstration of the JWT structure used in Pass-the-PRT
// cookie minting. Uses placeholder values throughout; no real PRT material.

const base64url = (buf) => Buffer.from(buf).toString('base64')
  .replace(/=+$/, '').replace(/\\+/g, '-').replace(/\\//g, '_');

const header = { alg: 'HS256', ctx: 'AAAAAAAA' };
const payload = {
  // The PRT itself, an opaque refresh-token string Entra issued to the
  // device. In a real attack this comes from mimikatz dpapi::cloudapkd.
  refresh_token: 'AQABAAAAAAA...redacted...',
  // Marks this cookie as a primary refresh token cookie.
  is_primary: 'true',
  // Fresh nonce from an unauthenticated POST against the v1 token endpoint
  // at login.microsoftonline.com/common/oauth2/token with form body
  // grant_type=srv_challenge (returns JSON with Nonce field; the canonical
  // server-challenge pattern used by ROADtools roadtx prt).
  request_nonce: 'AwABAAEAAAAC...',
  iat: Math.floor(Date.now() / 1000),
};

// HMAC-SHA256 over the JWT under the session key recovered from CloudAP.
// Placeholder key for demonstration only.
const sessionKey = Buffer.alloc(32); // 32 bytes of zeros (fake)
const crypto = require('crypto');

const h = base64url(JSON.stringify(header));
const p = base64url(JSON.stringify(payload));
const sig = base64url(
  crypto.createHmac('sha256', sessionKey).update(h + '.' + p).digest()
);

console.log('Header segment:    ' + h);
console.log('Payload segment:   ' + p);
console.log('Signature segment: ' + sig);
console.log();
console.log('Full PRT cookie: ' + h + '.' + p + '.' + sig);
// In a real attack the attacker would now POST this as the
// x-ms-RefreshTokenCredential cookie to login.microsoftonline.com.
`}</RunnableCode>

The current partial mitigations are worth enumerating, because none of them closes the gap.

**Token Protection** (a [Conditional Access](/blog/who-decided-this-token-is-good-a-field-guide-to-conditional-/) session control) attempts to ensure that only device-bound sign-in session tokens are accepted at the Entra ID token endpoint for protected resources. The Microsoft Learn page is explicit about both the design intent and the deployment limits: "Token Protection is a Conditional Access session control that attempts to reduce token replay attacks by ensuring only device bound sign-in session tokens, like Primary Refresh Tokens (PRTs), are accepted by Microsoft Entra ID when applications request access to protected resources." [@ms-entra-token-protection] As of the current documentation the *supported resources* are five named applications: Exchange Online, SharePoint Online, Microsoft Teams, Azure Virtual Desktop, and Windows 365. Browser applications are out of scope; "Token Protection currently supports native applications only. Browser-based applications are not supported." [@ms-entra-token-protection] Most Entra-integrated SaaS is unbound.

**Continuous Access Evaluation** (CAE) shortens the window during which a stolen PRT is operationally usable, by allowing the token endpoint to revoke tokens within minutes of a triggering signal (password change, risk-based detection, conditional-access policy update) [@ms-entra-cae]. CAE is evaluation-time, not isolation. It shortens the window between extraction and detection-driven revocation; it does not prevent extraction.

**Hybrid-joined PRT renewal binding** partially closes the cross-tenant case for hybrid Azure AD Join configurations, but does not address the same-tenant Pass-the-PRT case that Mollema's original 2020 posts described [@ms-entra-hybrid-join-plan].

The institutional acknowledgment of the supersession pattern is the verbatim Microsoft Learn sentence already quoted in section 6 [@ms-learn-credential-guard]: written about the 2015 Credential Guard architecture, it accurately predicts the 2020 Pass-the-PRT shift. The credential-replay family has reached the point where *every Microsoft defense* in the on-prem stack runs in parallel against an attack the on-prem stack cannot reach.

> **Key idea:** Pass-the-PRT defeats Credential Guard, KB5014754, and Protected Users simultaneously because each defense was designed around a different long-term artefact, and the PRT is none of them. The architectural property -- a long-term authentication artefact reachable from the using process is replayable -- is unchanged. The artefact moved.

Six years after Mollema's disclosure, the TPM-resilience finding still holds. The CloudAP plug-in is still in LSASS. Credential Guard still does not extend its boundary. Pass-the-PRT remains the operational frontier in 2026.

## 9. The 5x5 Matrix and the Irregular Cadence

Five generations of attack. Five generations of defense. They map onto each other unevenly; the gaps are not five years.

The matrix below consolidates the lineage at a glance. Rows are the attack generations (in the order they entered the practitioner literature). Columns are the defense generations (in the order they shipped). Each cell records whether that defense closes that attack on a fully-deployed hardware-eligible 2026 Windows 11 endpoint with the control turned on. "Closed" means the attack returns empty buffers or fails authentication; "Partial" means the defense increases attacker cost or closes one sub-case; "Open" means the defense's design scope does not include that attack.

| Attack \\ Defense | Mitigating-PtH whitepapers (2012/2014) | Protected Users + RunAsPPL + Restricted Admin (2013-2014) | Credential Guard / LSAISO (2015) | KB5014754 strong mapping (2022) | Token Protection + CAE (2023-2025) |
| --- | --- | --- | --- | --- | --- |
| Pass-the-Hash (Ashton 1997, Ochoa 2008) | Open (documentation) | Partial (Protected Users members) | Closed (on enabled endpoints) | Open (not in scope) | Open (not in scope) |
| Pass-the-Ticket (Delpy 2011, Duckwall+Delpy 2014) | Open (documentation) | Partial (4-hour TGT cap for Protected Users) | Closed (TGT session key in LSAISO) | Open (not in scope) | Open (not in scope) |
| Overpass-the-Hash (Delpy / Metcalf 2014) | Open (documentation) | Partial (RC4 banned for Protected Users) | Closed (NT hash in LSAISO) | Open (not in scope) | Open (not in scope) |
| Pass-the-Certificate (Schroeder + Christensen 2021, Méheut 2022) | Open (documentation) | Open (cert keys outside scope) | Open (cert keys outside scope) | Partial (closes Certifried sub-case; ESC2-ESC16 remain) | Open (not in scope) |
| Pass-the-PRT (Mollema + Delpy 2020) | Open (Entra ID is separate IDP) | Open (Entra ID is separate IDP) | Open (CloudAP not in LSAISO) | Open (not in scope) | Partial (5 named resources; browser apps out of scope) |

*Table 2. The 5x5 attack/defense matrix. The union of every cell in the rightmost column of "Closed" entries is the set of attacks Microsoft's published 2026 defenses close on hardware-eligible non-DC endpoints with every control turned on; that set is precisely the first three rows.*

The matrix makes the structure visible. No single defense closes all attacks, and no single attack is closed by all defenses. The union of every defense closes Pass-the-Hash, Pass-the-Ticket, and Overpass-the-Hash on hardware-eligible non-DC Windows 10/11 systems with all controls enabled. It partially closes Pass-the-Certificate (for the Certifried sub-case) and partially closes Pass-the-PRT (for five named resources). Both of the most recent generations remain operationally open against any deployment that does not run those specific controls -- which is most deployments.

The cadence is just as uneven as the matrix. The original input that prompted this article claimed "every Windows defense against credential replay buys about five years before the attack class evolves to the next credential type." Memorable. Also wrong. The actual timeline produces gaps from eleven months to eleven years, with one negative interval:

- **1997 -> 2008** (eleven years) for the Samba-patch -> Windows-native pivot. Pass-the-Hash existed for over a decade as a Unix-side novelty before Ochoa's LSASS-injection insight made it Windows-native.
- **2008 -> 2011** (three years) for the Mimikatz Pass-the-Ticket extension. The same memory-access primitive that animated `IAM.EXE` was retargeted at a different artefact.
- **2012/2014 -> 2015** (one to three years) for the Mitigating-PtH whitepapers -> Credential Guard pivot. Documentation took a year and a half to ship; the architectural counter took another.
- **2021 -> 2022** (eleven months) for the AD CS catalog -> KB5014754 response. Coordinated disclosure compressed this gap; Certifried's CVE-class status forced a CVE-class response.
- **2020 -> 2025+** (open-ended) for Pass-the-PRT with no Credential-Guard-equivalent shipped. As of the Windows 11 25H2 cycle there is no public roadmap for VBS-class isolation of CloudAP material.

The most striking gap is the 2020/2021 *negative* interval. Pass-the-PRT (Mollema, August 2020) and the AD CS catalog (Schroeder + Christensen, June 2021) are siblings rather than sequential; Pass-the-PRT predates Pass-the-Certificate as a *named technique* by ten months, even though the article treats them as Generation 4 and Generation 5 in narrative order. The Generation N -> N+1 framing is *taxonomic*, not strictly chronological. The reader needs this distinction to read the lineage accurately: the attack class evolves along the architectural property, not along the calendar.

> **Note:** The "every Windows defense buys five years" framing is what you see if you select the cleanest pairings (Mitigating-PtH 2012/2014 to Credential Guard 2015 plus an artificial 2020-targeted "next attack"). When you look at the actual intervals, you see eleven years (1997-2008), three years (2008-2011), eleven months (2021-2022), and an open-ended interval (2020 onwards). The pattern is the architectural property persisting across artefact changes, not a calendar drumbeat.

The storage-class progression is the cleanest way to see the property hold across the lineage. Each row names the long-term artefact, where it lives, and which defense moved or shielded that storage class.

| Generation | Long-term artefact | Storage location | Defense that isolated it | Status 2026 |
| --- | --- | --- | --- | --- |
| 1A (1997 Samba) | NT hash (and LM hash) | Local SAM file on disk | "Do not store LAN Manager hash" policy (Vista default-on); SAM hash extraction still works | LM hash retired; NT hash extraction still works |
| 1B (2008 Windows-native) | NT hash | LSASS credential cache | Credential Guard relocates to LSAISO | Closed on Credential-Guard-enabled endpoints |
| 2 (2011 Mimikatz) | Kerberos TGT plus session key | LSASS Kerberos package | Credential Guard relocates to LSAISO | Closed on Credential-Guard-enabled endpoints |
| 3 (2014) | NT hash promoted to RC4-HMAC Kerberos key | LSASS, same buffer as Pass-the-Hash | Credential Guard relocates to LSAISO; KB5021131 makes AES the default | Closed on Credential-Guard-enabled endpoints; RC4 deprecated in favour of AES [@ms-kb5021131] |
| 4 (2021 AD CS catalog) | X.509 certificate private key | CryptoAPI key container, TPM, or smart card | TPM-resident or VSC-resident keys are cryptographically non-exportable; KB5014754 binds certificates to SIDs at issuance | Partial; ESC2-ESC16 misconfigurations remain administrative hardening |
| 5 (2020 Pass-the-PRT) | PRT session key plus derived signing material | CloudAP plug-in in LSASS (session key optionally TPM-sealed) | None deployed; Token Protection partially shields five resources | Open |

*Table 3. Storage-class progression. Each attack generation targets the next long-term artefact whose storage location is not isolated by the previous generation's defense.*

The matrix and the storage-class table jointly produce the structural prediction: each generation shifts to the next available long-term artefact whose storage class the latest defense does not isolate. The graph-based formalisation of these storage-class transitions is the BloodHound edge catalog -- the `HasSession`, `AdminTo`, and `CanRDP` family that operationalises "which principal can reach which credential from where" as a queryable property of an enterprise's directory [@bloodhound-edges]. The pattern predicts a Generation 6 outside whatever isolation scope arrives next.

The most credible candidate today is **Pass-the-DeviceKey**: extraction or abuse of the device transport key the PRT binds to, or of the CloudAP-derived material the cookie-signing process produces from it [@mollema-prt-phishing]. Mollema's 2023-2025 continuation work documents the underlying device-transport-key primitives in detail; the September 2025 Actor-tokens disclosure shows that cross-tenant abuse of related Entra-side material is also operational in the wild [@mollema-actor-tokens] [@mollema-federated-credentials].

<Mermaid caption="The credential-replay family tree: five attack generations and the paired defenses that responded to each. The tree is drawn taxonomically rather than chronologically -- Generation 5 (Pass-the-PRT) was actually published before Generation 4 (Pass-the-Certificate).">
flowchart TD
    A1[Pass-the-Hash 1A Samba<br/>Ashton 1997]
    A2[Pass-the-Hash 1B Windows-native<br/>Ochoa 2008]
    A3[Pass-the-Ticket<br/>Delpy 2011]
    A4[Overpass-the-Hash<br/>Delpy / Metcalf 2014]
    A5[Pass-the-Certificate<br/>Schroeder + Christensen 2021]
    A6[Pass-the-PRT<br/>Mollema + Delpy 2020]
    A7[Pass-the-DeviceKey forecast]
    D1[Mitigating-PtH whitepapers<br/>v1 2012, v2 2014]
    D2[Protected Users + RunAsPPL + Restricted Admin<br/>2013-2014]
    D3[Credential Guard / LSAISO<br/>2015, default 2022]
    D4[KB5014754 strong mapping<br/>2022, enforced 2025]
    D5[Token Protection + CAE<br/>2023-2025]
    D6[CloudAP isolation forecast]
    A1 --> A2
    A2 --> A3
    A3 --> A4
    A4 --> A5
    A4 --> A6
    A6 --> A7
    D1 --> D2
    D2 --> D3
    D3 --> D4
    D4 --> D5
    D5 -.- D6
    A2 -.- D1
    A2 -.- D2
    A3 -.- D3
    A4 -.- D3
    A5 -.- D4
    A6 -.- D5
    A7 -.- D6
</Mermaid>

If the pattern holds, Generation 6 is already in research literature. Mollema's 2023-2025 continuation work [@mollema-prt-phishing] [@mollema-federated-credentials] [@mollema-actor-tokens] documents the device-transport-key extraction primitives. The only things missing are the name and the commodity tool. The historical pattern says we probably get both before VBS-class CloudAP isolation ships.

## 10. Open Problems and the 2026-2030 Forecast

The credential-replay family has six load-bearing open problems in 2026. Each is structural rather than mathematical; the cryptographic primitives that would close them already exist.

The architectural lower bound -- the only configuration that closes the family in principle -- is the union of three things.

**Universal hardware-rooted non-extractable keys**: every long-term authentication artefact lives in a TPM, secure enclave, FIDO2 authenticator, or smart card, with key attestation, and is never released to software memory. **Universal protocol-layer token binding**: every issued token (Kerberos service ticket, OAuth refresh token, OIDC ID token, SAML assertion) is cryptographically bound to the device that requested it, and a verifier rejects any presentation from a non-bound device. **Universal continuous evaluation**: every protected resource queries the issuer in near-real-time and revokes within minutes of a triggering signal. Each component is deployed *somewhere*; none is deployed *everywhere*; no single vendor controls all three layers.

The five concrete open problems flow from the lower bound.

**The CloudAP isolation problem.** When does Microsoft extend VBS-class isolation to the CloudAP plug-in's working memory in LSASS? No public roadmap as of 2026. Until it ships, Pass-the-PRT remains operationally open against every Entra-joined Windows endpoint.

**The token-binding adoption problem.** Token Protection's verbatim 2026 scope is the five named resources enumerated in section 8 [@ms-entra-token-protection], which covers approximately five percent of typical Entra-integrated SaaS surface area; every other Entra-integrated resource accepts unbound tokens. The OAuth working group's RFC 9449 (DPoP, September 2023) standardises proof-of-possession at the OAuth layer [@rfc-9449], but adoption across SaaS providers and enterprise applications is uneven.

**The Pass-the-DeviceKey forecast.** Mollema's 2023-2025 continuation work exercises device-transport-key extraction primitives, federated-credential persistence on Entra applications, and cross-tenant Actor-token abuse [@mollema-prt-phishing] [@mollema-federated-credentials] [@mollema-actor-tokens]. The pattern of every previous generation predicts that whichever of these primitives commoditises first will be the next named "Pass-the-X" technique.

**The ESC9-ESC16 hardening problem.** The AD CS catalog has grown from 8 entries (June 2021) to 16 (current Certipy and Certify wikis [@certipy-wiki-privesc] [@specterops-certify-wiki]); most additions are misconfiguration-class rather than CVE-class. ESC9 specifically describes the `CT_FLAG_NO_SECURITY_EXTENSION` template flag that *exempts* a template from the very SID extension KB5014754 introduced -- so administrators who turn that flag on for legacy compatibility reasons silently re-enable the Certifried-class abuse path on those templates.

**Hardware-backed identity ubiquity.** When does the union of Pluton + FIDO2 + virtual smart cards + TPM key attestation eliminate the long-term software-extractable artefact class? Human interactive sign-in to Entra ID can already be fully passwordless on supported hardware. The long tail of service accounts, scheduled tasks, on-prem AD workflows, and legacy applications resists migration; the migration is a years-long enterprise project, not a feature flag.

**The non-Microsoft sibling lineages.** The credential-replay family is not Windows-specific. Okta session-cookie theft, Google IDP refresh-token reuse, Apple ASWebAuthSession token replay, and AWS STS session-token theft all face the same architectural property. An enterprise running Microsoft plus Okta plus Google inherits the union of every vendor's residual replay surface. The family generalises beyond Microsoft because the architectural property generalises beyond Microsoft.

<Aside label="The non-Microsoft analogues">
Okta's `sessionToken` and OAuth `refresh_token` artefacts live on the device that requested them, and have been used in commodity offensive tooling since at least 2022. Google's IDP refresh tokens face the same exposure surface on managed Chromebooks. Apple's ASWebAuthSession tokens are device-bound at the platform level, which closes the cross-device replay case but not the same-device extraction case. AWS STS session tokens are not device-bound at all. The credential-replay family is a property of long-term software-extractable authentication artefacts in general; this article is Windows-specific only because Windows has the longest documented lineage.
</Aside>

The institutional position is that the protocol-level fix is unavailable -- Microsoft's framing of Pass-the-Hash as a structural property of NTLM generalises directly to every later generation. A universal fix would require replacing every long-term software-extractable artefact globally with hardware-bound primitives, with mandatory token binding at every issuer and every resource server, with continuous evaluation everywhere. Each step is incrementally closable; the union has not yet closed for any deployment.

> **Note:** Universal hardware-rooted non-extractable keys, universal protocol-layer token binding, universal continuous evaluation. Each component is deployed somewhere; none is deployed everywhere. No single vendor controls all three layers.

The architectural property the family shares has held for twenty-nine years; the defensive lineage will not close it without making *every* long-term artefact live in hardware-rooted isolation that exceeds the host's privilege. Whether that happens in the next five years, the next ten, or the next twenty-five, is the open question the next chapter of this lineage will answer.

## 11. The 2026 Defender Playbook

Architectural humility does not mean defensive passivity. The 2026 estate is defensible against generations 1 through 3 and partially against generation 4; the playbook is to deploy every available control while reading Mollema's 2025 posts to know what's coming for generation 5 and beyond.

1. **Credential Guard everywhere it can run.** Hardware-eligible non-DC Windows 10/11 endpoints, with the four-residual disclosure (AD database, DCs, certificate keys, CloudAP) documented for the SOC so that detection engineering does not assume Credential Guard covers categories it explicitly excludes [@ms-learn-credential-guard].

2. **LSA Protection (RunAsPPL), UEFI-anchored** stacked underneath, per itm4n's "complementary" framing [@itm4n-lsass-runasppl]. The UEFI-anchored variant resists the registry-based bypass that a kernel-mode attacker can otherwise apply at boot.

3. **Authentication Silos and Protected Users for Tier-0 accounts.** Expect to encounter unconstrained-delegation breakage on legacy services and budget remediation; the 240-minute TGT cap is the lever that prevents long-lived Tier-0 ticket reuse [@ms-protected-users].

4. **KB5014754 strong-mapping enforcement** -- fully on by the September 9, 2025 cutover -- plus an annual certificate-template audit cycle against the ESC1-ESC16 catalog using Certipy or PSPKIAudit [@ms-kb5014754] [@certipy-wiki-privesc]. The audit is the load-bearing control because the strong-mapping fix only closes Certifried-class abuses; the template misconfigurations Schroeder and Christensen catalogued are still administrative responsibility.

5. **Conditional Access with Token Protection where supported** -- the five resources Microsoft Learn enumerates [@ms-entra-token-protection]. Device-bound sign-ins for privileged accounts; FIDO2 for human interactive sign-in. Know that the long tail of Entra-integrated SaaS does not enforce binding, and that a stolen PRT used against an unbound resource will still authenticate.

6. **PRT-extraction telemetry.** Detect CloudAP-plug-in token access from non-CloudAP processes; tie to Endpoint DLP; alert on out-of-band access to `cloudap.dll`-owned regions of LSASS memory. Mollema's `roadtx` and BARK produce signal patterns worth modelling.

7. **Mental model: assume the PRT is the next NT hash.** Architect today as if Credential Guard for CloudAP shipped tomorrow -- which means TPM-attested device joins as standard, FIDO2 for every human sign-in, hardware-backed identity for service accounts wherever the vendor supports it, and conditional access policies that treat unmanaged or non-attested devices as untrusted by default.

<Spoiler kind="solution" label="How to verify Credential Guard is actually running on a Windows 11 endpoint">
Open PowerShell as administrator and run:

`Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard | Format-List`

The result of interest is `SecurityServicesRunning`. A value of `1` in that list means Credential Guard is actively running (per the Win32_DeviceGuard documentation: `1 = Credential Guard`, `2 = HVCI`, `3 = System Guard secure launch`, etc.). `SecurityServicesConfigured` tells you what the policy intends; `SecurityServicesRunning` tells you what the hypervisor is actually enforcing right now. The two values disagree more often than you would expect, usually because the hardware did not meet a prerequisite at boot.
</Spoiler>

> **Note:** The minimum-viable layer: Credential Guard on every hardware-eligible non-DC endpoint, KB5014754 enforcement-mode certificate strong mapping with an annual ESC catalog audit, and PRT-extraction telemetry tied to a real detection workflow. The first two are commodity Microsoft features that close real attack classes today; the third is the only meaningful signal you can get on the attack class that none of the published defenses currently closes.

None of this closes Pass-the-PRT. All of it shortens the dwell time.

## 12. Frequently Asked Questions

<FAQ title="Frequently asked questions">
<FAQItem question="Doesn't Credential Guard protect against Pass-the-PRT?">
No. The Primary Refresh Token sits in the CloudAP plug-in, which is outside Credential Guard's verbatim three-credential scope -- see section 6 ("What does Credential Guard isolate?") and section 8 ("Pass-the-PRT defeats three Microsoft defenses simultaneously") for the full mechanism.
</FAQItem>

<FAQItem question="Was Pass-the-Hash invented by Mimikatz?">
No. The 1997 Ashton patch and the 2008 Ochoa Windows-native pivot are both pre-Mimikatz; see section 1 and section 3 for the full origin story. Mimikatz is the dominant *tool* (May 2011 first release) but it is not the *origin* of Pass-the-Hash.
</FAQItem>

<FAQItem question="Is the PRT a cloud-only thing?">
No. The PRT is *hybrid* -- issued and revoked cloud-side by Entra ID, but stored and used client-side via the CloudAP plug-in inside LSASS. See section 8 ("Where the PRT *lives*") for why this hybrid architecture is what makes Pass-the-PRT operationally tractable today.
</FAQItem>

<FAQItem question="Did KB5014754 kill Pass-the-Certificate?">
No. It closed the three Certifried-class CVEs (CVE-2022-26923, CVE-2022-26931, CVE-2022-34691) but not the broader ESC2 through ESC16 catalog. See section 7 ("What does KB5014754 actually close?") and Table 1 for the per-template breakdown.
</FAQItem>

<FAQItem question="Will FIDO2 or passkeys make all of this go away?">
For human interactive sign-in to Entra ID, mostly, if the entire enterprise migrates -- the FIDO2 authenticator holds a non-extractable private key in hardware, and the resulting authentication is bound to that key. For service accounts, scheduled tasks, on-prem Kerberos workflows, hybrid identity scenarios, and the long tail of legacy applications, no -- those paths still rely on long-term software-extractable artefacts (passwords, hashes, keys) by construction. The architectural counter is universal hardware-rooted non-extractable keys plus universal token binding plus universal continuous evaluation; the operational reality is partial coverage.
</FAQItem>

<FAQItem question="Did Microsoft ever ship a 'Mitigating Pass-the-Hash v3'?">
No public v3. See section 5 ("The Mitigating-PtH v3 that never shipped") for the source-by-source disambiguation against Microsoft Download Center ID 36036.
</FAQItem>
</FAQ>

## 13. The Pattern That Outlived Six Defenses

The 1997 patch and the 2026 attack are the same attack because the architectural property the family shares is unchanged. The artefact moved; the property did not.

A long-term authentication artefact reachable by the using process is replayable. The NT hash sat in LSASS on Windows NT 4.0 and replayed against SMB. The Kerberos TGT sat in LSASS on Windows Server 2003 and replayed against Kerberos services. The NT hash sat in LSASS on Windows Server 2008 and replayed against the KDC's RC4-HMAC authentication path as a real Kerberos client.

The X.509 certificate private key sat in a CryptoAPI key container on Windows Server 2012 R2 and replayed against PKINIT-supporting domain controllers as the principal in the SAN. The Primary Refresh Token sits in the CloudAP plug-in inside LSASS on Windows 11 23H2 today, and replays against Entra ID as the device's user from any machine that holds the extracted session key.

Each defense relocated the artefact to a harder-to-reach storage class. The "Do not store LAN Manager hash" policy retired LM. RunAsPPL marked LSASS as a Protected Process Light. Credential Guard moved NT hashes and TGT session keys out of LSASS in VTL0 into the LSAISO trustlet in VTL1. KB5014754 bound certificates to SIDs at issuance, so that a certificate without the SID extension fails strong mapping at the KDC. Token Protection bound PRTs to devices, so that a stolen PRT used against a supported resource from a non-bound device fails.

Each defense was real. Each closed a generation. The family did not close.

The reason the family does not close is structural. Every generation finds the next long-term artefact whose storage class the latest defense did not isolate. Pass-the-Hash worked because the NT hash was reachable. Pass-the-Ticket worked because the TGT was reachable. Overpass-the-Hash worked because the NT hash was reachable *and* the KDC accepted RC4-HMAC. Pass-the-Certificate worked because certificate templates were misconfigured and the SID extension did not exist. Pass-the-PRT works because CloudAP is in LSASS in VTL0 and Token Protection covers five resources.

The architectural lower bound -- universal hardware-rooted non-extractable keys plus universal token binding plus universal continuous evaluation -- is the only configuration that closes the family, and it is not deployed anywhere as a complete stack.

The playbook in the previous section is what to do today. The forecast in section 10 is what to architect for next. The closing observation is the one this article exists to register: when you read about the next named "Pass-the-X" technique, you already know what it will look like. A long-term authentication artefact, reachable from the process that holds it, replayed from a different machine, defeating the latest defense because that defense was designed for a different artefact.

Generation 6 is already in research literature. The only thing missing is the name.

<StudyGuide slug="pass-the-hash-to-pass-the-prt" keyTerms={[
  { term: "NT hash", definition: "16-byte MD4 of the user's password as UTF-16 little-endian; the long-term Windows authentication secret since the early NT releases, unsalted by design." },
  { term: "NTLM challenge-response", definition: "Family of Windows authentication protocols (NTLMv1 and NTLMv2) in which the server sends a random challenge and the client returns a keyed cryptographic response computed under a key derived from the user's password; the password is never transmitted." },
  { term: "Pass-the-Hash", definition: "Authenticating with a stolen NT hash by feeding it directly to the protocol's response-construction function instead of typing a password; Paul Ashton, NTBugtraq, April 1997." },
  { term: "LSASS", definition: "Local Security Authority Subsystem Service; the user-mode Windows process that caches in-memory credential material (hashes, tickets, certificate handles, PRT material) for the duration of each logon session." },
  { term: "Kerberos TGT", definition: "Ticket Granting Ticket: the long-lived Kerberos credential issued by the KDC's Authentication Service, encrypted under the krbtgt long-term key, carrying a session key for subsequent service-ticket requests." },
  { term: "Pass-the-Ticket", definition: "Extracting a Kerberos TGT (and its session key) from one machine's LSASS-resident Kerberos cache and injecting it into another machine's cache." },
  { term: "Overpass-the-Hash", definition: "Presenting a stolen NT hash to the KDC as the user's long-term RC4-HMAC Kerberos key (per RFC 4757) to obtain a real TGT signed by the real krbtgt." },
  { term: "Credential Guard", definition: "Windows feature that relocates NT hashes, Kerberos TGT session keys, and 'credentials stored by applications as domain credentials' from LSASS in VTL0 to the LSAISO trustlet in VTL1, isolated by the Windows hypervisor." },
  { term: "LSAISO trustlet", definition: "The isolated-user-mode LSA process (lsaiso.exe) that holds Credential Guard's protected credential material in VTL1; unreadable from any VTL0 process or driver." },
  { term: "PKINIT", definition: "Kerberos pre-authentication using a certificate's private key in place of a long-term symmetric key (RFC 4556); the SAN of the certificate maps to the principal whose TGT the KDC will issue." },
  { term: "Pass-the-Certificate", definition: "Authenticating to Active Directory with a stolen X.509 certificate's private key via PKINIT to the KDC or Schannel client-cert authentication to LDAPS." },
  { term: "szOID_NTDS_CA_SECURITY_EXT", definition: "X.509 extension introduced by KB5014754 (OID 1.3.6.1.4.1.311.25.2) that carries the requesting principal's SID at certificate issuance; the basis of KDC strong certificate mapping." },
  { term: "Primary Refresh Token (PRT)", definition: "Microsoft Entra-issued long-lived refresh token for SSO on Entra-joined or Hybrid-joined Windows devices; carries a session key (HMAC-SHA256) and binds to a device transport key; default 90-day lifetime with sliding renewal." },
  { term: "CloudAP", definition: "Cloud Authentication Provider; the Windows authentication package (cloudap.dll) loaded into LSASS that holds Microsoft Entra credential material including the PRT; not currently inside Credential Guard's isolation scope." }
]} />
