# From Password-in-the-Pipe to Cloud-Issued Session: Twenty-Six Years of RDP Authentication

> How five generations of Windows RDP authentication -- classic delegation, NLA via CredSSP, Restricted Admin, Remote Credential Guard, and PRT-over-RDP -- retreated from the 1998 design that gave attackers the keys to every target.

*Published: 2026-05-12*
*Canonical: https://paragmali.com/blog/from-password-in-the-pipe-to-cloud-issued-session-twenty-six*
*License: CC BY 4.0 - https://creativecommons.org/licenses/by/4.0/*

---
<TLDR>
**Remote Desktop Protocol** has spent twenty-six years retreating from one design decision: in 1998, "the user's password becomes the target's credential." Five generations now coexist on a Windows estate. **Classic credential delegation** sends the user's NT one-way function into the target's `lsass.exe`. **Network Level Authentication via CredSSP** [@rdpbcgr-credssp] (Windows Vista, 2006) moves authentication before the session starts but still delivers credential material. **Restricted Admin mode** [@ms-adv-2871997] (Windows 8.1 / Server 2012 R2 RTM, October 17, 2013) stops delivering credentials and runs the user's session as the target's machine identity. **Remote Credential Guard** [@msl-rcg] (Windows 10 1607, August 2, 2016) forwards Kerberos operations back to the caller's `lsass.exe`, with VTL1 trustlet protection conditional on the caller having local Credential Guard enabled. **PRT-over-RDP** [@msl-prtrdp-mstsc] (October 11, 2022 cumulative updates) uses a Microsoft Entra ID Primary Refresh Token cookie scoped to the Conditional Access app `a4a365df-50f1-4397-bc59-1a1564b8bb9c`. **CVE-2018-0886** [@nvd-2018-0886] (CredSSP MITM) and **CVE-2019-0708** [@nvd-2019-0708] (BlueKeep, pre-auth channel-setup) are the canonical RDP CVEs. The residual classes are RBCD against `TERMSRV` [@shamir-wagging], PRT extraction at the session host [@mollema-prt2], and the architectural SYSTEM-on-target floor that no RDP mode can close.
</TLDR>

## 1. Four sekurlsa Dumps, One Target

A red-team operator with `SYSTEM` on a single Windows 11 25H2 host runs `mimikatz sekurlsa::logonpasswords` four times in a row [@mimikatz-github]. Each time, a different user has just disconnected an RDP session. Each time, the dump looks different.

The first dump shows the user's NT one-way function. The second dump shows the target machine's identity instead of the user's. The third dump shows the user's identity but no hash that can be replayed anywhere. The fourth dump shows no password-equivalent material for the user at all -- only a Primary Refresh Token bound to the target's own TPM.

Four RDP sessions, one target, four entirely different post-exploitation pivots. The difference is not in what the attacker did. The difference is in which authentication mode the client negotiated before the session was established.

This article is about those four modes -- classic, Restricted Admin, Remote Credential Guard, and PRT-over-RDP -- and the fifth (NLA via CredSSP) that sits underneath them all. It is the story of a twenty-six-year retreat from "the user's password becomes the target's credential."

The wire-protocol selectors are public, even if their names mostly are not. The `RDP_NEG_REQ` structure [@rdpbcgr-negreq] sets `requestedProtocols` to one of `PROTOCOL_RDP (0x00)`, `PROTOCOL_SSL (0x01)`, `PROTOCOL_HYBRID (0x02)` for CredSSP-based NLA, `PROTOCOL_HYBRID_EX (0x08)`, or `PROTOCOL_RDSAAD (0x10)` for the Entra-based path. Inside `PROTOCOL_HYBRID`, two `flags` bits switch the sub-mode: `RESTRICTED_ADMIN_MODE_REQUIRED (0x01)` and `REDIRECTED_AUTHENTICATION_MODE_REQUIRED (0x02)`. Five wire-level paths. Five different answers to the same question: what does the target's `lsass.exe` end up holding?

The next twelve sections walk each mode end-to-end, the CVEs that broke each layer, the Microsoft Learn comparison matrix verbatim, the residual class that survives each generation, and the operational guide for the engineer who has to make these primitives interoperate on Monday morning. Before we can read the four dumps, we have to understand the one credential-delivery decision every later generation was built to correct. That decision shipped in 1998.

## 2. Terminal Services and the Password-in-the-Pipe Era (1998-2005)

In 1998 Microsoft shipped a remote-display product that solved an obvious problem -- run a Windows desktop over the network -- and a second, less obvious problem along the way: every machine that accepted an RDP connection now needed to be a credential reservoir for every user who connected to it.

The product was Windows NT 4.0 Terminal Server Edition [@wiki-nt4tse], built on top of MultiWin technology that Microsoft had licensed from Citrix the previous year [@wiki-rdp]. The protocol that carried the display and the keystrokes was the Remote Desktop Protocol, version 4.0, listening on TCP port 3389 (and, much later, UDP port 3389 for the QUIC variant) [@wiki-rdp]. The protocol itself was an extension of the ITU-T T.128 application-sharing protocol [@wiki-rdp], with RC4 channel encryption layered on top using a 40-bit, 56-bit, or 128-bit session key (a FIPS-validated 3DES variant was added in Server 2003) [@rdpbcgr-index].

<Mermaid caption="From NT 4.0 TSE (1998) to PRT-over-RDP (2022): twenty-six years of RDP authentication. Timeline sources, in row order: wiki-rdp, cdc-smbrelay, rdpbcgr-credssp, ms-adv-2871997, msl-rcg, msl-prtrdp-mstsc.">
timeline
    title Twenty-six years of RDP authentication
    1998 : NT 4.0 Terminal Server Edition / RDP 4.0
         : Password delivered to target's lsass
    2001 : SMBRelay (cDc) names credential-in-motion attack
    2006 : Windows Vista / RDP 6.0 ships NLA via CredSSP
    2013 : Windows 8.1 / 2012 R2 ships Restricted Admin
    2014 : KB2871997 backports Restricted Admin to Win 7
    2016 : Windows 10 1607 / 2016 ships Remote Credential Guard
    2018 : CVE-2018-0886 CredSSP RCE; AllowEncryptionOracle
    2019 : CVE-2019-0708 BlueKeep pre-auth channel-setup RCE
    2022 : KB5018418 ships PRT-over-RDP / Entra SSO for RDP
    2025 : Win 11 24H2 KIR recovers from RDP-stack regression
</Mermaid>

<Definition term="Terminal Services / Remote Desktop Services">
Microsoft's multi-user remote-desktop subsystem, introduced in Windows NT 4.0 Terminal Server Edition (1998) [@wiki-rdp]. Renamed to Remote Desktop Services in Windows Server 2008 R2. Provides interactive Windows sessions over TCP/3389 using the Remote Desktop Protocol, an extension of the ITU-T T.128 application-sharing protocol family.
</Definition>

Authentication, in 1998, looked nothing like authentication today. The client opened a TCP/3389 connection. The server sent a Proprietary Certificate containing an RSA public key. The client generated a 32-byte Client Random, encrypted it with that RSA public key, and both sides derived RC4 session keys from the shared random [@rdpbcgr-index].

The user then typed a username and password into the remote login screen, and the password traveled into the target's `Winlogon` process inside that RC4 channel. The target's `lsass.exe` ran NTLM challenge-response against a domain controller (or against its local SAM) and, on success, materialised an interactive session for the user. The target now held the user's NT one-way function for the lifetime of that session.

The architectural property was simple: the target was the credential reservoir. Five accounting clerks who RDP'd into a Terminal Server during a shift left five NT-OWF entries in that host's `lsass.exe` memory. An attacker who later got `SYSTEM` on the Terminal Server held the credential material for all five.

Two years later, Windows 2000 made Terminal Services a built-in server feature, and Windows XP Professional (October 2001) shipped the desktop-side variant under the brand "Remote Desktop" [@wiki-rdp]. The credential-aggregation surface, previously confined to dedicated Terminal Server hosts, now extended to every workstation in the estate.

The first public articulation that *credential material in motion is itself an attack surface* came on March 31, 2001, when Sir Dystic of Cult of the Dead Cow released SMBRelay at the `@lanta.con` convention in Atlanta [@cdc-smbrelay]. SMBRelay was an SMB man-in-the-middle that hijacked an inbound NTLM authentication and relayed it onward.<Sidenote>The Wikipedia SMBRelay article gives March 21, 2001 [@wiki-smbrelay], but the primary source -- Sir Dystic's own publication at cultdeadcow.com -- says March 31, 2001 [@cdc-smbrelay]. Primary-source dating wins. The Wikipedia article also says "receives a connection on UDP port 139," which is incorrect; NetBIOS Session Service has always run over TCP/139, and the SMBRelay v0.98 source listing on cultdeadcow.com explicitly binds a TCP socket to port 139.</Sidenote> RDP was not yet a direct target, but the principle was now public: pass-the-hash and credential relay would work against any protocol that put credential material on the wire.

RDP 5.2 (Server 2003, XP SP2) responded to the wire-confidentiality problem in 2003 by adding an optional `Security Layer = SSL` setting that wrapped the RDP traffic in TLS [@rdpbcgr-index]. The header byte called `selectedProtocol` could now take the value `PROTOCOL_SSL = 0x01`, meaning the channel was TLS-encrypted before the legacy basic-settings exchange ran. TLS solved the wire-snooping problem.<Sidenote>"Security Layer = SSL" in RDP 5.2 was *transport confidentiality only*. The TLS handshake authenticated the server's certificate (or did not, in many production configurations); the user authentication still happened later, inside the basic-settings exchange and the `Logon_Info` PDU. The credential the target ended up with was identical to classic-RDP credential delivery. The distinction between "TLS protects the wire" and "TLS protects the credential" is the load-bearing precision the next section will need.</Sidenote> It did not solve the credential-aggregation problem.

By 2005 the architectural problem was named. Microsoft's eventual response would shape the next two decades of Windows authentication strategy. It would also, on its first attempt, fix the wrong half of the problem.

## 3. Network Level Authentication via CredSSP (2006-2013)

Network Level Authentication is the policy that requires authentication before the RDP session is established. NLA is not a protocol. NLA is implemented by CredSSP -- the Credential Security Support Provider -- running over TLS [@rdpbcgr-credssp]. The difference between those two sentences is the one that matters.

Windows Vista (November 2006) shipped RDP 6.0, the first Windows release to include NLA and CredSSP support. NLA was selectable in System Properties but did not become the Remote Desktop default until Windows 7 / Server 2008 R2 [@wiki-rdp]. The MS-CSSP open specification documents CredSSP's role and its lineage, with the protocol summary listing its first revision in December 2006 [@mscssp-index] -- the same shipping window as Vista.

MS-CSSP defines CredSSP as a protocol that "enables an application to securely delegate a user's credentials from a client to a target server" [@mscssp-index]. That phrasing matters: from CredSSP's own design statement, the credential is delegated *to* the target. The credential still ends up on the target. The protocol design did not change that property; it changed *when* the delivery happens and *what* protects it on the wire.

<Definition term="Network Level Authentication (NLA)">
A policy on the RDP server that requires the connecting user to authenticate before the RDP session is established (before the basic-settings exchange and the virtual-channel binding). Implemented by CredSSP over TLS [@rdpbcgr-credssp]. NLA reduces denial-of-service exposure and gates the pre-auth channel-setup attack surface (the failure mode BlueKeep would later exploit) but does not change the credential material the target receives.
</Definition>

<Definition term="Credential Security Support Provider (CredSSP)">
The Microsoft authentication protocol, specified in MS-CSSP [@mscssp-index] and used by RDP and Windows Remote Management, that "amalgamates" TLS with Kerberos and NT LAN Manager [@rdpbcgr-credssp]. CredSSP runs SPNEGO inside a TLS channel, performs Kerberos or NTLM authentication inside SPNEGO, and finally delivers a `TSCredentials` payload to the target. CredSSP is what NLA *is*, at the wire.
</Definition>

<Definition term="TSCredentials">
The CredSSP payload structure that carries the user's credential material to the target after the SPNEGO and Kerberos/NTLM phases complete [@mscssp-index]. The classic form is `TSPasswordCreds` (username + domain + plaintext password). Two later forms -- the credential-less form for Restricted Admin and the redirected form (`TSRemoteGuardCreds`) for Remote Credential Guard -- change what travels in this slot without changing the surrounding exchange.
</Definition>

The wire choreography is documented verbatim in section 5.4.5.2 of MS-RDPBCGR. CredSSP is "essentially the amalgamation of TLS with Kerberos and NT LAN Manager (NTLM)" [@rdpbcgr-credssp]. The exchange runs in this order:

1. Client opens TCP/3389.
2. `RDP_NEG_REQ` carries `requestedProtocols & PROTOCOL_HYBRID = 0x02` (or `PROTOCOL_HYBRID_EX = 0x08`, which adds an Early User Authorization Result PDU) [@rdpbcgr-negreq].
3. TLS handshake completes inside the RDP transport.
4. SPNEGO negotiates Kerberos or NTLM inside the TLS channel.
5. Kerberos or NTLM authenticates the user (and, for Kerberos, the server as well).
6. The `TSCredentials` payload is sent to the target inside the still-open TLS channel. "Once Kerberos or NTLM has completed successfully, the user's credentials are sent to the server" [@rdpbcgr-credssp].
7. The RDP basic-settings exchange and virtual-channel binding proceed.

<Mermaid caption="The NLA / CredSSP exchange: TLS handshake, SPNEGO inside TLS, Kerberos or NTLM inside SPNEGO, TSCredentials delivered to the target, basic-settings exchange follows.">
sequenceDiagram
    autonumber
    participant C as Client (mstsc.exe)
    participant T as Target (lsass.exe + termsrv)
    participant K as KDC / domain controller
    C->>T: TCP/3389 + RDP_NEG_REQ (PROTOCOL_HYBRID 0x02)
    T-->>C: RDP_NEG_RSP (PROTOCOL_HYBRID selected)
    C->>T: TLS Client Hello
    T-->>C: TLS Server Hello + cert chain
    C->>T: SPNEGO NegTokenInit inside TLS
    C->>K: AS-REQ / TGS-REQ for target SPN
    K-->>C: AS-REP / TGS-REP
    C->>T: AP-REQ inside SPNEGO inside TLS
    T-->>C: AP-REP (mutual auth)
    C->>T: TSCredentials (TSPasswordCreds)
    T->>T: lsass logs user on, NT-OWF cached
    C->>T: RDP basic-settings exchange + session
</Mermaid>

> **Note:** "Enable NLA" in the System Properties dialog flips a server-side policy that requires the connecting client to authenticate via CredSSP before the RDP session is established. NLA is *that policy*. CredSSP [@mscssp-index] is the wire protocol that satisfies it. When operators say "we require NLA," they mean "we accept only `requestedProtocols = PROTOCOL_HYBRID` or `PROTOCOL_HYBRID_EX`," which is enforced by Windows refusing the `RDP_NEG_REQ` if those bits are not set. The protocol carrying the credential to the target is CredSSP, today and twenty years from now.

What NLA accomplishes is real. The unauthenticated RDP channel-setup code -- basic-settings exchange, virtual-channel binding, the `MS_T120` handler that BlueKeep would exploit a decade later -- is no longer reachable from the network. An attacker who reaches TCP/3389 must complete a CredSSP handshake (with valid Kerberos or NTLM credentials) before any RDP-stack code beyond the negotiation header runs. That is a denial-of-service mitigation and a pre-auth-RCE mitigation. It is not a credential-isolation mitigation.

What NLA does not accomplish is what happens at step 6. The output of CredSSP is `TSPasswordCreds`, which is the user's plaintext password (or its NTLM equivalent in some paths) delivered to the target's `lsass.exe`. Mimikatz `sekurlsa::logonpasswords` against the target after the session ends returns the user's NT-OWF [@mimikatz-github, @wiki-mimikatz], exactly as it would against a 1998-era classic-RDP target. The 2014 Microsoft *Mitigating Pass-the-Hash* whitepaper (version 2) [@msl-pthv2] named this failure mode eight years after NLA shipped: NLA is necessary but not sufficient.

Mimikatz had given the failure mode a name. Benjamin Delpy released the first version in May 2011, initially closed-source [@wiki-mimikatz]. In September 2011 a version of the exploit was used in the DigiNotar incident [@wiki-mimikatz]. By 2012, on a Windows estate running NLA-mandatory RDP since 2007, attackers were still pivoting from a compromised admin's workstation to every server that admin had logged into, harvesting NT-OWFs as they went. NLA was on the wire. The Pass-the-Hash playbook still worked.

NLA moved when the authentication happened. It did not change what the target ended up with. Pass-the-Hash against a 2012-era CredSSP-authenticated RDP target was identical to Pass-the-Hash against a 1998-era classic-RDP target. Microsoft's architectural response shipped in October 2013 -- and it was a structurally different idea.

## 4. BlueKeep, CVE-2018-0886, and the Two Failure Modes of CredSSP

The same NLA that mitigates BlueKeep also introduces CVE-2018-0886. The CVE class is not a coincidence. CredSSP is both the protocol that gates the pre-auth channel-setup code *and* the protocol whose own logic now has to be correct. Two CVEs anchor this section, six years apart.

### CVE-2018-0886: CredSSP Remote Code Execution

On March 13, 2018, Microsoft patched a CredSSP logical flaw discovered by Preempt (now CrowdStrike) [@crowdstrike-credssp]. The NVD record states the vulnerability allows "a remote code execution vulnerability due to how CredSSP validates request during the authentication process" [@nvd-2018-0886] and classifies it as CWE-287 (Improper Authentication). The affected matrix is wide: Windows Server 2008 SP2 and R2 SP1, Windows 7 SP1, Windows 8.1 / RT 8.1, Windows Server 2012 and R2, Windows 10 (1507 through 1709), Windows Server 2016, and Windows Server version 1709 [@nvd-2018-0886].

The mechanism is a man-in-the-middle injection. Preempt's disclosure timeline (verbatim from the CrowdStrike advisory) is "20/08/2017: Initial disclosure to MSRC; 30/08/2017: MS repro attack and acknowledge issue; 18/09/2017: Microsoft requested an extension on 90 days SLA; 12/03/2018: Microsoft fixes CVE-2018-0886 as part of March patch Tuesday" [@crowdstrike-credssp]. The attack scenarios are real-world: ARP poisoning on a flat LAN, KRACK against a poorly-patched Wi-Fi network, or a vulnerable router on the path between client and target.

<PullQuote>
"The vulnerability consists of a logical flaw in Credential Security Support Provider protocol (CredSSP), which is used by RDP (Remote Desktop Protocol) and Windows Remote Management (WinRM)... The vulnerability can be exploited by attackers by employing a man-in-the-middle attack." -- CrowdStrike (formerly Preempt) [@crowdstrike-credssp]
</PullQuote>

The architectural lesson is that CredSSP's role as a security boundary creates a second security boundary inside the protocol itself. NLA gates the pre-auth code path *behind CredSSP*. If CredSSP has a bug, NLA does not protect anything beyond it; the bug *is* the pre-auth code path.

### The AllowEncryptionOracle deployment incident

KB4093492 (May 8, 2018) is the worked example of how a protocol-layer compatibility shim becomes a deployment hazard [@msl-kb4093492]. The patch introduced a three-state registry value at `HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters\AllowEncryptionOracle`. The states are:

- **Force Updated Clients (0)** -- the client refuses to communicate with non-patched servers.
- **Mitigated (1)** -- the client accepts patched servers and refuses unpatched servers (default after May 8, 2018).
- **Vulnerable (2)** -- the client accepts both, preserving compatibility with unpatched servers (transitional default).

On May 8, 2018, Microsoft flipped the default from `Vulnerable (2)` to `Mitigated (1)`. The KB article states bluntly: "By default, after this update is installed, patched clients cannot communicate with unpatched servers" [@msl-kb4093492]. RDP between patched and unpatched estates broke worldwide for a week. The diagnostic Event ID 6041 (`LsaSrv`, "Error encountered while reading from the protected payload of the bilateral exchange") appeared in millions of system logs.

> **Note:** A protocol-layer compatibility shim is itself a deployment surface. The May 2018 default-flip from `Vulnerable (2)` to `Mitigated (1)` [@msl-kb4093492] was correct as a security posture and disastrous as a rollout sequence. Patch the servers before the clients; verify with `Get-ItemProperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters'`; do not assume that "GPO push to clients" is the right first step.

### CVE-2019-0708: BlueKeep

On May 14, 2019, Microsoft shipped a fix for a use-after-free in the `MS_T120` virtual-channel binding handler inside `termdd.sys` -- the kernel-mode driver that handles RDP transport-layer code [@wiki-bluekeep]. The vulnerability, named BlueKeep by Kevin Beaumont on Twitter and discovered by the UK National Cyber Security Centre [@wiki-bluekeep], allowed pre-authentication remote code execution at `SYSTEM` on the target. The NVD record (CVE-2019-0708) lists references to PacketStorm exploits, Siemens advisories, the MSRC vendor advisory, and the CISA Known Exploited Vulnerabilities catalog [@nvd-2019-0708].

The affected matrix is "Windows XP, Windows Vista, Windows 7, Windows Server 2003, Windows Server 2008, and Windows Server 2008 R2" [@wiki-bluekeep]. Microsoft issued out-of-band patches for the end-of-life operating systems (Windows XP and Server 2003) [@wiki-bluekeep] -- a step the company reserves for vulnerabilities expected to be weaponised at scale. CISA, the NSA, and Microsoft all issued emergency advisories.

<Aside label="The BlueKeep precision: why 'pre-NLA RDP' is the wrong frame">
The common shorthand for BlueKeep is that it was "a vulnerability in pre-NLA RDP." The shorthand is wrong, and the precision matters because it sets up the wrong intuition for every authentication mode that follows.

NLA existed natively in every BlueKeep-affected operating system from Windows Vista onward -- Windows 7, Server 2008, and Server 2008 R2 all shipped NLA support, and many of those estates ran with NLA on. Windows XP and Server 2003 did not ship NLA natively; CredSSP / NLA was retrofitted to both via KB951608 (March 2009) [@wiki-bluekeep]. BlueKeep is a vulnerability in the channel-setup code reachable when NLA is *not enforced* -- the channel-setup code being the `MS_T120` virtual-channel binder in `termdd.sys`, which is reachable only after the negotiation header but before the basic-settings exchange when CredSSP is not gating the path [@wiki-bluekeep].

When `requestedProtocols = PROTOCOL_RDP (0x00)` and the server permits it, the client skips the CredSSP gate and walks straight into the basic-settings exchange. The `MS_T120` channel binding happens in that pre-authentication window. NLA closes that window by requiring `PROTOCOL_HYBRID (0x02)` (or `_HYBRID_EX 0x08`) before any RDP-stack code beyond the negotiation header runs. The mitigation guidance every operator received in May 2019 -- "enable NLA" -- worked because of this layering, not because BlueKeep was a vulnerability in a pre-NLA era.

The framing matters because the same precision applies to every later mode. Restricted Admin, Remote Credential Guard, and PRT-over-RDP all sit on top of CredSSP gating (or, for PRT-over-RDP, on top of a different gate entirely). None of them protect anything in the channel-setup phase. NLA does.
</Aside>

<Sidenote>The BlueKeep out-of-band patch for Windows XP and Server 2003 [@wiki-bluekeep] is one of the rare exceptions to Microsoft's end-of-life policy. The 2017 WannaCry / EternalBlue cycle made Microsoft cautious about wormable pre-auth RCE on end-of-life operating systems; BlueKeep met the same threshold. The pattern -- a pre-auth RCE in long-deployed Windows networking code, with end-of-life patches issued out-of-band -- recurs about once every five years.</Sidenote>

NLA mitigates BlueKeep but does not stop Pass-the-Hash. CredSSP itself has a non-trivial logical-attack surface. The architectural response to the Pass-the-Hash failure had already shipped five years before BlueKeep -- and it took the opposite approach. Instead of delivering the credential more securely, it stopped delivering the credential at all.

## 5. Restricted Admin: User Is the Machine (2013)

On October 17, 2013, Microsoft shipped a feature whose entire architectural insight fits in one sentence: stop delivering the user's credential to the target, and let the target log the user on as the target itself.

The feature is Restricted Admin mode, part of the CredSSP protocol family. It first shipped with Windows 8.1, Windows Server 2012 R2, and Windows RT 8.1 at RTM. Microsoft Security Advisory 2871997 states this verbatim: "Supported editions of Windows 8.1, Windows Server 2012 R2, and Windows RT 8.1 already include these features and do not need the 2871997 update" [@ms-adv-2871997]. The advisory is the load-bearing primary that pins the October 2013 ship date, because the advisory itself was the *backport* notice for older operating systems.

<Aside label="Three rollout dates, not one: untangling KB2871997">
The shorthand "Restricted Admin shipped with KB2871997 in 2014" is a recurring misreading worth defusing. Restricted Admin shipped on three separate dates:

1. **October 17, 2013** -- Windows 8.1, Windows Server 2012 R2, and Windows RT 8.1 RTM. Restricted Admin is in the box. No update required [@ms-adv-2871997].
2. **May 13, 2014** -- KB2871997 backported the *CredSSP-layer* support to Windows 7, Windows Server 2008 R2, Windows 8, Windows Server 2012, and Windows RT [@ms-adv-2871997]. The advisory text reads verbatim: "On May 13, 2014, Microsoft released the 2871997 update for supported editions of Windows 8, Windows RT, Windows Server 2012, Windows 7, and Windows Server 2008 R2 that improves credential protection and domain authentication controls to reduce credential theft. This update provides additional protection for the Local Security Authority (LSA), adds a restricted admin mode for Credential Security Support Provider (CredSSP)..." [@ms-adv-2871997].
3. **October 14, 2014** -- the *RDP-client-side* backport in KB2984972 (Win 7 / Server 2008 R2), KB2984976 (Win 7), KB2984981 (Win 7), and KB2973501 (Server 2012). Without the client-side update, Win 7 clients could not *initiate* a Restricted Admin RDP connection even though their CredSSP layer supported the protocol after May 2014 [@ms-adv-2871997].

If you read "2014 KB2871997" as the introduction date, the feature looks like a Windows-7-and-back retrofit. It is the opposite: Restricted Admin was a Windows 8.1 RTM feature whose value to the existing fleet was unlocked by two later backports.
</Aside>

### The wire protocol

Restricted Admin opt-in lives in two bytes on the wire, both documented verbatim in MS-RDPBCGR. The client sets `RDP_NEG_REQ.flags & RESTRICTED_ADMIN_MODE_REQUIRED = 0x01` to signal the request: "Indicates that the client requires credential-less logon over CredSSP (also known as 'restricted admin mode'). If the server supports this mode then it is acceptable for the client to send empty credentials in the **TSPasswordCreds** structure" [@rdpbcgr-negreq]. The server confirms support by setting `RDP_NEG_RSP.flags & RESTRICTED_ADMIN_MODE_SUPPORTED = 0x08` in the response: "Indicates that the server supports credential-less logon over CredSSP" [@rdpbcgr-negrsp].

The CredSSP exchange itself runs end-to-end. TLS handshake completes; SPNEGO selects Kerberos or NTLM; the user authenticates. At step 6 -- where classic CredSSP would send a populated `TSPasswordCreds` -- the client sends an *empty* `TSPasswordCreds`. No password, no NT-OWF, no forwarded TGT. The target receives no credential material.

<Definition term="Restricted Admin mode">
A CredSSP sub-mode signalled by the `RDP_NEG_REQ.flags & RESTRICTED_ADMIN_MODE_REQUIRED 0x01` bit [@rdpbcgr-negreq]. The client completes authentication to the target but sends an empty `TSPasswordCreds` payload; the target then logs the user on using the target's own machine account, restricting the session to actions the local Administrators group can perform. Introduced at Windows 8.1 / Server 2012 R2 RTM (October 17, 2013) [@ms-adv-2871997]; backported to Windows 7 / Server 2008 R2 via KB2871997 (May 13, 2014) and the October 14, 2014 client-side KBs.
</Definition>

### The mechanism: the user becomes the machine

When the target sees an empty `TSPasswordCreds` and the `RESTRICTED_ADMIN_MODE_REQUIRED` flag, it does not refuse the logon. It logs the user on by impersonating the target's own machine account (`<TARGETNAME>$`). The machine account is in the local Administrators group by default; the user requesting the session must already be a member of the same group on the target. Microsoft Learn states the access prerequisite for Restricted Admin as "Membership of **Administrators** group on remote host" [@msl-rcg].

<Mermaid caption="Restricted Admin: CredSSP completes, but the client sends an empty TSPasswordCreds. The target logs the user on as its own machine account, which is in the local Administrators group.">
sequenceDiagram
    autonumber
    participant C as Client
    participant T as Target
    participant K as KDC
    C->>T: RDP_NEG_REQ (PROTOCOL_HYBRID 0x02 + flags 0x01)
    T-->>C: RDP_NEG_RSP (flags 0x08 supported)
    C->>T: TLS handshake
    C->>K: Kerberos AS / TGS for target SPN
    C->>T: AP-REQ inside SPNEGO (user authenticated)
    C->>T: TSPasswordCreds (EMPTY)
    T->>T: LogonUser as TARGET$ machine account
    T->>T: Token in local Administrators
    C->>T: RDP session as machine identity
</Mermaid>

> **Note:** The breakthrough in Restricted Admin is not a new crypto primitive. It is the realisation that the target can act on the user's behalf by impersonating *itself* -- the target's own machine account -- which is already a local Administrator. The session has access to local resources, the user has full administrative use of the target, and the target's `lsass.exe` holds no user credential material. The trade is the user's downstream identity: the session cannot use the user's credentials for SSO, because the session is not the user. The session is the target.

### The trade-offs, verbatim from Microsoft Learn

Microsoft Learn publishes a comparison matrix that lays out the trade-offs across Remote Desktop (classic), Remote Credential Guard, and Restricted Admin [@msl-rcg]. For Restricted Admin, the row entries are:

- Prevent use of user's identity during connection: yes.
- Prevent use of credentials after disconnection: yes.
- Prevent Pass-the-Hash: yes.
- Single sign-on to other systems: no.
- Multi-hop RDP: no.
- Supported authentication: any negotiated by CredSSP (Kerberos or NTLM).
- Credentials supported from the client: signed-in credentials, supplied creds, saved creds.
- RDP access granted with: membership of Administrators on the remote host [@msl-rcg].

This is the architectural trade. The user is gone the moment the session ends. The attacker who compromises the target during the session gets local Administrator -- but via the machine identity, not via the user's credential.

### The RBCD residual class

There is no free lunch. Restricted Admin's "user becomes the machine identity" design creates a different residual surface. If the attacker can write the `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute on the target's computer object in Active Directory, the attacker can use Resource-Based Constrained Delegation to S4U2self + S4U2proxy a Kerberos service ticket for `TERMSRV/<target>` and RDP in as *anyone*.

Elad Shamir documented this in his January 28, 2019 essay "Wagging the Dog" [@shamir-wagging]. The TL;DR points are precise: "Resource-based constrained delegation does not require a forwardable TGS when invoking S4U2Proxy. S4U2Self works on any account that has an SPN, regardless of the state of the `TrustedToAuthForDelegation` attribute... if an attacker can control a computer object in Active Directory, then it may be possible to abuse it to compromise the host. S4U2Proxy always produces a forwardable TGS, even if the provided additional TGS in the request was not forwardable" [@shamir-wagging].

<Definition term="Resource-Based Constrained Delegation (RBCD)">
A Kerberos delegation model introduced in Windows Server 2012 where the *target* resource controls which principals can delegate to it via the `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute on its own computer object. Combined with S4U2self and S4U2proxy, RBCD lets any principal that can write that attribute on a target's computer object obtain a forwardable Kerberos service ticket for any service on the target, including `TERMSRV` (the RDP service principal) [@shamir-wagging]. See the companion *NTLMless* article on this site for the wider S4U and Kerberos-relay discussion.
</Definition>

<PullQuote>
"Computer accounts just got a lot more interesting. Start hunting for more primitives to trigger attack chains!" -- Elad Shamir, *Wagging the Dog* (2019) [@shamir-wagging]
</PullQuote>

Dec0ne's KrbRelayUp (2022) productionised the chain as "essentially a universal no-fix local privilege escalation in windows domain environments where LDAP signing is not enforced (the default settings)" [@krbrelayup]. The tool wraps Rubeus, KrbRelay, and ADCSPwn for a kerberos-relay-to-RBCD-to-ShadowCred-to-S4U2self-to-SCMUACBypass chain that ends in `SYSTEM` on the target. Restricted Admin's machine-identity-as-session design is exactly what this chain rewards: the attacker walks away with Administrator on the target via the machine identity, with no need to harvest the user's credential.

Restricted Admin solves the credential-aggregation problem for jump servers. It does so by eliminating SSO and requiring local Administrator on the target -- which means it cannot be the answer for regular user RDP. If the target needs to act as the user during the session but never holds the user's credentials, the only place those credentials can live is back on the caller. That insight took three more years to ship.

## 6. Remote Credential Guard: Challenges Redirect to Caller (2016)

Remote Credential Guard is what you get if you take Restricted Admin's "no credential material delivered to the target" rule and add "but the target still needs to act as the user during the session." Both halves are achievable. The cost is one extra RPC round-trip for every Kerberos operation the session performs -- and a hard dependency on Kerberos itself.

On August 2, 2016, Microsoft shipped Windows 10 1607 (the Anniversary Update) and Windows Server 2016 with Remote Credential Guard [@msl-rcg]. The Microsoft Learn page states the design property in one sentence: "Remote Credential Guard helps protecting credentials over a Remote Desktop (RDP) connection by redirecting Kerberos requests back to the device that's requesting the connection. If the target device is compromised, the credentials aren't exposed because both credential and credential derivatives are never passed over the network to the target device" [@msl-rcg].

### The wire protocol

Opt-in lives in two more flag bits on the CredSSP negotiation. The client sets `RDP_NEG_REQ.flags & REDIRECTED_AUTHENTICATION_MODE_REQUIRED = 0x02` to signal the request: the flag indicates "the client can send a redirected logon buffer in the TSRemoteGuardCreds structure" [@rdpbcgr-negreq]. The server confirms by setting `RDP_NEG_RSP.flags & REDIRECTED_AUTHENTICATION_MODE_SUPPORTED = 0x10`: "Indicates that the server supports credential-less logon over CredSSP with credential redirection (also known as 'Remote Credential Guard')" [@rdpbcgr-negrsp].

The credential payload changes. Instead of an empty `TSPasswordCreds` (Restricted Admin) or a populated one (classic CredSSP), the client sends a `TSRemoteGuardCreds`. The ASN.1 structure is documented verbatim in MS-CSSP [@mscssp-trgcreds]:

```
TSRemoteGuardCreds ::= SEQUENCE {
    logonCred         [0] TSRemoteGuardPackageCred,
    supplementalCreds [1] SEQUENCE OF TSRemoteGuardPackageCred OPTIONAL
}
```

The payload does not carry a password or a hash. It carries a *handle* that lets the target forward authentication challenges back to the caller. MS-CSSP states that "The logon credential is passed to the Negotiate package, which in turn passes the credential to the default authentication package" [@mscssp-trgcreds] -- the negotiate package on the *target* receives a redirect-handle, not a credential.

<Definition term="Remote Credential Guard">
A CredSSP sub-mode signalled by the `RDP_NEG_REQ.flags & REDIRECTED_AUTHENTICATION_MODE_REQUIRED 0x02` bit [@rdpbcgr-negreq]. The session preserves the user's identity (unlike Restricted Admin), but every downstream Kerberos operation is performed by the caller's `lsass.exe` on behalf of the session, forwarded via RPC. Kerberos-only -- no NTLM fallback. Introduced in Windows 10 1607 and Windows Server 2016 (August 2, 2016) [@msl-rcg].
</Definition>

<Definition term="TSRemoteGuardCreds">
The CredSSP payload used by Remote Credential Guard [@mscssp-trgcreds]. A `SEQUENCE` of a `logonCred` and zero or more `supplementalCreds`, each of type `TSRemoteGuardPackageCred`. The handle is opaque to the target's authentication package; the target uses it only to request operations from the caller.
</Definition>

### The runtime mechanism

The interesting half of Remote CG runs *after* the session establishes. Suppose the user, now logged into the target as themselves, opens a file from a network share, mounts a database connection, or starts a second RDP hop. Each of those actions needs a Kerberos service ticket. The session host does not call `KerbCreateTicket()` itself. It packages an RPC request and sends it back to the caller's machine, where the caller's `lsass.exe` performs the operation using the caller's TGT and session key, then returns the resulting service ticket to the target session.

<Mermaid caption="Remote Credential Guard: the target forwards every Kerberos operation back to the caller's lsass.exe via RPC. The target never holds the user's TGT or session key.">
sequenceDiagram
    autonumber
    participant C as Client + caller lsass
    participant T as Target session host
    participant K as KDC
    participant F as File server (TGS target)
    C->>T: RDP_NEG_REQ (flags 0x02)
    T-->>C: RDP_NEG_RSP (flags 0x10)
    C->>T: TLS handshake
    C->>T: TSRemoteGuardCreds (handle)
    T->>T: Session start as user identity
    T->>C: RPC: TGS-REQ for cifs/fileserver
    C->>K: TGS-REQ
    K-->>C: TGS-REP
    C-->>T: TGS-REP forwarded back
    T->>F: AP-REQ with forwarded TGS
    F-->>T: AP-REP, SMB session
</Mermaid>

The cost is a round-trip per Kerberos operation. Over a LAN that is a few milliseconds; over a WAN that can be 50 milliseconds or more.<MarginNote>About 5ms LAN, 50ms WAN, per operation.</MarginNote><Sidenote>Remote CG is the only RDP authentication mode with runtime overhead proportional to downstream Kerberos hops. Classic CredSSP, Restricted Admin, and PRT-over-RDP all complete their credential exchange before the session starts; the session then talks to downstream services using credentials that already live on the target. Remote CG keeps the credentials at home and pays an RPC round-trip every time the session needs one. On a chatty workload -- mounting multiple SMB shares, opening many database connections, or chaining RDP hops -- this overhead is observable.</Sidenote>

### The trustlet conditional

A common belief about Remote Credential Guard is that it stores the redirected-authentication signing material in the caller's VBS trustlet `LsaIso.exe`. That is *partly* true and worth getting precise.

Remote Credential Guard always redirects challenges to the caller's `lsass.exe`. Where the long-lived signing material lives on the caller is a separate question:

- If the caller has local Credential Guard enabled, the secrets that back the redirected operations live in the caller's VTL1 `LsaIso.exe` trustlet, isolated from VTL0 user-mode code on the caller.
- If the caller does *not* have local Credential Guard, the same material lives in regular user-mode `lsass.exe` on the caller, with no VTL1 isolation.

The protocol still works in both cases. The redirection still happens. What changes is the protection the caller's lsass gets from an attacker who later compromises the caller. See the companion *Credential Guard* article on this site for the LsaIso internals.

<Definition term="LsaIso.exe">
The "isolated LSA" trustlet that runs in VTL1 under Virtualization-Based Security when Credential Guard is enabled. Stores credential-derived secrets (NTLM hash, Kerberos session key, TGT key, certificate private keys) outside the reach of VTL0 code, including kernel-mode rootkits. Documented in detail in the companion *Credential Guard* article on this site.
</Definition>

> **Note:** Remote Credential Guard always protects the credential from the *target* -- the target never sees it, regardless of caller configuration. Remote Credential Guard protects the credential from a *post-compromise of the caller* only if the caller has local Credential Guard enabled. The shorthand "Remote CG runs in a VBS trustlet" is true only for the second protection; for the first, the protection lives in the protocol, not in VBS.

### Kerberos-only -- and what that means for NTLM-mixed estates

Remote CG depends on Kerberos. Microsoft Learn is explicit: "Must use Kerberos authentication to connect to the remote host. If the client can't connect to a domain controller, then RDP attempts to fall back to NTLM. Remote Credential Guard doesn't allow NTLM fallback because it would expose credentials to risk" [@msl-rcg].

The reason is structural. NTLM challenge-response sends a chosen-plaintext-style hash of the user's NT-OWF to the target. Remote CG's redirection scheme works for Kerberos because the target can ask the caller to mint a service ticket; there is no equivalent operation in NTLM. Remote CG has nothing to redirect that does not eventually require the caller to hand over usable hash material.

Operationally, this means a 2026 estate that has not finished NTLM deprecation work cannot universally deploy Remote CG. Any RDP path that would fall back to NTLM -- a workgroup machine, a target whose Kerberos SPN registration is broken, a destination behind a DC-isolating firewall rule -- refuses to negotiate Remote CG and either fails the session or falls back to Restricted Admin (depending on the `RestrictedRemoteAdministration` GPO setting). See the companion *NTLMless* article on this site for the wider context.

<Sidenote>The UWP Remote Desktop client (the modern Microsoft Store variant) does not support Remote Credential Guard [@msl-rcg]. Only the classic `mstsc.exe` Win32 client implements the negotiation. Operators planning to enforce Remote CG must inventory which client binaries connect to which targets; mixing UWP clients into a Remote-CG-mandatory target pool produces silent connection failures.</Sidenote>

Remote CG closes credential-after-disconnection and Pass-the-Hash without sacrificing SSO. It does so by demanding Kerberos and one extra RPC per downstream hop. But the model assumes the user has on-prem-AD-routable Kerberos credentials -- which a Microsoft-Entra-joined laptop without hybrid join does not. The next generation throws away Kerberos entirely.

## 7. PRT-over-RDP: No Password, No Hash, No Ticket (2022)

On October 11, 2022, Microsoft shipped the first RDP authentication mode that has no `lsass.exe`-credential-delivery story to tell -- because there is no NTLM hash, no Kerberos ticket, and no password in the entire exchange. The credential is a JSON Web Token issued by Microsoft Entra ID.

The shipping vehicle was the October 2022 cumulative updates: KB5018418 (Windows 11), KB5018410 (Windows 10 20H2+), and KB5018421 (Windows Server 2022). KB5018418's release notes pin the date precisely: "Release Date: 10/11/2022. Version: OS Build 22000.1098" [@msl-kb5018418]. The Microsoft Learn page for the feature lists the same prerequisites: "The remote PC and your local device must be running one of the following operating systems: Windows 11 with 2022-10 Cumulative Updates for Windows 11 (KB5018418) or later installed" [@msl-prtrdp-mstsc].

<Aside label="The October 2022, not October 2025, feature">
PRT-over-RDP (Microsoft's official name: "Microsoft Entra single sign-on for Remote Desktop") is sometimes attributed to "2025." The misreading is worth defusing because the date affects what one believes is on the deployment frontier.

The feature shipped in October 2022 [@msl-prtrdp-mstsc, @msl-kb5018418]. The 2025 angles are two: Windows 11 24H2 reached broad consumer GA in October 2024, and a CredSSP/RDP regression in 24H2 produced session hangs and 65-second disconnects in early 2025; Microsoft rolled out a Known Issue Rollback ("KIR") via Group Policy in March 2025, and the Windows 11 24H2 release-health page now reads "There are no active known issues at this time" as of March 27, 2025 [@msl-24h2-status]. PRT-over-RDP itself has been a generally-available feature since October 2022; the 2025 events were deployment-stack stability work, not feature ship dates.
</Aside>

### The wire protocol

Microsoft introduced a new value for `requestedProtocols` -- `PROTOCOL_RDSAAD = 0x10` [@rdpbcgr-negreq] -- and an entirely new sub-protocol underneath it, "RDS AAD Auth." Section 5.4.5.4 of MS-RDPBCGR documents it verbatim: "RDS AAD Auth is a variation of Enhanced RDP Security that is used to authenticate a user to an Azure AD-joined device or to a Hybrid Azure AD-joined device. Server authentication, encryption, decryption, and data integrity checks are implemented by leveraging the TLS security protocol, while user authentication is accomplished by exchanging RDS AAD Auth PDUs directly following the TLS handshake" [@rdpbcgr-rdsaad].

The CredSSP exchange is *replaced entirely*. No SPNEGO. No Kerberos. No NTLM. No `TSCredentials`. The TLS handshake still happens, because TLS is providing the wire confidentiality and server authentication. After the TLS handshake, the new RDS-AAD-Auth PDU stream takes over. The user-side credential becomes a PRT-cookie scoped to a Conditional Access application.

<Definition term="Primary Refresh Token (PRT)">
A long-lived OAuth refresh token bound to a Microsoft-Entra-joined or hybrid-joined device. The PRT holds proof of the user's primary authentication (typically including a Windows Hello for Business gesture or FIDO2 ceremony) and signs short-lived JWT cookies that authenticate the user to Entra-ID-integrated applications. The PRT's signing key is held in the device's TPM where possible. See the companion *Entra ID and the Primary Refresh Token* article on this site for the full mechanism.
</Definition>

<Definition term="CloudAP">
The Cloud Authentication Provider, an LSA authentication package introduced for Microsoft Entra ID (then Azure AD) sign-in. CloudAP runs inside `lsass.exe` and manages PRT issuance, refresh, and the minting of PRT-cookies for downstream authentication. On the target side of a PRT-over-RDP session, CloudAP validates the inbound PRT-cookie and produces the user's Windows session token without ever contacting a domain controller [@mollema-prt2].
</Definition>

### The mechanism: from `.rdp` file to Entra-issued session

The client-side flow starts with an `.rdp` connection file that includes `enablerdsaadauth:i:1` [@msl-rdp-files]. The official MSTSC user-facing label is "Use a web account to sign in to the remote computer." When the user clicks Connect:

1. The local CloudAP plugin generates a PRT-cookie scoped to the Conditional Access application `a4a365df-50f1-4397-bc59-1a1564b8bb9c` ("Microsoft Remote Desktop"). The Microsoft Learn documentation pins this app ID verbatim: "Conditional Access policies can be applied to the application **Microsoft Remote Desktop** with ID **a4a365df-50f1-4397-bc59-1a1564b8bb9c** to control access to the remote PC when single sign-on is enabled" [@msl-prtrdp-mstsc].
2. `mstsc.exe` opens TCP/3389 (or UDP/3389 for Shortpath) and sends `RDP_NEG_REQ` with `requestedProtocols = PROTOCOL_RDSAAD (0x10)` [@rdpbcgr-negreq].
3. TLS handshake completes; the target's server certificate is validated against the Entra device-identity.
4. The client sends RDS-AAD-Auth PDUs containing the PRT-cookie [@rdpbcgr-rdsaad].
5. The target's CloudAP plugin validates the cookie against Microsoft Entra ID. Entra ID evaluates the Conditional Access policies that target `a4a365df-...`, including device compliance, location, sign-in risk, and Authentication Strength.
6. On success, Entra ID issues an access token scoped to the target. The target's CloudAP plugin signs the user in. The RDP session starts.

<Mermaid caption="PRT-over-RDP: PROTOCOL_RDSAAD takes the place of CredSSP. No SPNEGO, no Kerberos, no NTLM. The user's credential is a JWT bound to the Conditional Access app a4a365df-50f1-4397-bc59-1a1564b8bb9c.">
sequenceDiagram
    autonumber
    participant C as Caller (CloudAP + mstsc)
    participant T as Target (CloudAP + termsrv)
    participant E as Microsoft Entra ID
    C->>C: CloudAP mints PRT-cookie for a4a365df
    C->>T: RDP_NEG_REQ (PROTOCOL_RDSAAD 0x10)
    T-->>C: RDP_NEG_RSP (PROTOCOL_RDSAAD selected)
    C->>T: TLS handshake
    C->>T: RDS-AAD-Auth PDU with PRT-cookie
    T->>E: Validate cookie + apply CA policies
    E-->>T: Access token for target SPN
    T->>T: CloudAP signs user in
    C->>T: RDP session as Entra principal
</Mermaid>

<Definition term="enablerdsaadauth">
The `.rdp` connection-file property that opts into RDS-AAD-Auth (PRT-over-RDP) [@msl-rdp-files]. Verbatim from Microsoft Learn: "Determines whether the client will use Microsoft Entra ID to authenticate to the remote PC. When used with Azure Virtual Desktop, this provides a single sign-on experience. This property replaces the property `targetisaadjoined`." The two valid values are `0` (disable) and `1` (enable).
</Definition>

### Two GUIDs, two purposes

PRT-over-RDP brings two distinct Microsoft Entra IDs into play, and the article must keep them separate.<Sidenote>The user-facing Conditional Access application "Microsoft Remote Desktop" has the application ID `a4a365df-50f1-4397-bc59-1a1564b8bb9c` [@msl-prtrdp-mstsc]. The AVD-side configuration uses a distinct service principal "Windows Cloud Login" with ID `270efc09-cd0d-444b-a71f-39af4910ec45` [@msl-avdsso], configured via `Update-MgServicePrincipal ... -Settings @{ isRemoteDesktopProtocolEnabled = $true }`. Both IDs exist for legitimate reasons; both pages are alive; they configure different layers. The Conditional Access policy in the admin console targets `a4a365df-...`; the AVD-side enablement flag flips on `270efc09-...`.</Sidenote> The `a4a365df-...` application is the user-facing PRT-cookie audience; Conditional Access policies that gate RDP sign-in (require WHfB, require compliant device, block from foreign geographies) target this app ID. The `270efc09-...` service principal is the AVD-side enablement flag for the configuration described in Azure Virtual Desktop documentation: "Your session hosts must be Microsoft Entra joined or Microsoft Entra hybrid joined. Session hosts joined to Microsoft Entra Domain Services or to Active Directory Domain Services only aren't supported" [@msl-avdsso].

> **Note:** PRT-over-RDP is the first RDP authentication mode whose wire-protocol selector does not have a CredSSP underneath it. `PROTOCOL_RDSAAD (0x10)` [@rdpbcgr-negreq] is its own path. The user's credential is a JWT cookie [@msl-prtrdp-mstsc] signed by a key derived from the device's session key (and bound to the TPM where possible). There is no NTLM hash to extract from the target; there is no Kerberos session key to relay. The residual surface is PRT-extraction from the *caller's* CloudAP cache -- not from the target.

PRT-over-RDP is the first RDP authentication mode that is intrinsically phishing-resistant when paired with Windows Hello for Business [@msl-prtrdp-mstsc]. It is also the first mode that requires both endpoints to be Microsoft-Entra-joined (or hybrid-joined) [@msl-avdsso]. A 2026 enterprise estate ends up running all five modes in parallel -- none retiring the others -- because no single Pareto-optimal point dominates the others.

## 8. Five Modes, One Matrix, 2026 Operational Reality

By 2026 the RDP authentication stack ships five compositional modes, negotiated by two distinct mechanisms in MS-RDPBCGR. The `requestedProtocols` field [@rdpbcgr-negreq] selects between classic RDP, TLS, CredSSP, and RDS-AAD-Auth. The `flags` byte signals the Restricted Admin and Remote Credential Guard sub-modes inside CredSSP. A real estate runs all five in different connection paths. None of them retire the others.

The Microsoft Learn page for Remote Credential Guard publishes the canonical practitioner-grade comparison matrix [@msl-rcg]. Reproducing it verbatim:

| Property | Remote Desktop | Remote Credential Guard | Restricted Admin |
|---|---|---|---|
| Single sign-on (SSO) for sessions | Yes | Yes | No |
| Multi-hop RDP | Yes | Yes | No |
| Prevent use of user's identity during connection | No | No | Yes |
| Prevent use of credentials after disconnection | No | Yes | Yes |
| Prevent Pass-the-Hash | No | Yes | Yes |
| Supported authentication | Any negotiable by SSP | Kerberos only | Any negotiable by SSP |
| Credentials supported from the client device | Signed-in creds, supplied creds, saved creds | Signed-in creds only | Signed-in creds, supplied creds, saved creds |
| RDP access granted with | Remote Desktop Users (target) | Remote Desktop Users (target) | Administrators (target) |

The matrix anchors three points of precision. First, "Prevent use of user's identity during connection" is `No` for both classic Remote Desktop *and* Remote Credential Guard. Only Restricted Admin can promise that the user's identity is not exercised on the target -- because only Restricted Admin replaces the user's identity with the target's machine identity.

Second, "Prevent use of credentials after disconnection" is `Yes` for Remote CG and Restricted Admin but `No` for classic. Third, "RDP access granted with" is the *access control* primitive, not the *credential* primitive: Restricted Admin demands Administrators-group membership on the target because the user is impersonating the machine account.

The matrix excludes the two non-CredSSP modes -- classic-RDP (`PROTOCOL_RDP = 0x00`) and PRT-over-RDP (`PROTOCOL_RDSAAD = 0x10`). Extending the matrix to all five modes:

| Property | Classic RDP | NLA (CredSSP) | Restricted Admin | Remote Credential Guard | PRT-over-RDP |
|---|---|---|---|---|---|
| Wire selector | `PROTOCOL_RDP 0x00` | `PROTOCOL_HYBRID 0x02` | CredSSP + `0x01` flag | CredSSP + `0x02` flag | `PROTOCOL_RDSAAD 0x10` |
| Credential delivered to target | Password in RC4 channel | Password in TLS (TSPasswordCreds) | Empty TSPasswordCreds | TSRemoteGuardCreds handle | Entra PRT-cookie (JWT) |
| Target session identity | User | User | Machine (`TARGET$`) | User | User (Entra principal) |
| User credential at target lsass | Yes (NT-OWF + plaintext) | Yes (NT-OWF) | No | No | No |
| SSO to downstream services | Yes | Yes | No | Yes (via caller RPC) | Yes (Entra token cache) |
| Multi-hop RDP | Yes | Yes | No | Yes | Yes (Entra) |
| Requires Administrators on target | No | No | Yes | No | No |
| NTLM fallback allowed | Yes | Yes | Yes | No | No |
| Pre-auth-RCE protection (NLA) | No | Yes | Yes | Yes | Yes (via TLS-first gate) |
| First shipped | RDP 4.0 / 1998 | RDP 6.0 / Vista / Nov 2006 | Win 8.1 / Server 2012 R2 / Oct 17, 2013 | Win 10 1607 / Server 2016 / Aug 2, 2016 | KB5018418 / Oct 11, 2022 |
| Canonical CVE | BlueKeep (channel-setup) | CVE-2018-0886 (CredSSP RCE) | RBCD against TERMSRV | Kerberos RBCD residual | PRT-extraction at session host |

> **Key idea:** The five modes are not strictly ordered. Each occupies a different point on the Pareto frontier of (no-credential-leak × SSO × universality × Kerberos-compatibility). An operator's job is to choose two of \{Entra-issued sessions, on-prem Kerberos SSO, no credential delegation, no local-admin requirement\} per RDP pair -- the matrix exists because nobody gets all four.

The 2026 operational defaults split along clean lines. The universal baseline is `NLA mandatory` (refuse `PROTOCOL_RDP = 0x00`), `AllowEncryptionOracle = 0` (Force Updated Clients) [@msl-kb4093492], NTLMv1 disabled at the domain controller, and the target-side GPO "Remote host allows delegation of nonexportable credentials" set so Remote CG can opt in without prompting. On top of that baseline:

- Admin-tier jump servers: Restricted Admin (`RestrictedRemoteAdministration` GPO mode 1, "Require Restricted Admin") [@msl-rcg].
- User-tier domain RDP: Remote Credential Guard (`RestrictedRemoteAdministration` GPO mode 2 for "Require Remote Credential Guard", or mode 3 for "Restrict credential delegation" -- the composite that prefers Remote CG and falls back to Restricted Admin when Remote CG cannot complete) [@msl-rcg].
- Entra-joined estates and AVD / Cloud-PC: PRT-over-RDP via `enablerdsaadauth:i:1` [@msl-rdp-files], gated by Conditional Access on the `a4a365df-...` app [@msl-prtrdp-mstsc].
- Legacy compatibility lane: NLA-mandatory classic CredSSP, accepting that the target's lsass will hold credential material for the session duration.

> **Note:** Regardless of which higher-level mode you choose, four settings should be on every Windows target before you read further: NLA mandatory; `AllowEncryptionOracle = 0` [@msl-kb4093492]; NTLMv1 disabled; "Remote host allows delegation of nonexportable credentials" set so Remote CG opt-in does not prompt. These four are the floor. Everything else is a per-target choice on top of them.

The matrix is the load-bearing artifact. The next four sections walk what it does not solve: the perimeter mitigations the matrix excludes, the theoretical limits no mode can close, the open problems still in the literature, and the practical guide an operator runs on Monday.

## 9. Adjacent Mitigations: What Else Protects RDP (And What It Does Not Protect)

Six adjacent mechanisms get called "RDP security" in vendor marketing. None of them are credential-protection mechanisms. They solve different problems at different layers, and conflating them with the five-mode matrix is the load-bearing operational confusion in modern RDP deployments.

**Remote Desktop Gateway / RDS Gateway.** A network-layer reverse-proxy that tunnels RDP inside HTTPS on TCP/443. The Gateway terminates the TLS connection from the internet, authenticates the user (often via smart card or Microsoft Entra), and forwards the inner RDP session to the back-end target. Gateway solves "RDP exposed to the internet on TCP/3389." It does not change which CredSSP sub-mode the inner session negotiates. If the inner session is classic-NLA, the target's lsass receives the user's NT-OWF, gateway or not.

> **Note:** A common misconception is that an RDS Gateway "protects credentials." It does not. The Gateway proxies the RDP session, which still negotiates classic, Restricted Admin, Remote CG, or PRT-over-RDP between the client and the back-end target. The Gateway is a perimeter primitive, not an authentication mode. An operator who deploys RDS Gateway *and* enforces Remote CG on the back-end pool has stacked two complementary mitigations. An operator who deploys RDS Gateway and leaves the back-end pool on classic NLA has hardened the perimeter without changing the post-exploitation pivot.

**Just-Enough Administration (JEA) over PowerShell Remoting.** The "don't use RDP for admin in the first place" answer. JEA constrains a PowerShell Remoting session to a curated set of cmdlets executed under a managed virtual account. The transport is WSMan over HTTPS (TCP/5986 with TLS, or TCP/5985 plain), not RDP.

WSMan has its own CredSSP exposure -- CVE-2018-0886 affects WinRM as well as RDP [@nvd-2018-0886] -- but a JEA endpoint configured for `RunAsVirtualAccount` does not delegate the operator's credentials at all. JEA combined with Remote Credential Guard for the remaining graphical-admin paths is the de facto 2026 reference architecture for admin-tier work.

<Definition term="Just-Enough Administration (JEA)">
A PowerShell-Remoting feature that constrains a remote session to a whitelisted set of commands executed under a managed virtual account, eliminating credential delegation for the operator. JEA is not an RDP mode; it is the "use a different protocol entirely" alternative for administrative tasks that do not need a graphical session. Configured via PowerShell session-configuration files (`.pssc`) and role-capability files (`.psrc`).
</Definition>

**Smart-card and FIDO2 as the underlying credential.** A user can authenticate to NLA / CredSSP using a smart card (Kerberos with PKINIT) or, for PRT-over-RDP, a Windows Hello for Business or FIDO2 ceremony. The credential type matters for *phishing resistance* and for *replayability*. It does not change what the target ends up with after the CredSSP exchange completes. A smart-card-backed NLA session still ends with a Kerberos session key in the target's `lsass.exe`. Phishing-resistant authentication is necessary but not sufficient; the post-exchange credential isolation lives in Restricted Admin, Remote CG, or PRT-over-RDP.

**Azure Bastion / AWS Session Manager.** Cloud-managed jump-host services that present a web UI and proxy RDP / SSH connections to back-end VMs without exposing 3389 to the internet. Bastion handles the network-layer exposure problem. The credential-protection guarantees still depend on which CredSSP sub-mode the inner RDP session negotiates. Bastion does not magic away the requirement to also configure Restricted Admin or Remote CG on the back-end pool.

**RDP-over-QUIC / AVD RDP Shortpath.** The Microsoft Azure Virtual Desktop "Shortpath" feature carries RDP traffic over UDP, with four variants documented verbatim on Microsoft Learn: "RDP Shortpath for managed networks; RDP Shortpath for managed networks with ICE/STUN; RDP Shortpath for public networks with ICE/STUN; RDP Shortpath for public networks via TURN" [@msl-shortpath]. The transport sits on QUIC, the UDP-based transport standardised in RFC 9000 [@rfc-9000].

The Tech Community announcement of public-networks GA states verbatim: "We are pleased to announce the general availability of RDP Shortpath for public networks... We started deploying RDP Shortpath in September and now the feature is 100% rolled out" [@tc-shortpath-blog]; the announcement is dated late 2022. The TURN-relayed variant is GA in late 2024 per the Microsoft AVD blog series.

<Definition term="RDP Shortpath">
Microsoft's QUIC/UDP transport for RDP, used inside Azure Virtual Desktop and Windows 365 [@msl-shortpath]. Four variants cover managed networks, ICE/STUN-mediated traversal, public-network NAT traversal, and TURN-relayed paths through restrictive NAT. The authentication stack above the transport is unchanged from TCP-based RDP; QUIC replaces TCP/TLS with UDP/QUIC at the bottom of the stack only.
</Definition>

What changes with QUIC transport is the detection surface. Network sensors keyed on `TCP/3389 + TLS handshake + CredSSP TS Request/Response` see nothing for an AVD Shortpath session; what they should look for instead is `UDP/&lt;ephemeral&gt; + QUIC handshake + STUN/ICE candidate exchange`. The credential-protection guarantees are *identical* to the underlying RDP mode; the visibility-engineering work is real.<Sidenote>FreeRDP and xrdp -- the two widely-used non-Microsoft RDP stacks -- implement a subset of the five modes. xrdp does not implement CredSSP server-side, so xrdp targets are reachable only via `PROTOCOL_RDP` or `PROTOCOL_SSL`; an operator who enables NLA on an xrdp host has effectively prevented Windows clients from connecting. FreeRDP supports classic, NLA / CredSSP, and Restricted Admin as a client, but does not implement Remote Credential Guard or PRT-over-RDP. Detection engineering for mixed-stack estates must account for these limits.</Sidenote>

**Conditional Access, Microsoft Entra PIM, Just-In-Time access.** Workflow-level controls that *grant* RDP access (the user must satisfy a PIM activation request before the JIT-provisioned admin group adds them; the Conditional Access policy must pass before the PRT-cookie is minted). These are orthogonal to what happens *during* the RDP session. A PIM-elevated admin session that runs classic-NLA RDP still leaves the admin's credential in the target's lsass when the session ends.

None of these mechanisms change the credential the target ends up with. That is the load-bearing fact. The next section walks the four classes of attack that no RDP mode -- regardless of how many adjacent mitigations are stacked -- can close.

## 10. Theoretical Limits: The Four Things RDP Authentication Cannot Close

The five modes between them close credential delegation (Restricted Admin), credential-after-disconnection (Restricted Admin and Remote CG), the password-and-hash entirely (PRT-over-RDP), and the pre-auth channel-setup surface (NLA). The four limits below are what is left. Each has a formal lower bound. None is closable by a sixth mode.

### Limit 1: The SYSTEM-on-target floor

Any RDP mode that grants the user an actionable identity on the target permits a `SYSTEM`-on-target adversary to use that identity for as long as the user stays connected. The session host kernel must materialise the user's security token to enforce ACL checks. An attacker with `SYSTEM` on the target can call `OpenProcessToken` against any process in the user's session, then `DuplicateTokenEx` and `ImpersonateLoggedOnUser` to perform actions as the user. Microsoft Learn encodes this as "Prevent use of user's identity during connection: No" for both Remote Desktop and Remote Credential Guard [@msl-rcg].

<PullQuote>
"Remote Credential Guard helps protecting credentials over a Remote Desktop (RDP) connection by redirecting Kerberos requests back to the device that's requesting the connection. If the target device is compromised, the credentials aren't exposed because both credential and credential derivatives are never passed over the network to the target device." -- Microsoft Learn [@msl-rcg]
</PullQuote>

That sentence promises protection of *credentials*. It does not promise protection of the user's identity in-session. The two properties are different and only one is closable by an authentication-protocol redesign.

> **Note:** No RDP mode can simultaneously give the target the ability to act as the user *and* prevent a SYSTEM adversary on the target from acting as the user. The defense is not to close in-session impersonation; the defense is to not put the user on a compromised target. Restricted Admin closes it by giving up the user's identity entirely. Every mode that preserves the user's identity (classic, NLA, Remote CG, PRT-over-RDP) leaves the SYSTEM-on-target floor open.

### Limit 2: The CredSSP residue

Even on a 2026 Entra-joined estate using PRT-over-RDP, CredSSP remains on the wire for every RDP path touching a non-Entra-joined endpoint. Legacy admin tooling, multi-hop sessions into on-prem servers, RDS deployments, hybrid scenarios -- all of them fall back to CredSSP. CredSSP has shipped at least one logical-flaw RCE (CVE-2018-0886) [@nvd-2018-0886] and the `AllowEncryptionOracle` compatibility window [@msl-kb4093492] remains a deployment hazard whenever a new CredSSP patch ships.

The architectural answer (deprecate CredSSP wholly, replace it with RDS-AAD-Auth for every RDP path) is not on Microsoft's public roadmap. MS-CSSP's current revision is 21.0, dated April 23, 2024 [@mscssp-index] -- the protocol is actively maintained, not deprecated. Operationally, CredSSP is a permanent fixture of any Windows estate that includes on-premises identity.

### Limit 3: The RBCD-against-TERMSRV class

Restricted Admin closes credential delegation. It does not close the machine-identity-as-attack-primitive class. Any principal that can write `msDS-AllowedToActOnBehalfOfOtherIdentity` on a target's computer object can S4U2self + S4U2proxy a `TERMSRV/<target>` ticket and RDP in as any account -- including a Domain Admin [@shamir-wagging]. Dec0ne's KrbRelayUp productionises this as "a universal no-fix local privilege escalation in windows domain environments where LDAP signing is not enforced (the default settings)" [@krbrelayup].

The phrase "no-fix" is doing real work. The chain depends on default LDAP-signing settings, default kerberos delegation behaviour for resource-based constrained delegation, and the user-creatable computer object quota of `ms-DS-MachineAccountQuota = 10` [@shamir-wagging] -- four configurations that are independently defensible per protocol but that compose into the chain. Tightening any one of them mitigates KrbRelayUp; Microsoft has not chosen to do so by default.

### Limit 4: The Entra-only / on-prem-only gap

PRT-over-RDP requires both endpoints to be Microsoft-Entra-joined or hybrid-joined [@msl-prtrdp-mstsc, @msl-avdsso]. Restricted Admin and Remote CG require Kerberos and on-premises Active Directory. The two architectures do not compose: a non-hybrid Entra-joined estate cannot deploy Restricted Admin or Remote CG; an on-prem-AD estate cannot deploy PRT-over-RDP. Hybrid join is the bridging primitive, but it has its own configuration cost (Entra Connect, device-write-back, certificate trust, password hash sync), and many estates have hybrid-join enabled for only a subset of devices.

<Aside label="Pareto frontier, not strict ordering">
The five RDP modes occupy different points on a four-axis Pareto frontier: (no-credential-leak × SSO × universality × Kerberos-compatibility). No mode dominates any other on all four axes simultaneously.

- Classic credential delegation gives universality and SSO and Kerberos-compatibility, at the cost of credential-leak protection.
- NLA via CredSSP adds pre-auth-RCE gating, but the credential-leak axis is identical to classic.
- Restricted Admin gives credential-leak protection and Kerberos-compatibility, at the cost of SSO and the universality of the "any user" property (because of the Administrators-group requirement).
- Remote Credential Guard gives credential-leak protection and SSO, at the cost of universality (Kerberos-only).
- PRT-over-RDP gives credential-leak protection and SSO and modern phishing-resistant authentication, at the cost of Kerberos-compatibility and the Entra-joined-everywhere requirement.

The operator's job is composition: pick the mode that matches each RDP pair's constraints, accept that two of the four axes will fail for that pair, and use the other modes for the other pairs. A typical 2026 enterprise pool runs (at least) NLA-mandatory classic for legacy, Restricted Admin for admin-tier, Remote CG for user-tier domain RDP, and PRT-over-RDP for AVD. Four authentication modes on one estate is the normal state.
</Aside>

Three of the four limits are bounded: they may shrink as Microsoft deprecates NTLM, ships VBS-trustlet protection for CloudAP on session hosts, or unifies the Entra and on-prem identity surfaces. One is architectural and applies to every authentication protocol ever proposed: `SYSTEM` on the target equals the user's identity for as long as the user stays connected. The next section walks the active research where the bounded limits are still moving.

## 11. Open Problems: Where Research and Operations Are Still Moving

Five open problems sit on the RDP authentication stack right now. Three are research-class. Two are operational-class. None has a "just ship a patch" answer.

### Open Problem 1: PRT extraction at the session host

A session host that serves N concurrent RDP-in connections with PRT-over-RDP caches at least N CloudAP entries. A SYSTEM adversary on the session host can dump all of them. Dirk-jan Mollema's August 2020 follow-up to his original PRT abuse research [@mollema-prt2] describes the underlying primitive in collaboration with Benjamin Delpy (Mimikatz author). The verbatim quote is decisive:

<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. Interesting enough, it turns out that 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* (2020) [@mollema-prt2]
</PullQuote>

That property -- the PRT and session key are recoverable from CloudAP `lsass.exe` memory irrespective of TPM protection -- holds on the *receiving* session host the same way it holds on the *issuing* device. This is the 2026 mirror of the 2008 "RDP into the Citrix jump server and dump credentials" problem.

The architectural answer is to run CloudAP inside a VBS trustlet (analogous to `LsaIso.exe` for NTLM and Kerberos) on every session host. Microsoft has not publicly committed to that work. The original PRT post [@mollema-prt1] notes that "if there is no TPM the keys are stored in software... If a TPM is present, the keys required to request or use the PRT are protected by the TPM and can't be extracted under normal circumstances" -- but "under normal circumstances" excludes the `SYSTEM`-on-target adversary the session-host scenario assumes.

### Open Problem 2: CredSSP is not deprecable

MS-CSSP revision 21.0 (April 23, 2024) [@mscssp-index] is a maintained protocol; no Microsoft roadmap deprecates it. The role transitions from "the authentication layer for RDP and WinRM" to "the compatibility shim for everything that does not speak RDS-AAD-Auth," but compatibility shims do not retire in the absence of a forcing function. Every CredSSP CVE in the next decade lands on a still-deployed surface. The `AllowEncryptionOracle` deployment pattern [@msl-kb4093492] is not the last of its kind.

### Open Problem 3: Remote CG NTLM exclusion and the hybrid-estate user experience

Remote Credential Guard is Kerberos-only [@msl-rcg]. The `RestrictedRemoteAdministration` GPO mode 3 is the composite "Restrict credential delegation" policy that prefers Remote CG and falls back to Restricted Admin when Remote CG cannot complete [@msl-rcg].

The result is a fragmented user experience: on Monday a user RDPs to `server01` and gets Remote CG (SSO works); on Tuesday the user RDPs to `server02` whose DC trust path has a transient routing problem and gets Restricted Admin (SSO does not work). The user observes "RDP to server02 is broken" and files a ticket; the platform team observes "the GPO fall-back is working as designed." This pattern persists until NTLM is universally removed from the estate, which is itself an open multi-year project. See the companion *NTLMless* article on this site for the wider deprecation arc.

### Open Problem 4: The Entra / on-prem composition gap

Real enterprise estates are a Venn diagram of Entra-only desktops, hybrid-joined Windows 11 laptops, and on-prem-AD-only servers. PRT-over-RDP works between Entra-joined and hybrid-joined endpoints [@msl-prtrdp-mstsc]; Restricted Admin and Remote CG work between Kerberos-routable endpoints; the four cells in the 2x2 (\{client-Entra, client-AD\} x \{target-Entra, target-AD\}) have different authentication paths. Hybrid join bridges the two architectures for devices that support it. A conjecture worth stating plainly: the two architectures will not fully converge before 2030. The intermediate state -- four authentication modes running on the same estate at the same time -- is the steady state, not a transition.

### Open Problem 5: Windows 11 24H2 KIR as a deployment-fault recovery surface

In early 2025, Windows 11 24H2 shipped an authentication-stack change that broke CredSSP-mediated RDP in a subset of configurations, manifesting as session hangs at the login screen or 65-second disconnects mid-session. Microsoft rolled out a Known Issue Rollback ("KIR") via Group Policy in March 2025; the policy name is widely attributed in industry press as "Windows 11 24H2 and Windows Server 2025 KB5053598 250314_20401 Known Issue Rollback." The Windows 11 24H2 release-health page now reads "There are no active known issues at this time" as of March 27, 2025 [@msl-24h2-status], indicating the KIR cycle has resolved.

> **Note:** Known Issue Rollback is now a primary operational tool for managing authentication-stack regressions in Windows. When a feature update breaks CredSSP, RDP, or any other load-bearing authentication primitive, the response is no longer "wait for the next monthly patch"; it is "push the KIR-disable Group Policy through your management plane." Operators should be familiar with the KIR mechanism *before* the next regression cycle. The 2025 24H2 RDP regression [@msl-24h2-status] is the worked example.

### Open Problem 6: QUIC transport and the network-layer detection surface

AVD RDP Shortpath for public networks has been GA since late 2022 [@tc-shortpath-blog, @msl-shortpath]; the TURN-relayed variant is GA from late 2024. QUIC is specified in RFC 9000 [@rfc-9000] and replaces TCP/3389 + TLS with UDP/&lt;ephemeral&gt; + QUIC. The IOC surface for "RDP session in progress" changes from a TLS handshake plus CredSSP TS Request/Response on TCP/3389 to a QUIC handshake plus STUN/ICE candidate exchange on a UDP port assigned at runtime.

Network-detection engineering for this surface has not finished re-tuning. A reasonable conjecture: the QUIC detection surface stabilises by 2027 around per-tenant Conditional Access app-ID telemetry (sign-in log entries for `a4a365df-50f1-4397-bc59-1a1564b8bb9c` [@msl-prtrdp-mstsc]) rather than network-layer packet signatures.

These open problems share a common shape. They are all about *composition*. The five modes have to interoperate; the credential-isolation has to extend to the session host; the detection has to span TCP and QUIC. None of them has a feature-shaped answer. The next section walks the practical guide for making the existing primitives work in your environment today.

## 12. Practical Guide, FAQ, and Closing

Here is what to do with this stack this week, depending on which side of the wire you live on.

### For the administrator / platform engineer

The four configurations below are the universal baseline. Set them everywhere; then choose a higher-level mode per RDP pair.

1. **Enforce NLA.** GPO: *Computer Configuration -> Administrative Templates -> Windows Components -> Remote Desktop Services -> Remote Desktop Session Host -> Security -> Require user authentication for remote connections by using Network Level Authentication*. Verify with PowerShell: `(Get-WmiObject -Class Win32_TSGeneralSetting -Namespace root\CIMV2\TerminalServices -Filter "TerminalName='RDP-Tcp'").UserAuthenticationRequired` returns `1`.

2. **Enforce `AllowEncryptionOracle = 0`.** Set "Encryption Oracle Remediation" to "Force Updated Clients" under *Computer Configuration -> Administrative Templates -> System -> Credentials Delegation*. Verify with `Get-ItemProperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters'` -- the `AllowEncryptionOracle` value should be `0` [@msl-kb4093492].

3. **Deploy Restricted Admin or Remote CG.** Set the `RestrictedRemoteAdministration` GPO mode under "Restrict delegation of credentials to remote servers" to `1` (Require Restricted Admin), `2` (Require Remote Credential Guard), or `3` (Restrict credential delegation -- the composite that prefers Remote CG and falls back to Restricted Admin when Remote CG cannot complete). Pair with the target-side "Remote host allows delegation of nonexportable credentials" GPO [@msl-rcg].

4. **Enable PRT-over-RDP for Entra-joined estates.** Distribute `.rdp` files with `enablerdsaadauth:i:1` [@msl-rdp-files]; gate sign-in via Conditional Access policy on the application `a4a365df-50f1-4397-bc59-1a1564b8bb9c` [@msl-prtrdp-mstsc]; pair with Windows Hello for Business or FIDO2 for phishing-resistant primary authentication.

Before enabling Remote CG on any target, inventory the NTLM-only paths into it. Workgroup machines, machines whose target SPN registration is incomplete, machines reachable only across DC-isolating firewall rules -- all of them will refuse the Remote CG negotiation when Kerberos cannot complete.

<Spoiler kind="solution" label="Optional: GPO paths and registry values for the 2026 baseline">
The exact GPO and registry settings for the four-baseline configuration:

- **NLA**: `Computer Configuration -> Administrative Templates -> Windows Components -> Remote Desktop Services -> Remote Desktop Session Host -> Security -> Require user authentication for remote connections by using Network Level Authentication`. Registry: `HKLM\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp\UserAuthentication = 1`.
- **AllowEncryptionOracle**: `Computer Configuration -> Administrative Templates -> System -> Credentials Delegation -> Encryption Oracle Remediation -> Force Updated Clients`. Registry: `HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters\AllowEncryptionOracle = 0`.
- **Restricted Admin / Remote CG**: `Computer Configuration -> Administrative Templates -> System -> Credentials Delegation -> Restrict delegation of credentials to remote servers`. Registry: `HKLM\Software\Policies\Microsoft\Windows\CredentialsDelegation\RestrictedRemoteAdministration = 1|2|3` (1 = Require Restricted Admin; 2 = Require Remote Credential Guard; 3 = Restrict credential delegation -- the composite that prefers Remote CG and falls back to Restricted Admin when Remote CG cannot complete) [@msl-rcg].
- **Target-side trust**: `Computer Configuration -> Administrative Templates -> System -> Credentials Delegation -> Remote host allows delegation of nonexportable credentials -> Enabled`.

Apply via Group Policy, Intune ADMX, or local policy. Reboot is not required for these settings to take effect, but new RDP connections must be opened after the policy applies for the negotiation to reflect the new state.
</Spoiler>

### For the security researcher

The wire-level distinction between modes is observable. Capture an RDP handshake with Wireshark (the RDP dissector is built-in). The `RDP_NEG_REQ` and `RDP_NEG_RSP` packets show the `requestedProtocols` and `selectedProtocol` fields and the Restricted Admin / Remote CG flag bits. `PROTOCOL_HYBRID = 0x02` plus `RESTRICTED_ADMIN_MODE_SUPPORTED = 0x08` in the response indicates the negotiated CredSSP sub-mode.

<RunnableCode lang="js" title="Decode an RDP_NEG_RSP selectedProtocol value">{`
// MS-RDPBCGR selectedProtocol bitmask: see learn.microsoft.com/.../b2975bdc
function decodeNegRsp(selectedProtocol, flags) {
  const protocols = [];
  if ((selectedProtocol & 0x01) !== 0) protocols.push("PROTOCOL_SSL (TLS)");
  if ((selectedProtocol & 0x02) !== 0) protocols.push("PROTOCOL_HYBRID (CredSSP)");
  if ((selectedProtocol & 0x04) !== 0) protocols.push("PROTOCOL_RDSTLS");
  if ((selectedProtocol & 0x08) !== 0) protocols.push("PROTOCOL_HYBRID_EX");
  if ((selectedProtocol & 0x10) !== 0) protocols.push("PROTOCOL_RDSAAD (Entra)");
  if (protocols.length === 0) protocols.push("PROTOCOL_RDP (classic)");
  const subModes = [];
  if ((flags & 0x08) !== 0) subModes.push("Restricted Admin supported");
  if ((flags & 0x10) !== 0) subModes.push("Remote Credential Guard supported");
  console.log("Protocols:", protocols.join(" + "));
  console.log("Sub-modes:", subModes.length ? subModes.join(", ") : "none");
}
// Example: PROTOCOL_HYBRID + Remote CG flag
decodeNegRsp(0x02, 0x10);
// Example: PROTOCOL_RDSAAD (PRT-over-RDP)
decodeNegRsp(0x10, 0x00);
`}</RunnableCode>

On the target, the distinction between Restricted Admin and the other modes shows up in the Windows event log. Event 4624 (logon-type 10, RemoteInteractive) records the subject; for Restricted Admin the subject is `TARGET$` (the machine account) while for classic, Remote CG, and PRT-over-RDP it is the user's account. A quick check: open an elevated `cmd` inside the RDP session and run `whoami`. Returns `<target>$` under Restricted Admin; returns the user's domain or Entra account otherwise.

<RunnableCode lang="python" title="Verify the RDP authentication stack (PowerShell-equivalent in Python)">{`
# Mirrors four PowerShell checks an operator runs on a Windows target.
checks = {
    "NLA required": "(Get-WmiObject Win32_TSGeneralSetting -Namespace root/CIMV2/TerminalServices -Filter \\"TerminalName='RDP-Tcp'\\").UserAuthenticationRequired",
    "AllowEncryptionOracle == 0": "(Get-ItemProperty 'HKLM:/Software/Microsoft/Windows/CurrentVersion/Policies/System/CredSSP/Parameters').AllowEncryptionOracle",
    "Restricted Admin GPO": "(Get-ItemProperty 'HKLM:/Software/Policies/Microsoft/Windows/CredentialsDelegation').RestrictedRemoteAdministration",
    "PRT-over-RDP opt-in": "Select-String -Pattern 'enablerdsaadauth:i:1' (Get-ChildItem -Recurse -Filter *.rdp)",
}
expected = {"NLA required": 1, "AllowEncryptionOracle == 0": 0,
            "Restricted Admin GPO": "1, 2, or 3", "PRT-over-RDP opt-in": "present in .rdp file"}
for label, cmd in checks.items():
    print(f"{label}: expect {expected[label]}; run -> {cmd}")
`}</RunnableCode>

For PRT-over-RDP detection, the highest-fidelity signal lives in Microsoft Entra ID's sign-in logs: a successful sign-in entry against the application ID `a4a365df-50f1-4397-bc59-1a1564b8bb9c` [@msl-prtrdp-mstsc] indicates an RDP session was authenticated using the Entra path. Correlate with the target's local event log for the same user / timestamp to verify session establishment.

### For the red-team operator

The post-exploitation pivots differ by mode, as the four `sekurlsa::logonpasswords` dumps in §1 illustrated:

- **Classic / NLA**: Pass-the-Hash against the target's `lsass.exe` cache is trivial. `sekurlsa::logonpasswords` returns user's NT-OWF.
- **Restricted Admin**: PtH yields the target's machine account (`TARGET$`), not the user. Pivot: RBCD against `TERMSRV` via the Wagging-the-Dog chain [@shamir-wagging] or KrbRelayUp [@krbrelayup].
- **Remote Credential Guard**: PtH yields nothing useful for the user; the credential never reached the target. Pivot: in-session impersonation via SYSTEM-on-target while the user is connected; use `OpenProcessToken` against a user-session process.
- **PRT-over-RDP**: No NTLM hash, no Kerberos ticket. Pivot: PRT extraction (`sekurlsa::cloudap`) from the target's CloudAP cache; the Dirk-jan Mollema PRT-cookie-mint flow [@mollema-prt2] applies.

### For the detection engineer

Five signal sources, ranked by fidelity:

1. The `selectedProtocol` and `flags` fields in the `RDP_NEG_RSP` packet identify the negotiated mode at the wire.
2. Event 4624 (logon-type 10) on the target identifies the session principal: machine-account name under Restricted Admin, user name otherwise.
3. `Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational` Event ID 1149 records successful RDP session connections.
4. RDS Gateway connection logs, if a Gateway is in the path.
5. Microsoft Entra ID sign-in logs for the application ID `a4a365df-50f1-4397-bc59-1a1564b8bb9c` [@msl-prtrdp-mstsc] for PRT-over-RDP sessions.

For BlueKeep-class detection on patched estates: the `MS_T120` channel name appearing in an RDP `Erect Domain Request` or `Attach User Request` is a high-fidelity IOC. Legitimate clients do not request that channel by name [@wiki-bluekeep].

<FAQ title="Frequently asked questions">

<FAQItem question="Is Network Level Authentication a separate protocol?">
No. NLA is the *policy* on the RDP server that requires authentication before the RDP session is established (before the basic-settings exchange and virtual-channel binding). NLA is *implemented by* CredSSP -- the Credential Security Support Provider, specified in MS-CSSP [@mscssp-index] -- running over TLS. When operators say "we require NLA," they mean "we accept only `requestedProtocols = PROTOCOL_HYBRID` or `PROTOCOL_HYBRID_EX`," both of which select CredSSP under the hood [@rdpbcgr-credssp].
</FAQItem>

<FAQItem question="Does NLA prevent Pass-the-Hash?">
No. NLA prevents pre-authentication remote code execution in the RDP channel-setup code (mitigating BlueKeep [@wiki-bluekeep]) and reduces denial-of-service exposure. NLA does not change what the target's `lsass.exe` ends up holding at the end of the CredSSP exchange. A CredSSP `TSPasswordCreds` exchange ends with the user's password or NT-OWF cached on the target. Mimikatz `sekurlsa::logonpasswords` works against a 2012-era NLA-authenticated target identically to a 1998-era classic-RDP target.
</FAQItem>

<FAQItem question="Are Restricted Admin and Remote Credential Guard the same feature?">
No. Restricted Admin makes the target act as *itself*: the user's session runs as the target's machine account, the target sees no user credentials, but the connecting user must already be a local Administrator on the target [@msl-rcg]. Remote Credential Guard makes the target forward operations *back to the caller*: the session runs as the user, SSO works, the connecting user only needs Remote Desktop Users group membership on the target, but the path is Kerberos-only [@msl-rcg]. Restricted Admin gave up SSO to gain universality. Remote CG kept SSO at the cost of NTLM compatibility.
</FAQItem>

<FAQItem question="Does Remote Credential Guard require Credential Guard to be enabled?">
Partly. Remote Credential Guard always redirects Kerberos challenges to the caller's `lsass.exe`. The long-lived signing material lives in the caller's VTL1 `LsaIso.exe` trustlet *only if* the caller has local Credential Guard enabled. Without local Credential Guard, the material is in regular user-mode `lsass.exe` on the caller. The protocol works in both cases; the protection from a post-compromise of the caller is stronger with local Credential Guard on.
</FAQItem>

<FAQItem question="Is BlueKeep a vulnerability in pre-NLA RDP?">
No. BlueKeep (CVE-2019-0708) is a use-after-free in the `MS_T120` virtual-channel binding inside `termdd.sys`, reachable in the RDP channel-setup phase *before* NLA gating completes [@wiki-bluekeep, @nvd-2019-0708]. NLA shipped natively in every BlueKeep-affected operating system from Windows Vista onward (Windows 7, Server 2008, Server 2008 R2); Windows XP and Server 2003 did not ship NLA natively but could be retrofitted via KB951608 (March 2009). The mitigation guidance "enable NLA" worked because NLA *gates* that pre-auth code path behind a successful CredSSP handshake. BlueKeep is "a vulnerability in the channel-setup code reachable when NLA is not enforced," not "a vulnerability in an era predating NLA."
</FAQItem>

<FAQItem question="Is PRT-over-RDP a 2025 feature?">
No. Microsoft Entra single sign-on for Remote Desktop shipped in the October 11, 2022 cumulative updates: KB5018418 for Windows 11, KB5018410 for Windows 10 20H2 and later, and KB5018421 for Windows Server 2022 [@msl-prtrdp-mstsc, @msl-kb5018418]. The 2025 angles are the Windows 11 24H2 broad GA wave (October 2024) and the March 2025 Known Issue Rollback for a 24H2 RDP regression [@msl-24h2-status]. The Entra-PRT-backed RDP authentication mode itself has been generally available since late 2022.
</FAQItem>

<FAQItem question="Does RDP-over-QUIC replace TCP/3389?">
Only for Azure Virtual Desktop and Windows 365. On-premises RDP defaults to TCP/3389 with TLS. RDP-over-QUIC is implemented in AVD's RDP Shortpath feature, with four variants documented in Microsoft Learn covering managed networks, ICE/STUN traversal, public networks via ICE/STUN, and TURN-relayed paths [@msl-shortpath]. Public-networks GA was announced in late 2022 [@tc-shortpath-blog]; the TURN-relayed variant is GA in late 2024. The QUIC transport itself is RFC 9000 [@rfc-9000]. The authentication stack above the transport is unchanged from TCP-based RDP.
</FAQItem>

</FAQ>

> **Key idea:** The five modes coexist because each makes a different Pareto trade-off, and no estate has the luxury of running just one. The matrix is the artifact you live with.

From password-in-the-pipe to cloud-issued session, every generation of RDP authentication has closed exactly the failure mode that motivated the next. Classic delegation made the credential-aggregation problem visible; NLA gated the pre-auth channel and inadvertently introduced its own CVE class. Restricted Admin gave up the user's identity to stop delivering credentials; Remote Credential Guard recovered the identity at the cost of Kerberos-only routing; PRT-over-RDP abandoned both Kerberos and NTLM in favour of Entra-issued cookies bound to per-application Conditional Access policies.

The residual classes -- RBCD against `TERMSRV`, PRT extraction at the session host, the in-session SYSTEM-on-target floor -- are what is left, and at least one of them is architectural rather than fixable.

The four `sekurlsa::logonpasswords` dumps in §1 are no longer four mysteries. They are four readings of a single matrix: which `requestedProtocols` byte the client offered, which `flags` bits the server accepted, and which credential payload (or which absence of a credential payload) the target received before it built the user's session. The protocol selectors are public. The trade-offs are public. The matrix is yours to compose, RDP pair by RDP pair, with full knowledge of what each choice puts on the wire and what it leaves in `lsass.exe`.

<StudyGuide slug="rdp-security-nla-restricted-admin-remote-credential-guard-and-the-prt-over-rdp-pivot" keyTerms={[
  { term: "NLA", definition: "Network Level Authentication: the server-side policy that requires the client to authenticate via CredSSP before the RDP session is established." },
  { term: "CredSSP", definition: "Credential Security Support Provider, the wire protocol that NLA uses: TLS + SPNEGO + Kerberos or NTLM + TSCredentials." },
  { term: "TSPasswordCreds", definition: "The CredSSP payload carrying the user's password or NT-OWF to the target; empty in Restricted Admin mode." },
  { term: "TSRemoteGuardCreds", definition: "The CredSSP payload used by Remote Credential Guard, carrying a redirect handle rather than a credential." },
  { term: "Restricted Admin", definition: "CredSSP sub-mode that sends empty credentials and runs the user's session as the target's machine account." },
  { term: "Remote Credential Guard", definition: "CredSSP sub-mode that forwards every Kerberos operation back to the caller's lsass via RPC, keeping credentials off the target." },
  { term: "PRT", definition: "Primary Refresh Token, the long-lived Entra refresh token bound to a Microsoft-Entra-joined device, signed by a TPM-protected key where possible." },
  { term: "PROTOCOL_RDSAAD", definition: "RDP_NEG_REQ.requestedProtocols value 0x10 selecting the RDS-AAD-Auth protocol used by PRT-over-RDP." },
  { term: "RBCD", definition: "Resource-Based Constrained Delegation; lets a target's computer object specify which principals can delegate to it via the msDS-AllowedToActOnBehalfOfOtherIdentity attribute." },
  { term: "BlueKeep", definition: "CVE-2019-0708, a pre-auth RCE in the MS_T120 virtual-channel handler in termdd.sys, reachable when NLA is not enforced." }
]} questions={[
  { q: "Why does enabling NLA not prevent Pass-the-Hash?", a: "Because NLA controls when authentication happens, not what is delivered. The CredSSP exchange still ends with the user's NT-OWF in the target's lsass." },
  { q: "What is the central trade-off between Restricted Admin and Remote Credential Guard?", a: "Restricted Admin gives up SSO and multi-hop in exchange for universality (any negotiable authentication); Remote CG keeps SSO and multi-hop in exchange for Kerberos-only routing and an extra RPC per downstream hop." },
  { q: "Why does PRT-over-RDP not need CredSSP?", a: "Because RDS-AAD-Auth replaces the CredSSP exchange with TLS plus RDS-AAD-Auth PDUs carrying an Entra-issued PRT-cookie; there is no SPNEGO, no Kerberos, and no NTLM on the wire." },
  { q: "What is the residual attack class for Restricted Admin?", a: "RBCD against TERMSRV: any principal that can write msDS-AllowedToActOnBehalfOfOtherIdentity on the target's computer object can S4U2self+S4U2proxy a TERMSRV ticket and RDP in as anyone." },
  { q: "What is the SYSTEM-on-target floor?", a: "The architectural property that any RDP mode preserving the user's identity on the target permits a SYSTEM adversary on the target to impersonate the user via OpenProcessToken and ImpersonateLoggedOnUser for the connection's duration." }
]} />
