Most breaches do not stay where they land. An attacker phishes one workstation, dumps the cached credentials in memory, and within the hour is authenticating to a file server, then a management box, then a domain controller — never once exploiting a CVE. The plumbing that makes this work is depressingly consistent across red-team reports and real intrusions alike: SMB carries the traffic, NTLM carries the authentication, and a hash or ticket sitting in LSASS memory carries the identity. Break any one of those links cleanly and the kill chain stalls; break all three and the same intrusion that used to reach Domain Admin in forty minutes never gets off the first host.
This guide hardens all three, end to end, for Windows Server 2019/2022/2025 and Windows 10/11 in an Active Directory domain. We remove SMBv1, enforce SMB signing and AES encryption, adopt SMB over QUIC where it fits, then clamp down on NTLM with audit-then-deny, and deploy virtualization-based Credential Guard so the secrets an attacker wants are no longer reachable from the OS — even with SYSTEM. Around that core we layer the controls that make the difference between “Credential Guard is on” and “lateral movement is actually dead”: the Protected Users group, Windows LAPS for local-admin password uniqueness, Remote Credential Guard and Restricted Admin for RDP, Kerberos armoring (FAST), the Tier administration model, Attack Surface Reduction (ASR) rules, firewall segmentation, and the detection that proves the controls held.
By the end you will be able to map every rung of the lateral-movement ladder — pass-the-hash, NTLM relay, pass-the-ticket, overpass-the-hash, Kerberoasting — to the specific control that severs it, and you will have real Group Policy paths, registry values, and PowerShell to deploy each one. This is dense and reference-shaped on purpose: read the prose once, keep the tables open while you build the GPOs. And test in a pilot ring before you touch production — several of these settings break legacy clients in ways that are obvious in hindsight and outage-shaped in the moment.
What problem this solves
The pain this addresses is the lateral-movement gap: the space between “an attacker has one foothold” and “an attacker owns the domain.” That gap is where almost all of the damage in a modern intrusion happens, and it is almost never bridged by exploiting a vulnerability. It is bridged by reusing credentials the attacker harvested from memory, and by abusing two protocols — SMB and NTLM — that ship enabled, trusting, and under-configured by default.
What breaks without this hardening is the entire premise of containment. You can have endpoint detection everywhere, MFA on every interactive login, and a fully patched fleet, and still watch an operator move from a help-desk workstation to a domain controller without one “exploit” alert — because every step is a legitimate authentication with a stolen but valid secret. The file server accepts the relayed NTLM session (signing not required); the next host accepts the replayed hash (NTLM only proves possession, never the password); the DC accepts the forged ticket (nobody noticed the krbtgt hash walked out). None of it is a bug. It is the protocols doing exactly what they were designed to do in 1996, on a network that assumed the LAN was trustworthy.
Who hits this: every organization running Active Directory, which is to say almost every enterprise. It bites hardest where there is a long tail of legacy — OT/SCADA gateways that still speak SMBv2 and NTLM-by-IP, copiers and NAS that needed SMBv1, line-of-business apps that authenticate with NTLM-only stacks — because the easy answers (rip out SMBv1, deny NTLM everywhere) collide with kit that cannot be changed on your timeline. The art is severing the kill chain without breaking the unpatchable, and that is precisely what the layered, audit-first approach in this article is built to do.
Before the deep dive, here is the whole field on one page: each lateral-movement technique, the carrier it abuses, and the single control that severs it. The rest of the article is the detail behind this table.
| Technique | What the attacker does | Carrier abused | Primary control that severs it | Does the easy fix also stop the others? |
|---|---|---|---|---|
| Pass-the-hash (PtH) | Replays an NTLM hash lifted from LSASS | NTLM over SMB | Credential Guard; restrict/disable NTLM | No — signing does nothing for PtH |
| NTLM / SMB relay | Coerces a victim auth, relays it to a third host | NTLM over SMB/LDAP/HTTP | SMB signing; LDAP channel binding + EPA | No — Credential Guard does nothing for relay |
| Pass-the-ticket (PtT) | Reuses a Kerberos TGT/service ticket from memory | Kerberos | Credential Guard; Protected Users; Tier model | No |
| Overpass-the-hash | Uses an NTLM hash to forge a Kerberos TGT | NTLM hash → Kerberos | Credential Guard; disable RC4; AES-only | Partly |
| Kerberoasting | Cracks a service ticket offline for an SPN’s password | Kerberos service tickets (RC4) | gMSA; AES-only; long passwords; Protected Users | No |
| Golden / Silver ticket | Forges TGT/TGS from the krbtgt or service hash | Kerberos trust in the KDC | krbtgt rotation; Tier-0 isolation; detection | No |
Learning objectives
By the end of this article you can:
- Describe the SMB → NTLM → credential-theft kill chain precisely, and map each lateral-movement technique (PtH, relay, PtT, overpass-the-hash, Kerberoasting, Golden/Silver tickets) to the specific control that severs it.
- Remove SMBv1 safely after auditing for dependencies, and enforce SMB signing and AES-128/256 encryption — server-wide or per-share — via PowerShell and Group Policy.
- Decide when SMB over QUIC is the right answer and configure the certificate, client access control, and firewall it requires.
- Run an audit-then-deny NTLM restriction program: enable fleet-wide NTLM auditing, build the allow-list of legitimate consumers from the operational logs, then deny with surgical server exceptions for unpatchable kit.
- Deploy virtualization-based security and Credential Guard with UEFI lock, confirm it is running (not merely configured), and explain exactly which secrets it does and does not protect.
- Layer the credential-theft defenses: Protected Users, Windows LAPS, Remote Credential Guard and Restricted Admin, Kerberos armoring (FAST), RC4 disablement, and LSASS protection (RunAsPPL).
- Implement the Tier administration model with logon-restriction GPOs and authentication policy silos, and add ASR rules, firewall segmentation, and the detection (Event IDs, KQL) that proves the controls held.
Prerequisites & where this fits
You should be comfortable administering Active Directory and Windows Server: creating and linking Group Policy Objects, editing the registry, running elevated PowerShell, and reading the Windows Event Log. You should know the difference between a domain controller, a member server, and a workstation, and understand that LSASS (the Local Security Authority Subsystem) is the process that holds credential material in memory. Familiarity with how Kerberos issues a TGT (ticket-granting ticket) and service tickets, and how NTLM performs its challenge/response handshake, will make the credential-theft sections land harder — but the article defines each as it goes.
This sits at the center of the Windows security and identity track. It is downstream of building the directory itself — see Building an AD DS Forest the Right Way: Deployment, FSMO, and a Tiered Admin Model for the forest and Tier-0 design this hardening assumes — and it pairs tightly with credential hygiene from Eliminating Static Service Credentials with gMSA and Windows LAPS. The GPO mechanics here are best managed as code; Group Policy at Scale: A Maintainable Architecture and Managing GPOs as Code is the discipline that keeps these dozens of settings reviewable and reversible. For the broader strategy this fits inside, Zero Trust Architecture Blueprint: Identity, Network, and Data Pillars frames lateral-movement defense as the network-and-identity pillar of a larger model.
A quick map of who owns what during this rollout, so the right team confirms the right control:
| Layer | What lives here | Who usually owns it | Lateral-movement step it gates |
|---|---|---|---|
| SMB transport | Signing, encryption, dialects, QUIC | Server / storage team | NTLM relay, SMBv1 worms |
| NTLM policy | Restrict/deny, NTLMv2-only, audit | Identity / AD team | Pass-the-hash, relay |
| LSASS / VBS | Credential Guard, RunAsPPL, LSAIso | Endpoint / platform team | Hash & ticket theft from memory |
| Kerberos | Armoring, RC4 disablement, AES-only | Identity / AD team | Overpass-the-hash, Kerberoasting |
| Privileged access | Protected Users, Tier model, RCG, PAW | IAM / PAM team | All of the above for privileged identities |
| Network | Segmentation, host firewall, SMB exposure | Network team | Coercion, relay paths, SMB reachability |
| Detection | Event collection, KQL hunts, alerting | SOC / blue team | Confirms the controls held; catches misses |
Core concepts
Six mental models make every later decision obvious. Get these right and the rest of the article is implementation detail.
The status code of an intrusion is “valid authentication.” Almost nothing in lateral movement looks like an attack to the systems being attacked: a relayed NTLM session is a real NTLM session, a replayed hash is a real hash, a forged Kerberos ticket carries a valid signature from the krbtgt key. This is why “we have EDR” is not an answer — the EDR sees a successful logon, not an exploit. The defense is to make the carriers refuse reuse: sign the SMB session so a relay fails its integrity check, isolate the secret so the hash cannot be lifted, armor Kerberos so a ticket cannot be forged or replayed.
NTLM proves possession of the hash, not knowledge of the password. This single fact is the engine of pass-the-hash. NTLM never sends or verifies the plaintext; it proves the client holds the NT hash (the MD4 of the UTF-16 password). So an attacker who steals the hash from memory can authenticate as that user until the password changes, with nothing to crack — the hash is a password-equivalent that never expires. Every NTLM control is ultimately about removing the hash from reach (Credential Guard) or removing NTLM from the conversation (restrict/deny, Kerberos-only).
Signing binds a session; encryption hides it; they solve different problems. SMB signing appends a keyed MAC to every packet, so a man-in-the-middle (including a relay) cannot tamper with or re-target the session — the signature won’t verify on a different channel. SMB encryption (SMB 3.x, AES-GCM/CCM) protects confidentiality on the wire. Signing defeats relay but does not hide data or stop pass-the-hash; encryption hides data but does not, alone, defeat relay (you also need signing or channel binding). You want both, applied where each matters.
LSASS is the vault, and by default the OS holds the key. NTLM hashes, Kerberos keys and tickets, and (historically) cached plaintext live in LSASS memory, and with admin rights an attacker reads it — Mimikatz, a comsvcs.dll minidump, an EDR-blind handle — and walks away with password-equivalents. Credential Guard changes the topology: it moves those secrets into LSAIso, an isolated trustlet inside a Hyper-V-based Virtual Secure Mode (VSM) at a higher virtual trust level (VTL 1) that the normal OS (VTL 0) — even SYSTEM — cannot read. The hash is still used; it can no longer be extracted.
Kerberos has its own theft and forgery problems, distinct from NTLM’s. Pass-the-ticket lifts a TGT or service ticket from memory and replays it. Overpass-the-hash uses a stolen NTLM hash to request a fresh Kerberos TGT. Kerberoasting requests a service ticket for an account with an SPN and cracks it offline to recover that account’s password — devastating against weak service passwords, especially with RC4-encrypted tickets. Golden/Silver tickets forge tickets from the krbtgt or a service account’s key. Credential Guard protects the tickets in memory; armoring, RC4 disablement, gMSA, and krbtgt rotation address the protocol-level forgery and offline-cracking paths.
Privilege tiering is what makes all of this hold. A single workstation compromise becomes domain compromise because a Tier-0 credential (Domain Admin) was once typed into, cached on, or delegated to a Tier-2 machine. The Tier administration model forbids that — Tier-0 identities log on only to Tier-0 systems, never down a tier — so even a perfect pass-the-hash from a workstation yields only Tier-2 credentials that cannot touch the DCs. Credential Guard removes the secret; the Tier model ensures the removable secret was never the valuable one to begin with.
The vocabulary in one table
Pin down every moving part before the deep sections. The glossary repeats these for lookup; this is the mental model side by side.
| Term | One-line definition | Where it lives | Why it matters here |
|---|---|---|---|
| NTLM hash | NT hash (MD4 of the password); a password-equivalent | LSASS memory; SAM/NTDS on disk | Stolen → pass-the-hash forever |
| SMB signing | Keyed MAC on every SMB packet | SMB client/server config | Defeats NTLM/SMB relay |
| SMB encryption | AES-GCM/CCM confidentiality (SMB 3.x) | Server or per-share | Hides data on the wire |
| SMBv1 | The 1990s dialect: no real signing, wormable | Optional Windows feature | EternalBlue carrier; remove it |
| NTLM relay | Forwarding a coerced NTLM auth to a third host | Network attacker | Signing / EPA / channel binding stops it |
| Credential Guard | VBS isolation of LSA secrets in LSAIso | VTL 1 / VSM | Hash & ticket can’t be dumped |
| VBS / VSM | Hyper-V-based memory isolation (VTL 0 vs VTL 1) | Hypervisor + UEFI | The foundation Credential Guard runs on |
| LSAIso / LsaIso.exe | The isolated LSA trustlet | VTL 1 | Holds the protected secrets |
| Protected Users | AD group that hardens member credential behavior | AD security group | No NTLM/RC4/delegation/caching for members |
| Windows LAPS | Rotates & stores unique local-admin passwords | AD/Entra + GPO/CSP | Kills local-admin password reuse |
| Remote Credential Guard | RDP SSO without sending a reusable credential | Client + target Lsa config | Admin’s secret never lands on the server |
| Restricted Admin | RDP with no credential delegation at all | Target Lsa config | Even stricter than RCG for jump hosts |
| Kerberos armoring (FAST) | Encrypts the pre-auth with the machine’s TGT | DC + client GPO | Hardens against offline & spoofing attacks |
| RC4 | Weak Kerberos/NTLM cipher | KDC + client policy | Enables Kerberoasting; disable it |
| RunAsPPL | LSASS as a Protected Process Light | LSA registry / GPO | Blocks userland LSASS reads |
| ASR rules | Defender attack-surface-reduction rules | Defender / Intune | Blocks LSASS dump, child-process abuse |
| Tier model | Privilege separation (T0/T1/T2) | Logon-right GPOs + silos | A foothold can’t reach a higher tier |
The lateral-movement kill chain, link by link
Before changing a single setting, be precise about the chain you are breaking. A real intrusion rarely uses one technique; it chains them, and each link has a distinct countermeasure that does nothing for the others. This is the most important idea in the article: there is no single silver bullet, only a set of cuts that together leave no intact path.
A typical chain runs: initial access (phish, macro) → credential access (dump LSASS) → lateral movement (PtH/relay/PtT to the next host) → privilege escalation (harvest a higher-tier credential along the way) → domain dominance (DCSync, Golden Ticket). Map the techniques onto that flow and the countermeasures fall out.
| Stage | Representative technique | What it requires to succeed | The cut that stops it |
|---|---|---|---|
| Credential access | Dump NTLM hashes / Kerberos keys from LSASS | Admin on the host + readable LSASS | Credential Guard; RunAsPPL; ASR LSASS rule |
| Credential access | Read cached domain credentials | Cached logons present on the host | Protected Users (no caching); limit cached count |
| Lateral movement | Pass-the-hash to SMB/WMI/PsExec | A reusable NTLM hash for a valid account | Credential Guard; restrict/deny NTLM |
| Lateral movement | NTLM relay (coerce → relay to 3rd host) | Unsigned target; coercion path | SMB signing; LDAP channel binding + EPA; patch PetitPotam |
| Lateral movement | Pass-the-ticket (replay TGT/TGS) | A ticket lifted from memory | Credential Guard; short ticket lifetimes |
| Privilege escalation | Overpass-the-hash (hash → TGT) | Stolen hash + RC4 allowed | Credential Guard; AES-only; disable RC4 |
| Privilege escalation | Kerberoasting (crack a service ticket offline) | An SPN with a crackable password | gMSA; AES; long random passwords; Protected Users |
| Domain dominance | DCSync (replicate secrets) | Replication rights on the DC | Tier-0 isolation; least privilege on replication |
| Domain dominance | Golden/Silver ticket forgery | krbtgt or service key in hand | krbtgt double-rotation; protect Tier-0; detection |
Read this as a defense-in-depth matrix, not a menu. Credential Guard appears against four rows — the highest-leverage single control because it removes the secret that fuels most of the chain — yet it is absent from the relay rows: an attacker who never touches your endpoint, who simply coerces a server to authenticate and relays that elsewhere, is unaffected by it entirely. That is why relay defense (signing, channel binding, EPA) is a separate, equally mandatory workstream, and why you cannot skip the Tier model — even with every secret isolated, a Domain Admin logging on interactively to a compromised Tier-2 box mints a ticket in that session, and the attacker is in the room. The two seductive anti-patterns (“just enable Credential Guard,” “just require SMB signing”) each block exactly one rung and are silent on the rest. Each is a band, not the architecture.
Removing SMBv1 and enforcing SMB signing and encryption
SMBv1 is the load-bearing protocol of the worm era. It has no signing worth the name, no encryption, a pre-authentication design riddled with parsing bugs, and a decade of wormable vulnerabilities (EternalBlue / MS17-010, the engine of WannaCry and NotPetya). It has shipped off by default and auto-uninstalls when unused on Windows 10 / Server 2019 and later, but it lingers in environments that once had a NAS, a copier, a medical device, or a backup appliance that needed it. Confirm its state, find what still uses it, then remove it.
Audit before you remove
The single most important step is not disabling SMBv1 — it is finding who still depends on it, so you do not black-hole a clinical system or a manufacturing line. The SMB server logs every SMBv1 access attempt when auditing is enabled.
# Check current SMBv1 state — both the protocol and the optional feature
Get-SmbServerConfiguration | Select-Object EnableSMB1Protocol
Get-WindowsOptionalFeature -Online -FeatureName SMB1Protocol | Select-Object State
# Turn ON SMBv1 access auditing FIRST — do not remove anything yet
Set-SmbServerConfiguration -AuditSmb1Access $true -Force
# After a representative window (days), review who connected over SMBv1:
Get-WinEvent -LogName 'Microsoft-Windows-SMBServer/Audit' -MaxEvents 200 |
Where-Object Id -eq 3000 |
ForEach-Object {
[pscustomobject]@{ Time = $_.TimeCreated; Client = $_.Message }
}
Event ID 3000 in Microsoft-Windows-SMBServer/Audit records each SMBv1 client. Only once that log is quiet (or you have remediated the named clients) do you remove the protocol.
# Disable the SMBv1 server protocol and remove the optional feature entirely
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart
# (Client-side feature, where present:)
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol-Client -NoRestart
Here is the SMB dialect landscape so you know exactly what you are removing and what you are standing on. The dialect is negotiated per connection; the server’s minimum/maximum bound which versions are even on the table.
| Dialect | OS that introduced it | Signing | Encryption | Status / what to do |
|---|---|---|---|---|
| SMB 1.0 (CIFS) | NT 4 / 2000 | Weak (HMAC-MD5, optional) | None | Remove — wormable, no real integrity |
| SMB 2.0 | Vista / 2008 | HMAC-SHA256 | None | Legacy floor; keep only for old kit |
| SMB 2.1 | 7 / 2008 R2 | HMAC-SHA256 | None | Leasing/large MTU; acceptable minimum |
| SMB 3.0 | 8 / 2012 | AES-CMAC | AES-128-CCM | First with encryption; good |
| SMB 3.0.2 | 8.1 / 2012 R2 | AES-CMAC | AES-128-CCM | Per-share encryption controls |
| SMB 3.1.1 | 10 / 2016+ | AES-CMAC / AES-GMAC | AES-128/256-GCM/CCM | Preferred; pre-auth integrity; QUIC-capable |
On modern OSes you can also clamp the minimum and maximum negotiated dialect explicitly — useful to refuse anything below SMB 2 even if SMBv1 somehow returns, and a hard requirement on Windows Server 2025 / 11 24H2 where the controls are first-class.
# Refuse any dialect below SMB 2.0.2; allow up to the newest (Server 2025 / Win11 24H2)
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
Set-SmbServerConfiguration -Smb2DialectMin SMB202 -Smb2DialectMax SMB311 -Force # where supported
Set-SmbClientConfiguration -Smb2DialectMin SMB202 -Smb2DialectMax SMB311 -Force # where supported
Enforce signing on both sides
With SMBv1 gone, require signing on SMBv2/3. Signing must be required on both the server (to refuse unsigned inbound) and the client (to refuse downgrade to an unsigned session). Required-vs-enabled is the distinction that bites: “enabled” means “sign if both sides agree,” which an attacker can downgrade; “required” means “refuse to talk unsigned.”
# Server side: REQUIRE signing for all inbound SMB sessions (not merely "enable")
Set-SmbServerConfiguration -RequireSecuritySignature $true -EnableSecuritySignature $true -Force
# Client side: REQUIRE signing on all outbound connections
Set-SmbClientConfiguration -RequireSecuritySignature $true -EnableSecuritySignature $true -Force
Roll this out by Group Policy so it survives rebuilds and applies fleet-wide. The four canonical policies live under Computer Configuration > Policies > Windows Settings > Security Settings > Local Policies > Security Options. Set all four to Enabled (the “(always)” pair is the one that requires; the “(if … agrees)” pair is the negotiable fallback):
Microsoft network server: Digitally sign communications (always) = Enabled
Microsoft network server: Digitally sign communications (if client agrees) = Enabled
Microsoft network client: Digitally sign communications (always) = Enabled
Microsoft network client: Digitally sign communications (if server agrees) = Enabled
The signing matrix — what each combination of server/client setting actually negotiates — is where most “it broke for one app” tickets resolve:
| Server setting | Client setting | Result | Relay-safe? |
|---|---|---|---|
| Required | Required | Always signed | Yes |
| Required | Enabled (not required) | Signed (server forces) | Yes (for this server) |
| Enabled | Enabled | Signed if both agree — downgradeable | No (attacker downgrades) |
| Enabled | Disabled | Unsigned | No |
| Required | Disabled | Connection refused | n/a (legacy client breaks) |
| Disabled | Required | Signed (client forces) — but server won’t refuse others | Partial |
Windows 11 24H2 and Windows Server 2025 require SMB signing by default for both the client and server roles, and add SMB client-side encryption mandates and SMB-over-QUIC. On those builds, plan for signing being on whether you set it or not — and test legacy clients against the new default before you deploy the OS, not after.
Apply encryption where it matters
Server-wide encryption (EncryptData $true) rejects any client that cannot negotiate SMB 3.x encryption — which can lock out older Linux/macOS SMB stacks and most OT gateways. The safer pattern for mixed fleets is per-share encryption on the data that actually needs confidentiality, leaving the server default broad. On a homogeneous modern fleet, server-wide is fine and cleaner.
# Per-share encryption (recommended for mixed fleets) — encrypt only sensitive shares
Set-SmbShare -Name "FinanceData" -EncryptData $true -Force
Set-SmbShare -Name "HRRecords" -EncryptData $true -Force
# OR server-wide (only when every client supports SMB 3.x encryption)
Set-SmbServerConfiguration -EncryptData $true -Force
# Reject any unencrypted access attempts to encrypted shares (don't silently fall back)
Set-SmbServerConfiguration -RejectUnencryptedAccess $true -Force
The encryption decision table — match the share to the policy:
| Scenario | Setting | Why |
|---|---|---|
| Homogeneous Windows 10/11 + Server 2016+ fleet | Server-wide EncryptData $true |
Every client supports SMB 3.x; simplest blanket protection |
| Mixed fleet (Linux/macOS/OT present) | Per-share on sensitive shares only | Avoids locking out SMB-2-only clients on non-sensitive shares |
| Highly sensitive data on a modern fleet | Per-share encrypt + RejectUnencryptedAccess $true |
No silent downgrade to cleartext for that data |
| Crossing an untrusted segment (branch, WAN) | Encrypt + consider SMB over QUIC | Confidentiality on a hostile path |
| Performance-critical, trusted segment, signing already on | Signing only, no encryption | Signing already stops relay/tamper; skip the AES cost where the path is trusted |
A note on the AES negotiation: SMB 3.1.1 negotiates AES-128-GCM (fast) or AES-128/256-CCM, and Windows Server 2022+ adds AES-256. You can prefer the stronger cipher where the data warrants it:
# Prefer AES-256-GCM ciphers (Server 2022 / Windows 11+)
Set-SmbServerConfiguration -EncryptionCiphers 'AES_256_GCM, AES_128_GCM' -Force
Set-SmbClientConfiguration -EncryptionCiphers 'AES_256_GCM, AES_128_GCM' -Force
The Group Policy equivalents for the encryption stance live under the same Security Options node and as SMB-specific MDM/registry settings; for fleet management the registry path HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters carries RequireSecuritySignature, EnableSecuritySignature, and (Server 2025) the new mandate values.
SMB over QUIC: SMB without the VPN
SMB over QUIC (Windows Server 2022 Azure Edition and later, including Server 2025; client support on Windows 11) tunnels SMB 3.1.1 inside the QUIC transport over UDP/443 with mandatory TLS 1.3. The point is reachability without exposing TCP/445 to the internet and without a VPN: a remote laptop reaches a file server over 443/UDP, the session is always encrypted, and the certificate authenticates the server. It is not a replacement for signing/encryption on the LAN — it is a way to publish SMB to untrusted networks safely.
QUIC changes the firewall and trust model, so it has prerequisites that catch people:
| Requirement | Detail | Why it matters |
|---|---|---|
| Server OS | Windows Server 2022 Datacenter: Azure Edition, or Server 2025 | QUIC SMB server is OS-gated |
| Client OS | Windows 11 (and managed via mapping/UNC) | Client QUIC stack required |
| Transport | UDP/443 (not TCP/445) inbound to the server | Only 443/UDP is exposed; 445 stays internal |
| Encryption | TLS 1.3, mandatory, always on | No cleartext option over QUIC |
| Certificate | Server auth cert (KU/EKU), SAN matching the FQDN, trusted by clients | Clients validate the server like HTTPS |
| KDC proxy (optional) | For Kerberos over the internet without DC line-of-sight | Lets remote clients still use Kerberos, not just NTLM |
Configure the QUIC listener by binding a certificate to the SMB server:
# Bind a server-auth certificate to the SMB-over-QUIC listener
$cert = Get-ChildItem Cert:\LocalMachine\My |
Where-Object Subject -like '*files.corp.example.com*' | Select-Object -First 1
New-SmbServerCertificateMapping -Name 'files.corp.example.com' `
-Thumbprint $cert.Thumbprint -StoreName My -Force
# Restrict which clients may connect over QUIC (access-control on the listener)
Get-SmbServerCertificateMapping
Set-SmbServerConfiguration -RestrictNamedpipeAccessViaQuic $true -Force # tighten named-pipe exposure
Critically, because QUIC publishes SMB to the internet, restrict client access (Grant-SmbClientAccessToServer / a device allow-list) so only authorized devices can even reach the listener — without it, anyone on the internet can attempt authentication. Keep the certificate lifecycle tight (SAN = FQDN, a CA your clients trust, monitored expiry; it is your server’s identity to the world), deploy a KDC proxy so remote clients keep using Kerberos instead of falling back to NTLM, enable connection logging, and allow only UDP/443 inbound while never exposing 445 publicly.
The decision is narrow: use SMB over QUIC for remote/branch/teleworker access to file servers where you would otherwise stand up a VPN or (worse) expose 445. Do not use it as your LAN transport — on the LAN, signing + encryption over TCP/445 is simpler and faster.
Restricting and auditing NTLM
NTLM is the substrate for both pass-the-hash and relay, so removing it removes the largest single class of lateral movement. It is dangerous on five distinct counts: the hash is a password-equivalent (pass-the-hash, until the password changes); it authenticates by possession, not channel (relayable to a third party); it does not mutually authenticate the server (a client can be lured to a rogue one — Kerberos does not have this flaw); its legacy LM/NTLMv1 responses are crackable offline in seconds; and it can be triggered by coercion (PetitPotam, the printer bug). But you rarely get to disable it outright on day one — too many appliances, scanners, backup agents, and line-of-business apps still authenticate by IP address or with NTLM-only stacks. The disciplined path is audit first, then deny with surgical exceptions. Skipping the audit is how you cause the outage.
Step 1 — audit fleet-wide
Turn on NTLM auditing everywhere before blocking anything. These policies are under Computer Configuration > Policies > Windows Settings > Security Settings > Local Policies > Security Options, in the “Network security: Restrict NTLM: …” group. The domain-wide auditing policy is set on domain controllers; the incoming/outgoing policies on members and clients.
Network security: Restrict NTLM: Audit Incoming NTLM Traffic = Enable auditing for all accounts
Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers = Audit all
Network security: Restrict NTLM: Audit NTLM authentication in this domain = Enable all (set on DCs)
Audit events land in Applications and Services Logs > Microsoft > Windows > NTLM > Operational (Event IDs 8001–8004) on clients, in NTLM/Operational plus Security 4624 (with “Authentication Package: NTLM”) on servers, and Event 8004 on DCs records domain NTLM authentications with the source, target, and whether it would be blocked. Harvest the outgoing-NTLM events to build the allow-list of legitimate consumers:
# Build the allow-list: every server your fleet still authenticates to via NTLM
Get-WinEvent -LogName 'Microsoft-Windows-NTLM/Operational' |
Where-Object Id -eq 8001 |
ForEach-Object {
[pscustomobject]@{
Time = $_.TimeCreated
TargetServer = $_.Properties[2].Value
User = $_.Properties[1].Value
}
} | Sort-Object TargetServer -Unique
The NTLM audit event reference, so you read the right log on the right role:
| Event ID | Log | Logged on | Meaning |
|---|---|---|---|
| 8001 | NTLM/Operational | Client | Outgoing NTLM authentication to a remote server |
| 8002 | NTLM/Operational | Client | Outgoing NTLM blocked (after deny is set) |
| 8003 | NTLM/Operational | Server | Incoming NTLM authentication audited |
| 8004 | NTLM/Operational | Domain Controller | Domain NTLM auth audited (source, target, block-decision) |
| 4624 | Security | Server | Successful logon; “Authentication Package: NTLM” identifies NTLM |
| 4776 | Security | DC | Credential validation (NTLM); failure codes reveal cracking attempts |
Step 2 — refuse the weak responses now
Independently of the audit, you can immediately force NTLMv2 only and refuse the ancient LM/NTLMv1 responses (trivially crackable) — this rarely breaks anything modern and removes the worst of the offline-cracking surface. The control is the LAN Manager authentication level.
Network security: LAN Manager authentication level
= Send NTLMv2 response only. Refuse LM & NTLM (value 5)
# Registry-driven equivalent (for MDM/Intune/imaging): 5 = NTLMv2 only, refuse LM & NTLM
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa' `
-Name 'LmCompatibilityLevel' -Value 5 -Type DWord
The LmCompatibilityLevel ladder — set it to 5 fleet-wide unless a named legacy system forces lower:
| Value | Client sends | Server accepts | Verdict |
|---|---|---|---|
| 0 | LM & NTLM | LM, NTLM, NTLMv2 | Never — accepts crackable LM |
| 1 | LM & NTLM (NTLMv2 if negotiated) | all | Never |
| 2 | NTLM only | all | Weak |
| 3 | NTLMv2 only | LM, NTLM, NTLMv2 | Better, but server still accepts weak |
| 4 | NTLMv2 only | NTLM, NTLMv2 (refuse LM) | Good |
| 5 | NTLMv2 only | NTLMv2 only (refuse LM & NTLM) | Target — set this |
Step 3 — deny with exceptions
Once you know who genuinely needs NTLM, flip from audit to deny and carve out the exceptions by name. On domain controllers, deny domain NTLM but add server exceptions for the unpatchable kit:
Network security: Restrict NTLM: NTLM authentication in this domain
= Deny for domain servers (then "Deny all" once confident)
Network security: Restrict NTLM: Add server exceptions in this domain
= legacy-app01.corp.example.com
scanner-fleet*.corp.example.com
ot-gw*.corp.example.com
On members and clients, you can deny outgoing NTLM with client exceptions, and incoming NTLM where a server should only ever see Kerberos:
Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers = Deny all
Network security: Restrict NTLM: Add remote server exceptions for NTLM = legacy-nas01, backup-appliance01
Network security: Restrict NTLM: Incoming NTLM traffic = Deny all accounts (Kerberos-only servers)
The audit-to-deny rollout, staged so an exception list precedes every block:
| Phase | Setting | Goal | Exit criterion |
|---|---|---|---|
| 1. Audit | Audit incoming/outgoing/domain NTLM | See every NTLM flow | Stable allow-list of legitimate targets |
| 2. Harden responses | LmCompatibilityLevel = 5 |
Kill LM/NTLMv1 | No 4776 failures from refused LM |
| 3. Exceptions | Add server/remote-server exceptions | Protect unpatchable kit | Exception list reviewed & minimal |
| 4. Deny subset | Deny for domain servers / outgoing deny all | Block the bulk | 8002 events only from non-critical paths |
| 5. Deny all | Deny all NTLM in domain | NTLM eliminated except exceptions | Steady state; exceptions trending to zero |
A reading note that saves an incident: denying NTLM does not stop relay against the systems still in your exception list, and it does not retroactively remove the hash from memory — it stops new NTLM authentications. Pair NTLM restriction with Credential Guard (removes the hash) and signing/EPA (stops relay on what remains) or you have closed only one of three doors.
Defeating NTLM relay across protocols
SMB signing kills SMB relay. But NTLM relay also targets LDAP (relay to a domain controller → grant yourself rights, or via AD CS → issue a certificate as a privileged account, the PetitPotam → ADCS ESC8 chain), HTTP (AD CS web enrollment, Exchange EWS/EWS-based attacks), and other services. The cross-protocol defenses are channel binding and Extended Protection for Authentication (EPA), which bind the NTLM authentication to the specific TLS channel it arrived on — a relayed authentication arrives on a different channel and is rejected.
Lock down LDAP on domain controllers
PetitPotam-to-AD-CS relayed exactly to LDAP/HTTP. Enforce LDAP signing and LDAP channel binding on every DC. Under Computer Configuration > Policies > Windows Settings > Security Settings > Local Policies > Security Options:
Domain controller: LDAP server signing requirements = Require signing
Domain controller: LDAP server channel binding token requirements = Always
The registry equivalents on the DC, for verification and imaging:
# On each DC — require LDAP signing and enforce channel binding tokens
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters' `
-Name 'LDAPServerIntegrity' -Value 2 -Type DWord # 2 = require signing
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters' `
-Name 'LdapEnforceChannelBinding' -Value 2 -Type DWord # 2 = always enforce
Enforce EPA on AD CS and other HTTP endpoints
The certificate-enrollment web endpoints are the classic HTTP relay target. Enforce HTTPS and EPA on the CA web enrollment / NDES sites, and disable NTLM there where you can (Kerberos-only enrollment closes the path entirely).
# Require EPA on the CertSrv web enrollment app in IIS (relay target for ESC8/PetitPotam)
Set-WebConfigurationProperty `
-Filter '/system.webServer/security/authentication/windowsAuthentication/extendedProtection' `
-PSPath 'IIS:\Sites\Default Web Site\CertSrv' `
-Name 'tokenChecking' -Value 'Require'
# And prefer Kerberos / disable NTLM on the enrollment endpoint where the clients support it
Set-WebConfigurationProperty `
-Filter '/system.webServer/security/authentication/windowsAuthentication' `
-PSPath 'IIS:\Sites\Default Web Site\CertSrv' `
-Name 'providers' -Value @{ Collection = @(@{ value = 'Negotiate:Kerberos' }) }
The relay-defense matrix by protocol — where each relay lands and what binds it:
| Relayed-to protocol | Classic attack | The binding control | GPO / setting |
|---|---|---|---|
| SMB | Relay coerced auth to a file/management server | SMB signing (required) | The four signing policies |
| LDAP / LDAPS | Relay to DC → grant rights / RBCD / DCSync setup | LDAP signing + channel binding | LDAPServerIntegrity=2, LdapEnforceChannelBinding=2 |
| HTTP (AD CS web enroll / NDES) | PetitPotam → ESC8: issue a cert as DC$ | EPA (Require) + HTTPS + Kerberos-only | IIS extendedProtection; disable NTLM |
| HTTP (Exchange / OWA / EWS) | Relay to mail for mailbox/privilege abuse | EPA on the vdirs; patch | IIS extendedProtection |
| RPC / DCOM | Relay to management interfaces | Packet privacy / signing; patch coercion | RPC auth-level; CVE patches |
The coercion vectors themselves must be addressed too — relay needs a victim to authenticate. Patch and constrain the known forced-authentication triggers:
| Coercion vector | Mechanism | Mitigation |
|---|---|---|
| PetitPotam (MS-EFSRPC) | Coerces a host to authenticate to an attacker | Patch; restrict NTLM; EPA on relay targets; filter EFSRPC |
| PrinterBug / SpoolSample (MS-RPRN) | Print spooler triggers auth | Disable Spooler on DCs/servers that don’t print |
| DFSCoerce (MS-DFSNM) | DFS RPC coerces auth | Patch; restrict the RPC interface |
| ShadowCoerce / others (MS-FSRVP etc.) | Various RPC coercions | Patch; NTLM restriction; segment management RPC |
The principle: relay defense is a matrix, not a single switch. Sign SMB, bind LDAP, EPA the HTTP enrollment paths, disable the Spooler where it has no business running, and patch the coercion CVEs — then the relayed authentication has nowhere left to land.
Credential Guard and virtualization-based security
Signing and NTLM restriction shrink the network attack surface. Credential Guard attacks the other half of the problem: the secrets in memory. It moves NTLM hashes, Kerberos TGTs and keys, and derived credentials into the LSAIso isolated trustlet, protected by a Hyper-V-based Virtual Secure Mode running at a higher virtual trust level (VTL 1) that the host OS (VTL 0) — and therefore Mimikatz, a minidump, or any userland or even kernel reader in VTL 0 — cannot read. Even with SYSTEM, an attacker can no longer dump usable secrets for accounts that logged on while Credential Guard was running.
What it does and does not protect
This is the most-misunderstood control in the article, so be exact about the boundary:
| Protected by Credential Guard | NOT protected by Credential Guard |
|---|---|
| NTLM hashes of logged-on users (in LSAIso) | Credentials typed into a compromised app/keylogger |
| Kerberos TGTs and session keys (in LSAIso) | Secrets on a host where CG is not running |
| Derived domain credentials in memory | The krbtgt / domain database on the DC (CG is not a DC control for AD secrets) |
| WDigest plaintext (forced off; field empty) | Local SAM database on disk (use LAPS + BitLocker) |
| Cached domain credentials’ usable form | Relay attacks (no endpoint secret needed) |
| — | DPAPI/credentials an admin can decrypt with their own rights |
Read that right column carefully: Credential Guard does not make a host immune. It makes the secrets in memory unusable to an attacker who lands on that host. It does nothing for relay (no endpoint secret is stolen), nothing for a host that isn’t running it (so coverage must be universal), and — importantly — it is not supported on domain controllers in the credential-isolation sense, because the DC’s job is to be the authority for those secrets. Protect DCs with Tier-0 isolation, RunAsPPL, and physical/console control, not Credential Guard.
Requirements
| Requirement | Why | Notes |
|---|---|---|
| UEFI + Secure Boot | Roots the VBS chain in firmware | BIOS/CSM mode unsupported |
| VT-x / AMD-V + SLAT (EPT/NPT) | Hardware virtualization for VSM | Enable in firmware |
| TPM 2.0 (recommended) | Binds keys; UEFI-lock anti-tamper | TPM 1.2 works; 2.0 preferred |
| IOMMU / DMA protection (recommended) | Blocks DMA attacks on VSM | “Secure Boot and DMA Protection” level |
| 64-bit OS, Enterprise/Server | VBS is an Enterprise/Server feature | Win10/11 Enterprise; Server 2019+ |
| Hypervisor enabled (Hyper-V components) | VSM uses the hypervisor | Auto-enabled by the VBS feature |
On Windows 11 22H2+ and Server 2025, VBS and Credential Guard are enabled by default on qualifying hardware. Everywhere else, deploy by policy.
Enable it (GPO and registry)
Enable via Group Policy under Computer Configuration > Policies > Administrative Templates > System > Device Guard > Turn On Virtualization Based Security:
Turn On Virtualization Based Security = Enabled
Select Platform Security Level = Secure Boot and DMA Protection
Credential Guard Configuration = Enabled with UEFI lock
Secure Launch Configuration = Enabled
The UEFI lock is the decision that matters. It writes a variable to firmware so Credential Guard cannot be silently disabled by a registry edit from a compromised admin context — turning it off then requires physical/console access to clear the lock. Use it for production. Use “Enabled without lock” only while piloting, so you can disable remotely if a driver or app is incompatible.
The registry equivalent, for imaging or Intune (the \Scenarios\CredentialGuard key is what flips CG specifically; the parent keys enable VBS):
$dg = 'HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard'
New-Item -Path $dg -Force | Out-Null
Set-ItemProperty -Path $dg -Name 'EnableVirtualizationBasedSecurity' -Value 1 -Type DWord
Set-ItemProperty -Path $dg -Name 'RequirePlatformSecurityFeatures' -Value 3 -Type DWord # 1=Secure Boot, 3=+DMA
New-Item -Path "$dg\Scenarios\CredentialGuard" -Force | Out-Null
Set-ItemProperty -Path "$dg\Scenarios\CredentialGuard" -Name 'Enabled' -Value 1 -Type DWord # CG on
Set-ItemProperty -Path "$dg\Scenarios\CredentialGuard" -Name 'LsaCfgFlags' -Value 1 -Type DWord # 1=UEFI lock, 2=no lock
The VBS / Credential Guard registry reference:
| Value | Key | Meaning |
|---|---|---|
EnableVirtualizationBasedSecurity |
…\DeviceGuard |
1 = VBS on |
RequirePlatformSecurityFeatures |
…\DeviceGuard |
1 = Secure Boot; 3 = Secure Boot + DMA |
Scenarios\CredentialGuard\Enabled |
…\DeviceGuard\Scenarios\CredentialGuard |
1 = Credential Guard configured |
LsaCfgFlags |
…\DeviceGuard\Scenarios\CredentialGuard |
0 = off, 1 = on with UEFI lock, 2 = on without lock |
HypervisorEnforcedCodeIntegrity\Enabled |
…\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity |
1 = HVCI (Memory Integrity) on |
Confirm it is RUNNING, not merely configured
This is where teams declare victory too early. Configured ≠ running: a missing hardware prerequisite (Secure Boot off, virtualization disabled in firmware, an incompatible driver) leaves Credential Guard configured-but-off, and the secrets are still dumpable. Reboot, then verify the running state via WMI:
$g = Get-CimInstance -ClassName Win32_DeviceGuard `
-Namespace 'root\Microsoft\Windows\DeviceGuard'
$g.SecurityServicesConfigured # array; 1 present = Credential Guard CONFIGURED
$g.SecurityServicesRunning # array; 1 present = Credential Guard RUNNING <-- the one that counts
$g.VirtualizationBasedSecurityStatus # 0=off, 1=enabled-not-running, 2=RUNNING
# Quick boolean: is CG actually running?
[bool]($g.SecurityServicesRunning -contains 1)
# Corroborate: the isolated trustlet process must exist
Get-Process LsaIso -ErrorAction SilentlyContinue
The enum values are not intuitive, so decode them: VirtualizationBasedSecurityStatus is 0 (off), 1 (enabled-not-running) or 2 (running); the SecurityServicesConfigured and SecurityServicesRunning arrays use 1 for Credential Guard, 2 for HVCI, and 3 for System Guard Secure Launch. The single value that proves the secrets are isolated is SecurityServicesRunning containing 1. System Information (msinfo32) also reports “Virtualization-based security: Running” and “Credential Guard: Running” under System Summary — a fine portal-style confirmation for spot checks. But for fleet reporting, query SecurityServicesRunning and assert it contains 1 across every machine.
What changes for users and apps
Credential Guard is largely transparent, but three behaviors change and should be communicated:
| Behavior | Before CG | After CG | Impact |
|---|---|---|---|
| WDigest plaintext in memory | Present (if enabled) | Forced off; field empty | Some very old SSO/web-auth scenarios break |
| NTLMv1 / MS-CHAPv2 with CG-protected creds | Worked | Not supported with isolated creds | Legacy VPN/RADIUS using these may break |
| Credential delegation (unconstrained) | Worked | Restricted for protected creds | Combine with RCG/Restricted Admin for RDP |
| Third-party SSPs / credential providers | Loaded into LSASS | Custom SSPs that need raw creds may break | Test custom auth providers in the pilot ring |
Pilot Credential Guard against your VPN clients, smartcard middleware, custom credential providers, and any app doing in-process credential interception before you flip UEFI lock fleet-wide — those are the breakage classes, and they are easy to find in a ring and painful to find in production.
LSASS protection: RunAsPPL and ASR
Credential Guard isolates the protected secrets, but you should also harden the LSASS process itself, because not every secret type and not every legacy path lives behind VSM, and defense-in-depth means an attacker who somehow disables one control still hits the next.
Run LSASS as a Protected Process Light (RunAsPPL)
RunAsPPL marks LSASS as a Protected Process Light, so non-protected (userland) processes cannot open a handle to read its memory — Mimikatz’s classic sekurlsa::logonpasswords is blocked at the handle-open. On Windows 11 22H2+ this is enabled by default; elsewhere set it, ideally bound to UEFI so it cannot be silently cleared.
Computer Configuration > Administrative Templates > System > Local Security Authority
Configure LSASS to run as a protected process = Enabled with UEFI Lock
# Registry equivalent: 1 = PPL on, 2 = PPL with UEFI lock
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa' `
-Name 'RunAsPPL' -Value 2 -Type DWord
# (Server / older clients also honour RunAsPPLBoot for UEFI-lock semantics)
A caveat: RunAsPPL blocks userland reads but a kernel-mode attacker (a malicious or vulnerable signed driver — “bring your own vulnerable driver”) can still reach LSASS. That is why you pair RunAsPPL with HVCI / Memory Integrity (blocks unsigned/incompatible kernel code) and the Microsoft vulnerable driver blocklist.
Attack Surface Reduction rules
Microsoft Defender ASR rules add behavioral blocks that catch credential-theft tradecraft regardless of which process attempts it. The headline rule for this topic blocks credential stealing from LSASS; several others close adjacent lateral-movement tradecraft.
# Block credential stealing from LSASS (GUID is the ASR rule ID); 1 = Block, 2 = Audit
Add-MpPreference -AttackSurfaceReductionRules_Ids 9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2 `
-AttackSurfaceReductionRules_Actions Enabled
# Verify which ASR rules are enforced
Get-MpPreference | Select-Object -ExpandProperty AttackSurfaceReductionRules_Ids
The ASR rules most relevant to lateral movement and credential theft:
| ASR rule (purpose) | What it stops | Recommended mode |
|---|---|---|
Block credential stealing from LSASS (lsass.exe) |
Mimikatz / minidump reads of LSASS | Block |
| Block process creations from PSExec and WMI commands | Lateral execution via PsExec/WMI | Block (test admin tooling) |
| Block untrusted/unsigned processes from USB | Removable-media payloads | Block |
| Block executable content from email/webmail | Initial-access droppers | Block |
| Block Office apps from creating child processes | Macro → payload chains | Block |
| Block persistence through WMI event subscription | Stealth persistence | Block |
| Use advanced protection against ransomware | Ransom encryptors | Audit → Block |
Deploy ASR in Audit first (it reports what would be blocked without blocking), confirm no legitimate admin tooling trips the PsExec/WMI rules, then move to Block. The LSASS rule rarely has false positives and can usually go straight to Block alongside RunAsPPL and Credential Guard — three independent layers over the same secret.
Protected Users, Windows LAPS, and Kerberos hardening
Credential Guard and LSASS protection defend the machine. The next layer defends the identities and the Kerberos protocol itself — and this is where you stop overpass-the-hash, Kerberoasting, and local-admin password reuse.
The Protected Users group
Protected Users is a built-in domain security group that, for its members, enforces a bundle of credential-hardening behaviors at the protocol level — no cached logons, no NTLM, no RC4/DES Kerberos, no unconstrained delegation, and a short TGT lifetime. Put your Tier-0 and Tier-1 admins in it (never service accounts that need NTLM/RC4 or cached logon, and never the only break-glass account without testing — members cannot log on if no DC supporting the feature is reachable).
# Add privileged admins to Protected Users (requires DFL 2012 R2+ for full effect)
Add-ADGroupMember -Identity 'Protected Users' -Members 'svc-na-DA1','adm.jdoe.t0'
Get-ADGroupMember -Identity 'Protected Users'
What membership enforces, and what therefore breaks if you add the wrong account:
| Restriction for members | Effect | Who you must NOT add |
|---|---|---|
| No NTLM authentication | Cannot use NTLM at all | Accounts that log on to NTLM-only apps/appliances |
| No DES / RC4 Kerberos | AES-only tickets | Accounts needing RC4 for legacy services |
| No cached (offline) logon | Cannot log on when DCs are unreachable | Laptops that work offline; lone break-glass |
| No unconstrained delegation | Credential not delegated | Accounts relying on unconstrained delegation |
| 4-hour max TGT lifetime | Forces frequent re-auth | (generally fine for admins) |
| No long-term credential caching | Less to steal from memory | (the point) |
Protected Users is the cleanest single control for privileged identities because it removes the very behaviors (NTLM, RC4, caching, delegation) that lateral movement exploits — but precisely because it removes them, it is a pilot-then-roll control, scoped to human admins first.
Windows LAPS
Pass-the-hash thrives on local-administrator password reuse: image once with a shared local-admin password and a single dumped local hash unlocks every machine in the fleet. Windows LAPS (built into current Windows, superseding the legacy MSI) generates a unique, random, rotated local-admin password per machine and stores it in Active Directory or Entra ID, retrievable only by authorized principals. A stolen local hash then works on exactly one box.
# Update the AD schema for Windows LAPS (one-time, by a Schema Admin)
Update-LapsADSchema
# Grant a computer OU the right to store its managed password
Set-LapsADComputerSelfPermission -Identity 'OU=Servers,DC=corp,DC=example,DC=com'
# Retrieve a machine's current local-admin password (authorized principal only)
Get-LapsADPassword -Identity 'FS01' -AsPlainText
Configure rotation and complexity by GPO under Computer Configuration > Administrative Templates > System > LAPS:
Configure password backup directory = Active Directory (or Azure Active Directory)
Password Settings = 20+ chars, all character sets
Password age in days = 30
Post-authentication actions = Reset the password and logoff/restart the managing account
Name of administrator account to manage = <the local admin you rotate>
The LAPS decisions that matter:
| Decision | Options | Recommendation |
|---|---|---|
| Backup directory | AD vs Entra ID | AD for on-prem-joined; Entra for cloud-joined / hybrid |
| Password length | 8–64 | ≥ 20 (defeats offline cracking of the on-disk hash) |
| Rotation age | days | 30 (or less for high-value hosts) |
| Post-auth action | none / logoff / reset+logoff | Reset & logoff after use (limits a captured password’s window) |
| Account managed | built-in vs custom local admin | A dedicated non-default-named local admin |
| Encryption (Windows LAPS) | encrypt stored password | Enable (DFL 2016+); only authorized readers decrypt |
Kerberos armoring, RC4 disablement, and AES-only
Kerberos has its own hardening. Kerberos armoring (FAST — Flexible Authentication Secure Tunneling) wraps the Kerberos pre-authentication exchange inside an encrypted tunnel keyed by the machine’s TGT, which thwarts offline cracking of the pre-auth and spoofing. Disabling RC4 forces AES-encrypted tickets, which removes the cheap path for Kerberoasting and overpass-the-hash (RC4 tickets are far easier to crack and to forge from an NTLM hash).
Enable armoring on the KDC and require it on clients. On DCs, under Computer Configuration > Policies > Administrative Templates > System > KDC:
KDC support for claims, compound authentication and Kerberos armoring = Enabled: Always provide claims (or Fail unarmored requests once ready)
On clients, under Computer Configuration > Policies > Administrative Templates > System > Kerberos:
Kerberos client support for claims, compound authentication and Kerberos armoring = Enabled
Disable RC4 and move to AES — first audit, because a service still pinned to RC4 will break:
# Per-account: require AES, drop RC4 (msDS-SupportedEncryptionTypes: 0x18 = AES128+AES256)
Set-ADUser -Identity 'svc-sql01' -Replace @{ 'msDS-SupportedEncryptionTypes' = 0x18 }
# Domain-wide via GPO (Network security: Configure encryption types allowed for Kerberos):
# tick AES128, AES256, Future; UNtick RC4_HMAC_MD5, DES — once audit shows no RC4 dependency
The Kerberos hardening controls and what each closes:
| Control | Setting | Closes |
|---|---|---|
| Kerberos armoring (FAST) | KDC + client GPO | Offline pre-auth cracking; AS-REQ spoofing |
| Disable RC4 | msDS-SupportedEncryptionTypes / GPO |
Easy Kerberoasting & overpass-the-hash |
| AES-only tickets | Same as above | Forces strong ticket encryption |
| gMSA for service accounts | New-ADServiceAccount |
Kerberoasting (120-char machine-managed password) |
| krbtgt double-rotation | Reset-KrbtgtKeyInteractive (twice, 10h apart) |
Golden Ticket validity after compromise |
| Short ticket lifetimes / strong AS-REP | Kerberos Policy in Default Domain Policy | Window for pass-the-ticket |
| Disable Kerberos pre-auth never | (keep pre-auth ON) | AS-REP roasting (accounts with pre-auth disabled) |
For service accounts specifically, gMSA is the structural fix for Kerberoasting — the password is 120+ random characters, machine-managed, and never typed — covered in depth in Eliminating Static Service Credentials with gMSA and Windows LAPS.
Remote Credential Guard and Restricted Admin for RDP
Credential Guard protects the machine you sit at. The moment an admin RDPs into a server, the old default delegated their credentials to the remote host — so compromising any server an admin touched yielded that admin’s secrets. This is the single most common way a Tier-0 credential ends up on a Tier-2 box. Two features fix it, with different trust assumptions.
| Mode | What happens to the credential | Trust assumption | When to use |
|---|---|---|---|
| Default RDP | Full credential delegated to the target | Target is trusted | Never for privileged sessions |
| Remote Credential Guard (RCG) | Stays on the client; Kerberos SSO into the session; no reusable cred sent | You trust the client, not necessarily the target | Admin RDP where the admin’s machine is a trusted PAW |
| Restricted Admin | No credential delegated at all; you log on as the machine’s network identity | You trust neither; minimize footprint | Jump hosts; touching a possibly-compromised server |
The trade-off between them: RCG gives you genuine SSO (your identity flows via Kerberos, so network resources from the session act as you), but requires the client to be trustworthy and Kerberos line-of-sight to a KDC. Restricted Admin sends nothing, so even a fully-owned target yields no admin secret — but you act as the machine account on the network, which can itself be abused if that machine is privileged, so scope it carefully.
Enable on the RDP target (the server that accepts the connection):
# On the RDP target: 0 = allow Restricted Admin & RCG; 1 = disable RCG; 2 = require RCG
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa' `
-Name 'DisableRestrictedAdmin' -Value 0 -Type DWord
Require it on the client by policy so an operator cannot accidentally fall back to credential delegation. Under Computer Configuration > Policies > Administrative Templates > System > Credentials Delegation:
Restrict delegation of credentials to remote servers
Use the following restricted mode = Require Remote Credential Guard
(or "Require Restricted Admin" for the stricter, no-delegation mode)
Then connect with the flag (Kerberos and KDC line-of-sight required; not for cross-domain-without-trust or saved-credential scenarios):
mstsc.exe /remoteGuard /v:server01.corp.example.com # Remote Credential Guard
mstsc.exe /restrictedAdmin /v:jump01.corp.example.com # Restricted Admin (no delegation)
Now an attacker who fully owns server01 gets the machine, but not the domain-admin hash of whoever administered it. Pair this with the Tier model below: RCG/Restricted Admin keep the credential off the target; the Tier model ensures the credential that could reach that target was the right (low) tier in the first place.
The Tier administration model
Every control so far reduces the chance and value of a stolen credential. The Tier administration model changes the blast radius when one is stolen anyway. It partitions identities and systems into tiers and forbids credentials from ever crossing down a tier — so a Tier-2 (workstation) compromise can never yield a Tier-0 (domain) credential, because Tier-0 credentials are never present on Tier-2 systems to begin with.
| Tier | Contains | Logs on to | Never logs on to | Example identities |
|---|---|---|---|---|
| Tier 0 | Domain controllers, AD CS, Entra Connect, PKI, the directory itself | Tier-0 systems only | Tier-1 or Tier-2 systems | Domain Admins, Enterprise Admins |
| Tier 1 | Member servers, applications, databases | Tier-1 systems only | Tier-0 or Tier-2 systems | Server admins, DBAs |
| Tier 2 | Workstations, devices, help desk | Tier-2 systems only | Tier-0 or Tier-1 systems | Workstation/help-desk admins, users |
The model is enforced with logon-right restrictions (deny higher-tier accounts from logging on to lower-tier machines) delivered via GPO. The “Deny log on” rights are the workhorses — they prevent the credential from ever being entered/cached on the wrong tier:
Computer Configuration > Policies > Windows Settings > Security Settings
> Local Policies > User Rights Assignment
# On Tier-2 (workstation) GPOs — deny Tier-0 and Tier-1 admins from logging on here:
Deny log on locally = Tier0-Admins; Tier1-Admins
Deny log on through Remote Desktop Services = Tier0-Admins; Tier1-Admins
Deny access to this computer from the network= Tier0-Admins; Tier1-Admins
Deny log on as a batch job = Tier0-Admins; Tier1-Admins
Deny log on as a service = Tier0-Admins; Tier1-Admins
The deny-rights map per tier — apply the denials so each tier’s admins are blocked from the tiers below:
| GPO applied to | Deny these groups | Effect |
|---|---|---|
| Tier-2 (workstation) OU | Tier-0 admins, Tier-1 admins | DA/server-admin creds never land on a workstation |
| Tier-1 (server) OU | Tier-0 admins, Tier-2 admins | DA creds never land on a member server; workstation admins can’t touch servers |
| Tier-0 (DC/PKI) OU | Tier-1 admins, Tier-2 admins, regular users | Only Tier-0 identities touch the directory |
For stronger, Kerberos-enforced isolation, layer Authentication Policies and Silos on top of the logon-right GPOs. A silo can restrict a Tier-0 account so its TGT is only issued when it authenticates from a Tier-0 host (via armoring/FAST), and cap its ticket lifetime — enforced by the KDC, not just by a GPO that a local admin might dodge.
# Create a Tier-0 authentication silo and policy (KDC-enforced), then assign accounts
New-ADAuthenticationPolicy -Name 'T0-Policy' -UserTGTLifetimeMins 240 -Enforce
New-ADAuthenticationPolicySilo -Name 'T0-Silo' -UserAuthenticationPolicy 'T0-Policy' `
-ComputerAuthenticationPolicy 'T0-Policy' -ServiceAuthenticationPolicy 'T0-Policy' -Enforce
Grant-ADAuthenticationPolicySiloAccess -Identity 'T0-Silo' -Account 'adm.jdoe.t0'
Set-ADUser -Identity 'adm.jdoe.t0' -AuthenticationPolicySilo 'T0-Silo'
The Tier model also implies Privileged Access Workstations (PAWs): Tier-0 admins administer only from a hardened, locked-down workstation that never browses the web or reads email — the secure origin from which RCG sessions to Tier-0 are launched. The full design (JIT elevation, PAWs, just-enough-admin) is covered in Privileged Identity Management and PAM Architecture: Just-in-Time Access at Scale and Building Enterprise PAM: Credential Vaulting, Session Brokering, and Automatic Rotation. This is the control that makes Credential Guard’s gaps survivable — defeat every memory protection on a workstation and the only credentials present are still Tier-2, which by logon-right and silo enforcement cannot reach the DCs.
Firewall segmentation and reducing SMB exposure
Lateral movement also needs reachability — a path from the foothold to the next host’s SMB/RPC/WinRM ports. Host-based firewall segmentation removes the unnecessary paths so even a valid credential has nothing to connect to. The single highest-value rule: workstations should not accept inbound SMB from other workstations. Almost no legitimate workflow requires peer-to-peer SMB between user PCs, yet it is the highway for PsExec/WMI lateral movement.
# Block inbound SMB (445) on workstations EXCEPT from management subnets
New-NetFirewallRule -DisplayName 'Block inbound SMB from peers' `
-Direction Inbound -Protocol TCP -LocalPort 445 -Action Block `
-RemoteAddress Any -Profile Domain,Private
New-NetFirewallRule -DisplayName 'Allow inbound SMB from management' `
-Direction Inbound -Protocol TCP -LocalPort 445 -Action Allow `
-RemoteAddress 10.20.30.0/24 -Profile Domain # PAW/management subnet only
The lateral-movement ports to govern, and the right default for each:
| Port / protocol | Used for | Lateral-movement abuse | Recommended posture |
|---|---|---|---|
| TCP/445 (SMB) | File sharing, PsExec, admin$ | PtH/relay execution, file staging | Block workstation↔workstation; allow only from mgmt |
| TCP/135 + dynamic (RPC/DCOM) | WMI, DCOM, service control | WMI/DCOM lateral execution | Restrict to management subnets |
| TCP/5985-5986 (WinRM) | PowerShell remoting | Remote execution | Allow only from PAW/management |
| TCP/3389 (RDP) | Remote desktop | Interactive lateral movement | Allow only from PAW/jump hosts; NLA on |
| TCP/139 (NetBIOS) | Legacy SMB/NetBIOS | Name-spoofing, legacy SMB | Disable where not required |
| UDP/137-138 (NetBIOS name/datagram) | LLMNR/NBT-NS adjacency | Poisoning → coerced auth | Disable LLMNR/NBT-NS (see below) |
| TCP/88 (Kerberos) | Authentication | (legit) Keep open to DCs only | Allow to DCs; not peer-to-peer |
| TCP/389,636,3268-3269 (LDAP/GC) | Directory | Relay to DC | Sign+channel-bind (above); to DCs only |
A frequently-missed adjacency control: disable LLMNR and NBT-NS (and consider mDNS), the legacy name-resolution fallbacks that Responder-class tools poison to coerce NTLM authentications. Killing them removes a whole class of “machine in the middle” coercion.
Computer Configuration > Administrative Templates > Network > DNS Client
Turn off multicast name resolution = Enabled (disables LLMNR)
# Disable NetBIOS over TCP/IP per adapter (or via DHCP option 001 microsoft disable netbios)
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters\Interfaces\Tcpip_*' `
-Name 'NetbiosOptions' -Value 2 # 2 = disable NetBIOS
Segmentation does not replace the credential and protocol controls — a determined attacker with a valid credential and a permitted path still moves — but it shrinks the reachable-target graph dramatically, turning “any host can reach any host’s SMB” into “only management can reach servers’ SMB,” which alone defeats a large fraction of off-the-shelf lateral tooling. For the Linux side of the same principle, see Designing Stateful Linux Firewalls with native nftables Rulesets and NAT.
Architecture at a glance
Picture the hardened estate as three concentric defensive bands wrapped around the thing the attacker actually wants — a reusable credential — and trace one intrusion attempt through all three.
The outer band is the network and transport. An attacker on a Tier-2 workstation first tries to reach the next host, but host-firewall segmentation has removed workstation-to-workstation SMB (445 blocked except from management), so PsExec/WMI sweeps find no open peers, and disabling LLMNR/NBT-NS kills name-poisoning coercion. If they do reach a server’s SMB, the session is signed (required both ends), so a relayed authentication fails the integrity check on a different channel; relay to LDAP is dead too because every DC requires LDAP signing and channel binding, and the AD CS enrollment endpoints enforce EPA and prefer Kerberos — closing the PetitPotam→ESC8 path end to end. SMBv1 is gone, so the wormable EternalBlue carrier does not exist.
The middle band is the credential in memory. Suppose the attacker gains SYSTEM and reaches for LSASS anyway: RunAsPPL blocks the userland handle-open, the ASR LSASS rule blocks the dump behaviorally, and Credential Guard has already moved the hashes and tickets into LSAIso at VTL 1 — where neither SYSTEM nor a kernel reader in VTL 0 can follow, HVCI having blocked the malicious-driver route into the kernel. The minidump that used to yield a domain-admin hash comes back empty: WDigest plaintext is blank, and the usable secrets live in a process the OS cannot read.
The inner band is identity and Kerberos. The credentials that do exist on this host are, by the Tier model, only Tier-2 — Domain Admins are denied workstation logon by user-rights GPO and confined to a KDC-enforced Tier-0 authentication silo, so no DA credential was ever cached here. The local-admin hash that is present is LAPS-managed — unique to this one machine, so replaying it unlocks nothing else. NTLM is denied in the domain bar a named exception list of unpatchable OT gateways (which hold no privileged credentials), RC4 is disabled and Kerberos armoring is on (no cheap Kerberoasting or RC4 forgery), and the admins are in Protected Users, so their sessions never cached, never used NTLM, and never delegated — every server RDP used Remote Credential Guard, keeping the admin’s secret on the PAW.
The lesson is structural: no single control closes the kill chain — the bands do it together. The network band stops relay and reachability but not theft; the memory band stops theft but not relay; the identity band ensures whatever leaks is low-value and non-reusable. Remove any one band and an intact path reappears — which is exactly why “we turned on Credential Guard” or “we required SMB signing” is a partial answer, and the full set is the architecture.
Real-world scenario
Helvar Manufacturing runs a 9,000-seat hybrid AD estate across plants in three countries. Their annual red-team exercise had, for two years running, reached Domain Admin in under an hour: operators landed on a shop-floor engineering workstation through a macro-laden spreadsheet, dumped credentials with a comsvcs.dll minidump of LSASS, lifted a cached domain-admin hash from a help-desk remote session, and pass-the-hashed their way to a domain controller in 38 minutes. The platform team’s mandate after the third near-miss was blunt: make that exact path stop working — without breaking the SCADA gateways that still spoke SMBv2 and NTLM-by-IP and could not be patched inside the vendor’s two-year cycle.
The constraint ruled out the easy answers. They could not require SMB encryption server-wide (the OT gateways did not support SMB 3.x), and they could not deny NTLM globally (the gateways authenticated NTLM-only by IP). So they segmented the response into the three bands.
For the credential band, Credential Guard with UEFI lock went onto every endpoint and server via the Device Guard GPO, alongside RunAsPPL (also UEFI-locked) and the ASR LSASS rule in Block. The 300-machine pilot ring surfaced exactly two breakages — a legacy VPN client using MS-CHAPv2 against RADIUS, and a third-party SSO agent reading LSASS directly — both replaced before broad rollout. That removed the dumpable hash that started the chain, and the OT gateways were unaffected because they were never the credential source. For the network band, SMB signing was made mandatory everywhere (signing, unlike encryption, works on SMBv2, so the gateways kept running), LDAP signing and channel binding went onto all DCs, EPA onto the AD CS enrollment site, workstation-to-workstation SMB was firewalled off, and LLMNR/NBT-NS were disabled. For the identity band, the OT subnet got an NTLM server-exception list naming exactly the gateway hostnames while “Deny all” applied to the rest of the domain; the Tier model was enforced with deny-logon GPOs and a Tier-0 authentication silo; Domain Admins went into Protected Users; Windows LAPS rotated every local-admin password to a unique 24-character value; and RC4 was disabled after a two-week audit found only three services pinned to it (all moved to gMSA with AES).
The Credential Guard GPO that did the heavy lifting was deliberately minimal and locked:
Computer Configuration > Administrative Templates > System > Device Guard
Turn On Virtualization Based Security = Enabled
Select Platform Security Level = Secure Boot and DMA Protection
Credential Guard Configuration = Enabled with UEFI lock
The next red-team run got the same initial foothold — the spreadsheet macro still ran — but the LSASS dump came back empty of reusable domain hashes (SecurityServicesRunning contained 1 on every host; the operators confirmed it themselves). The one NTLM authentication they coerced was refused everywhere except the explicitly-excepted OT gateways, which held no privileged credentials. The help-desk remote session that used to leak a DA hash now used Remote Credential Guard, so nothing reusable landed on the workstation. Time-to-domain-admin went from 38 minutes to “not achieved” over a five-day engagement.
The retrospective ran the numbers as a before/after, and the order of the bands was the lesson — no single line in this table would have stopped the chain alone:
| Control band | Before | After | What it cut |
|---|---|---|---|
| LSASS dump → reusable hash | Yielded cached DA hash | Empty (CG + RunAsPPL + ASR) | The fuel for PtH/PtT |
| SMB relay path | Unsigned; relayable | Signing required; LDAP bound; EPA | The relay highway |
| NTLM in domain | Allowed everywhere | Denied except 11 OT hosts | PtH targets |
| Local-admin reuse | One shared password | LAPS-unique per host | Lateral reuse of a local hash |
| DA credential location | Cached on a workstation | Tier-0 silo only; deny-logon GPO | The valuable secret was never there |
| Time to Domain Admin | 38 minutes | Not achieved (5 days) | The whole chain |
The sentence the team put on the wall: “We didn’t find a silver bullet. We removed the secret, removed the relay, and made sure the secret that could leak was worthless — and the kill chain had nowhere left to go.”
Advantages and disadvantages
The layered model is powerful but not free; weigh it honestly before committing a fleet.
| Advantages | Disadvantages |
|---|---|
| Credential Guard makes dumped hashes/tickets unusable — defeats the most common lateral technique at the source | Requires UEFI/Secure Boot/SLAT/TPM; older hardware can’t run it; configured≠running traps teams |
| SMB signing/EPA/channel binding kill relay across SMB, LDAP and HTTP with policy, no agents | “Required” signing breaks legacy clients (old NAS, copiers, SMBv1-era kit) without a pilot |
| Protected Users hardens privileged identities with one group membership | Membership breaks NTLM/RC4/offline-logon for anyone wrongly added (incl. some service/break-glass accounts) |
| Windows LAPS ends local-admin password reuse fleet-wide | Adds AD/Entra schema work and a retrieval-access model to govern |
| The Tier model bounds blast radius even when every other control fails | Operationally heavy: separate admin accounts, PAWs, silos, discipline to sustain |
| Most controls are GPO/registry — manageable as code, reversible, auditable | Dozens of interacting settings; one wrong “required” or deny-rule can cause an outage |
| Defense-in-depth: an attacker must defeat all three bands, not one | No single control is sufficient; partial deployments give false confidence |
| Detection (Event IDs/KQL) proves the controls held and catches gaps | Detection needs log collection (WEF/Sentinel) and tuning to be useful |
When each matters most: Credential Guard is the highest-leverage control for any fleet with modern hardware and is close to non-negotiable for privileged endpoints. SMB signing and relay defenses matter most where the network is flat or the directory is internet-adjacent (hybrid, branch). The Tier model matters most at scale and for any organization that has already been breached laterally — it is the control that would have contained the breach. The disadvantages are all manageable, but only with a pilot ring, a configuration-as-code discipline, and the audit-before-deny patience that this article keeps insisting on — because the failure mode of rushing is an outage, and the failure mode of skipping is a breach.
Hands-on lab
This lab verifies Credential Guard end to end on a single Windows 11/Server 2022+ machine with VBS-capable hardware (a physical box or a VM with nested virtualization, Secure Boot, and a virtual TPM). It is non-destructive and reversible; it does not require a domain. Run all commands in an elevated PowerShell.
Step 1 — Confirm the hardware can support VBS.
$g = Get-CimInstance Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard
$g.AvailableSecurityProperties # expect to include values for Secure Boot, DMA, VBS
$g.VirtualizationBasedSecurityStatus # 0 = off (we will turn it on)
Expected: AvailableSecurityProperties lists the platform capabilities. If it is empty, enable virtualization and Secure Boot in firmware first, or this lab cannot proceed on this host.
Step 2 — Record the baseline (CG not yet running).
[bool]($g.SecurityServicesRunning -contains 1) # expect: False (CG not running yet)
Get-Process LsaIso -ErrorAction SilentlyContinue # expect: nothing
Step 3 — Enable VBS + Credential Guard via the registry (without UEFI lock, so the lab is reversible).
$dg = 'HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard'
New-Item -Path $dg -Force | Out-Null
Set-ItemProperty $dg 'EnableVirtualizationBasedSecurity' 1 -Type DWord
Set-ItemProperty $dg 'RequirePlatformSecurityFeatures' 1 -Type DWord # 1 = Secure Boot
New-Item -Path "$dg\Scenarios\CredentialGuard" -Force | Out-Null
Set-ItemProperty "$dg\Scenarios\CredentialGuard" 'Enabled' 1 -Type DWord
Set-ItemProperty "$dg\Scenarios\CredentialGuard" 'LsaCfgFlags' 2 -Type DWord # 2 = ON WITHOUT lock (reversible)
Step 4 — Reboot. Credential Guard initializes during boot; it cannot start without a restart.
Restart-Computer
Step 5 — Verify Credential Guard is RUNNING (the payoff).
$g = Get-CimInstance Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard
$g.VirtualizationBasedSecurityStatus # expect: 2 (running)
[bool]($g.SecurityServicesRunning -contains 1) # expect: True (Credential Guard running)
Get-Process LsaIso # expect: an LsaIso process now exists
Expected output: VirtualizationBasedSecurityStatus = 2, the running check returns True, and LsaIso.exe is present. msinfo32 will also now show “Credential Guard: Running” under System Summary. That True is your proof — the secrets are isolated.
Step 6 — Confirm WDigest plaintext is forced off (a side effect of CG).
# With CG running, WDigest cannot cache plaintext; verify the field is disabled
(Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest' `
-Name UseLogonCredential -ErrorAction SilentlyContinue).UseLogonCredential # expect: 0 or absent
Step 7 — (Optional) Add the LSASS protections alongside CG.
# RunAsPPL (without UEFI lock for the lab) and the ASR LSASS rule in Audit
Set-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa' 'RunAsPPL' 1 -Type DWord
Add-MpPreference -AttackSurfaceReductionRules_Ids 9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2 `
-AttackSurfaceReductionRules_Actions AuditMode
Get-MpPreference | Select-Object -ExpandProperty AttackSurfaceReductionRules_Ids
Step 8 — Teardown (revert everything). Because you used LsaCfgFlags = 2 (no UEFI lock) and RunAsPPL = 1, you can disable cleanly:
$dg = 'HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard'
Set-ItemProperty "$dg\Scenarios\CredentialGuard" 'Enabled' 0 -Type DWord
Set-ItemProperty "$dg\Scenarios\CredentialGuard" 'LsaCfgFlags' 0 -Type DWord
Set-ItemProperty $dg 'EnableVirtualizationBasedSecurity' 0 -Type DWord
Set-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa' 'RunAsPPL' 0 -Type DWord
Remove-MpPreference -AttackSurfaceReductionRules_Ids 9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2
Restart-Computer # CG fully clears after this reboot
If you had used UEFI lock (LsaCfgFlags = 1), the registry edit alone would not disable it — you would clear it with the Device Guard readiness tool and a console-present reboot. That is the whole point of UEFI lock in production: an attacker who pops admin cannot silently turn Credential Guard off.
Common mistakes & troubleshooting
The failure modes below are the ones that actually cost time. Match the symptom, confirm with the exact command/path, apply the fix.
| # | Symptom | Root cause | Confirm (exact command / path) | Fix |
|---|---|---|---|---|
| 1 | “We enabled Credential Guard” but hashes still dump | CG configured, not running (HW prereq missing) | (Get-CimInstance Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard).SecurityServicesRunning lacks 1 |
Enable Secure Boot + virtualization in firmware; reboot; re-check |
| 2 | A legacy NAS/copier stopped connecting after signing | Client can’t do required SMB signing | `Get-SmbServerConfiguration | Select RequireSecuritySignature` = True; client SMBv1/old |
| 3 | App outage after Deny all NTLM |
NTLM-only app not on the exception list | NTLM/Operational 8002 (outgoing blocked) naming the target | Add the target to “Restrict NTLM: Add server exceptions”; verify with 8001 |
| 4 | Admin can’t RDP after requiring RCG | No Kerberos/KDC line-of-sight, or cross-domain-no-trust | mstsc /remoteGuard fails; saved-cred or IP-based connect |
Use FQDN with KDC reachable; for jump hosts use Restricted Admin instead |
| 5 | An account in Protected Users can’t log on | Member needs NTLM/RC4/offline logon | Logon fails; 4625; account is NTLM/RC4-dependent | Remove from Protected Users; fix the dependency (AES/Kerberos) first |
| 6 | Credential Guard can’t be disabled to troubleshoot | UEFI lock is set (by design) | LsaCfgFlags = 1; registry edit doesn’t clear it |
Use the DG readiness tool + console-present reboot to clear the lock |
| 7 | VPN/SSO broke after CG | App relied on WDigest plaintext / NTLMv1 / custom SSP | WDigest\UseLogonCredential now 0; app uses MS-CHAPv2/NTLMv1 |
Move the app to Kerberos/EAP-TLS; replace the credential-reading SSP |
| 8 | LDAP-based app fails after channel binding | App doesn’t send a channel binding token over LDAPS | DC Event 3039/3040 (LDAP CBT) | Patch/update the app’s LDAP library; or set CBT to “When supported” temporarily |
| 9 | Coerced auth still succeeds despite signing | Relay went to LDAP/HTTP, not SMB | Relay landed on AD CS/Exchange, not a file server | Enforce LDAP signing+CBT and EPA on HTTP; patch the coercion CVE |
| 10 | Kerberoasting still works after “AES-only” | A service account still allows RC4 | Get-ADUser -Filter * -Properties msDS-SupportedEncryptionTypes shows RC4/0 |
Set 0x18 on the account; move it to gMSA; verify ticket etype |
| 11 | Whole app/file service down after a deny rule | Over-broad NTLM deny or firewall block | 8002 storm; firewall logs deny on 445 from mgmt | Scope the deny/exception; allow 445 from the management subnet |
| 12 | RunAsPPL set but Mimikatz still reads LSASS | Kernel-mode (vulnerable-driver) read bypasses PPL | A signed but vulnerable driver loaded | Enable HVCI + the vulnerable-driver blocklist; investigate the driver |
| 13 | LAPS password not rotating | OU lacks self-permission or GPO not applied | Get-LapsADPassword -Identity <host> empty; gpresult no LAPS |
Set-LapsADComputerSelfPermission; confirm LAPS GPO scope/age |
| 14 | “Signing required” but a relay still worked | Signing was enabled, not required (downgraded) | Security Options shows “(if client agrees)” only | Set the “(always)” pair to Enabled on both client and server |
Best practices
- Audit before you enforce — every time. SMBv1 removal, NTLM deny, and RC4 disablement each have an audit mode; use it, build the dependency/exception list from the operational logs, and only then flip to enforce. The audit step is the difference between a clean rollout and an outage.
- Deploy in rings. Pilot Credential Guard, signing-required, Protected Users, and ASR-Block on a representative 1–5% ring (mix of hardware, VPN clients, LOB apps) before fleet-wide. The breakages are findable in a ring and brutal in production.
- Confirm running, not configured. For Credential Guard, RunAsPPL, and HVCI, assert the running state in WMI across the fleet —
SecurityServicesRunningcontaining1— not just that the GPO applied. - Use UEFI lock in production. Credential Guard and RunAsPPL with UEFI lock cannot be silently disabled by a compromised admin; use “without lock” only while piloting.
- Require, don’t merely enable. SMB signing, LDAP signing, and channel binding must be required/always; “enabled if agreed” is downgradeable and gives false assurance.
- Make NTLM exceptions named, minimal, and shrinking. Track the exception list as technical debt with an owner and a retirement date per entry; the goal is zero.
- Keep Credential Guard universal. It only protects the host it runs on; partial coverage leaves stepping-stone hosts. Treat any CG-incapable machine as a known weak point and isolate it.
- Tier your admins and never cross down. Separate Tier-0/1/2 accounts, enforce with deny-logon GPOs and authentication silos, and administer Tier-0 only from a PAW via Remote Credential Guard.
- Rotate local-admin passwords with LAPS and never share an image password. One unique password per host turns a stolen local hash into a single-machine problem.
- Address coercion, not just relay. Patch PetitPotam/PrinterBug/DFSCoerce, disable the Spooler where it isn’t needed, and disable LLMNR/NBT-NS — relay needs a victim to authenticate.
- Manage it as code. Keep these GPOs/registry settings in version control with review (see the Group Policy-as-code discipline); dozens of interacting security settings demand auditability and a rollback path.
- Prove it with detection and red-teaming. Validate by attack simulation, not policy reporting — an empty LSASS dump and a refused relay are the only acceptance tests that matter.
Security notes
Beyond the controls themselves, a few security principles govern how to deploy them without creating new risk:
| Principle | Application here |
|---|---|
| Least privilege on retrieval | LAPS password read, Credential Guard exemptions, NTLM exceptions — grant to the fewest principals; audit reads |
| Protect Tier-0 absolutely | DCs, AD CS, Entra Connect: physical/console control, RunAsPPL, no inbound from lower tiers, no internet, dedicated admins |
| Encryption serves integrity and confidentiality | Signing for integrity (anti-relay), encryption for confidentiality; apply both per the data’s sensitivity |
| Network isolation as a multiplier | Segmentation shrinks the reachable graph so a valid credential has fewer targets; it complements, never replaces, the credential controls |
| Identity for machines too | gMSA for services, machine authentication silos, and computer-tier deny-rights — machines hold credentials worth stealing |
| Detect the residual | After hardening, the attempts still happen (refused) — collect 4624/4625/4768/4769/4776/8002 and the SMB/NTLM operational logs to see them |
| Break-glass survivability | Never put your only emergency account in Protected Users untested; keep an offline-validated break-glass path |
| Assume the host can be SYSTEM | Design so SYSTEM-on-a-workstation yields nothing reusable (CG + Tier + LAPS) — that is the threat model, not “admin won’t get popped” |
A specific watch-item: detection must survive the controls. With NTLM denied and signing required, the attacker’s attempts generate 8002 (outgoing NTLM blocked) and signing-mismatch events rather than successful logons — those are gold. Forward them (Windows Event Forwarding → Sentinel/your SIEM) and hunt them. A refused relay you saw is worth more than a relay you merely prevented and never knew was attempted. The KQL and ATT&CK mapping for hunting these live in KQL Threat Hunting Playbooks: MITRE ATT&CK Mapping, UEBA, and Hunting Notebooks.
// Hunt: blocked outgoing NTLM (8002) and NTLM auth surviving after deny (should trend to zero)
SecurityEvent
| where EventID == 8002 or (EventID == 4624 and AuthenticationPackageName == "NTLM")
| summarize count() by Computer, TargetServerName=tostring(EventData), bin(TimeGenerated, 1h)
| order by TimeGenerated desc
Cost & sizing
The good news: almost every control here is a configuration change, not a purchase. The costs are operational (engineering time, pilot effort) and, in a minority of cases, hardware refresh.
| Item | Direct cost | What actually drives it |
|---|---|---|
| SMB signing/encryption | Free (built-in) | CPU overhead of signing/AES — negligible on modern CPUs (AES-NI); test storage-heavy workloads |
| NTLM restriction/audit | Free (GPO) | Engineering time to audit and build exception lists |
| Credential Guard / VBS | Free (Enterprise/Server license already held) | Hardware: needs UEFI/Secure Boot/SLAT/TPM — old machines may need refresh |
| RunAsPPL / HVCI | Free | Driver compatibility testing (HVCI) |
| Protected Users | Free | Pilot effort to find broken dependencies |
| Windows LAPS | Free (in-box) | AD/Entra schema update; retrieval-access governance |
| Remote Credential Guard | Free | PAW provisioning (the hardware/build for privileged workstations) |
| ASR rules | Free with Defender AV; Defender for Endpoint adds reporting | E5/Defender for Endpoint licensing if you want central ASR reporting |
| Detection (WEF/SIEM) | Log ingestion cost | Event volume forwarded; Sentinel/SIEM per-GB pricing |
| SMB over QUIC | Free (in-box) + cert | Server-auth certificate lifecycle; OS edition (Azure Edition/2025) |
Sizing is mostly about the tail, not the steady state. The signing/AES CPU cost is negligible with AES-NI (benchmark only very high-throughput file servers, where encryption can cost a few percent), and VSM reserves a trivial amount of RAM per host — immaterial on machines with ≥8 GB. The numbers that drive budget are: the hardware-refresh tail (inventory for UEFI/Secure Boot/TPM 2.0/SLAT and budget to replace the non-compliant minority), SIEM ingestion (estimate GB/day for the forwarded security logs — 4624/4625/4768/4769/4776/8002 and the SMB/NTLM operational channels), and PAW count (one per Tier-0/Tier-1 admin — a small population by design). The pilot ring is 1–5% of the fleet, weighted to cover hardware variety, VPN clients, and LOB apps.
The dominant cost is engineering discipline — the audit-then-deny patience, the ring-based rollout, the configuration-as-code review — not money. The dominant risk of skimping is either an outage (skipping the audit) or a breach (skipping a band). In INR terms, the hard spend is typically only the hardware-refresh tail (machines too old for VBS) and any SIEM ingestion; the rest is labor you are spending anyway on security operations.
Interview & exam questions
1. What does NTLM authentication actually prove, and why does that enable pass-the-hash? NTLM proves possession of the NT hash (the MD4 of the password), not knowledge of the plaintext. Because the hash is a password-equivalent and never expires on its own, an attacker who steals it from LSASS can authenticate as that user indefinitely until the password changes — no cracking required. (Maps to SC-300/SC-200, Security+.)
2. SMB signing versus SMB encryption — which stops relay, and why doesn’t the other one? Signing appends a keyed MAC to each packet, so a relayed/tampered session fails the integrity check on a different channel — it stops relay. Encryption protects confidentiality on the wire but does not, by itself, prevent a valid authentication from being relayed; you need signing or channel binding for that. You want both, applied where each matters.
3. A team says “we enabled Credential Guard, so we’re protected from pass-the-hash.” What two checks and one caveat do you raise?
Check that it is running, not merely configured (Win32_DeviceGuard.SecurityServicesRunning must contain 1; LsaIso.exe must exist). Check coverage is universal (it only protects the host it runs on). Caveat: it does nothing for NTLM/SMB relay, nothing on domain controllers’ AD secrets, and nothing if a Tier-0 credential is interactively used on a compromised host — pair it with signing, NTLM restriction, and the Tier model.
4. What does the Protected Users group enforce, and who should you never put in it? For members it disables NTLM, DES/RC4 Kerberos, cached (offline) logon, unconstrained delegation, and caps the TGT at 4 hours. Never add accounts that need NTLM/RC4 (legacy apps/appliances), accounts that must log on offline (laptops), or an untested sole break-glass account — they will fail to authenticate.
5. Explain the difference between Remote Credential Guard and Restricted Admin for RDP. Remote Credential Guard keeps the credential on the client and uses Kerberos SSO so the admin’s identity flows to network resources without a reusable credential ever reaching the target — it assumes the client is trusted. Restricted Admin delegates no credential at all; you log on as the target machine’s network identity — use it for jump hosts where you trust neither end. Both keep the admin’s secret off a potentially-compromised server.
6. How does NTLM relay reach a domain controller, and what two controls close it? An attacker coerces a host (e.g., PetitPotam) to authenticate, then relays that NTLM exchange to the DC’s LDAP (or to AD CS web enrollment to mint a privileged certificate — the ESC8 chain). Require LDAP signing and channel binding on DCs, and enforce EPA (plus prefer Kerberos / disable NTLM) on the AD CS HTTP endpoints; also patch the coercion vector.
7. Why is the Tier administration model still necessary if Credential Guard isolates every secret in memory? Because a freshly-minted credential (e.g., a Domain Admin’s ticket created when they log on interactively) exists in that session regardless of isolation, and because not every host can run Credential Guard. The Tier model ensures high-value credentials are never present on lower-tier (more-exposed) systems, so even a total memory compromise on a workstation yields only Tier-2 credentials.
8. What is Kerberoasting, and which three controls reduce it most? An attacker requests a service ticket for an account with an SPN and cracks it offline to recover that account’s password — easiest when the ticket uses RC4 and the password is weak. The strongest controls: gMSA (120-char machine-managed password), disabling RC4 / enforcing AES, and putting service identities where possible in Protected Users (no RC4).
9. You require SMB signing but a relay still succeeds. Give two reasons. Either signing was enabled but not required (the “(if … agrees)” pair only), so the attacker forced a downgrade to unsigned — set the “(always)” pair on both client and server. Or the relay didn’t target SMB at all; it hit LDAP or an HTTP endpoint (AD CS/Exchange), which SMB signing doesn’t cover — enforce LDAP channel binding and HTTP EPA.
10. What does “RunAsPPL” protect, and what defeats it? RunAsPPL marks LSASS a Protected Process Light so userland processes cannot open a handle to read its memory, blocking Mimikatz’s standard read. A kernel-mode attacker — a malicious or vulnerable signed driver (BYOVD) — can still reach LSASS, which is why you pair RunAsPPL with HVCI/Memory Integrity and the vulnerable-driver blocklist.
11. Why disable RC4 for Kerberos, and what must you do first?
RC4-encrypted tickets are far cheaper to crack (Kerberoasting) and easier to forge from an NTLM hash (overpass-the-hash) than AES tickets. First audit for accounts/services pinned to RC4 (msDS-SupportedEncryptionTypes), remediate them (set 0x18 for AES, move services to gMSA), then enforce AES-only — disabling RC4 before auditing breaks anything still depending on it.
12. When is SMB over QUIC the right tool, and when is it the wrong one? Right for remote/branch/teleworker access to file servers over untrusted networks where you’d otherwise stand up a VPN or expose TCP/445 — it tunnels SMB 3.1.1 in QUIC over UDP/443 with mandatory TLS 1.3 and a server certificate. Wrong as a LAN transport, where signing + encryption over TCP/445 is simpler and faster; QUIC’s value is safe internet exposure, not intra-LAN traffic.
Quick check
- Which control stops NTLM/SMB relay but does nothing against pass-the-hash?
- What WMI property (and value) proves Credential Guard is actually running, not just configured?
- You must deny NTLM in the domain but a SCADA gateway authenticates NTLM-only by IP. What setting keeps it working?
- Which group, by membership alone, disables NTLM, RC4, cached logon, and unconstrained delegation for privileged admins?
- An admin RDPs to a server you may not fully trust and wants no credential delegated to it at all. Which RDP mode?
Answers
- SMB signing (required) — it binds the session against relay/tamper but has no effect on a replayed hash.
Win32_DeviceGuard.SecurityServicesRunningmust contain1(andVirtualizationBasedSecurityStatus = 2);LsaIso.exeshould also be present.- “Network security: Restrict NTLM: Add server exceptions in this domain” — name the gateway hostname(s) there while “Deny all” applies to the rest.
- Protected Users — but only add accounts that don’t need those legacy behaviors.
- Restricted Admin mode (
mstsc /restrictedAdmin) — it delegates no credential; you act as the machine’s network identity. (Remote Credential Guard keeps the cred on the client but does flow your identity via Kerberos.)
Glossary
| Term | Definition |
|---|---|
| Pass-the-hash (PtH) | Authenticating with a stolen NTLM hash instead of the password; the hash is a password-equivalent. |
| NTLM relay | Forwarding a coerced NTLM authentication to a third host to act as the victim; defeated by signing/EPA/channel binding. |
| Pass-the-ticket (PtT) | Replaying a stolen Kerberos TGT or service ticket from memory. |
| Overpass-the-hash | Using a stolen NTLM hash to request a fresh Kerberos TGT (turning a hash into a ticket). |
| Kerberoasting | Requesting a service ticket for an SPN and cracking it offline to recover the account’s password. |
| Golden / Silver ticket | Forged Kerberos tickets minted from the krbtgt key (Golden) or a service account’s key (Silver). |
| SMB signing | A keyed MAC on every SMB packet that prevents tampering and relay. |
| SMB encryption | AES-GCM/CCM confidentiality for SMB 3.x traffic, server-wide or per-share. |
| Credential Guard | VBS feature isolating LSA secrets (hashes, tickets) in the LSAIso trustlet, unreadable from the normal OS. |
| VBS / VSM | Virtualization-Based Security / Virtual Secure Mode — Hyper-V-rooted memory isolation (VTL 0 vs VTL 1). |
| RunAsPPL | Running LSASS as a Protected Process Light to block userland memory reads. |
| Protected Users | AD group that hardens member credential behavior (no NTLM/RC4/caching/delegation; short TGT). |
| Windows LAPS | In-box feature rotating and storing unique local-admin passwords in AD/Entra. |
| Remote Credential Guard | RDP mode keeping the credential on the client (Kerberos SSO) so no reusable secret reaches the target. |
| Kerberos armoring (FAST) | Encrypting the Kerberos pre-auth with the machine’s TGT to thwart offline cracking and spoofing. |
| EPA / channel binding | Extended Protection for Authentication — binds NTLM to the TLS channel so a relayed auth is rejected. |
| Tier model | Privilege separation (Tier 0/1/2) preventing credentials from crossing down to more-exposed systems. |
Next steps
- Design the directory and Tier-0 isolation this hardening assumes in Building an AD DS Forest the Right Way: Deployment, FSMO, and a Tiered Admin Model.
- Eliminate the other major credential-reuse vector — static service accounts — with Eliminating Static Service Credentials with gMSA and Windows LAPS.
- Keep these dozens of interacting GPO/registry settings reviewable and reversible using Group Policy at Scale: A Maintainable Architecture and Managing GPOs as Code.
- Put lateral-movement defense inside the larger strategy with Zero Trust Architecture Blueprint: Identity, Network, and Data Pillars.
- Operationalize just-in-time privileged access and PAWs with Privileged Identity Management and PAM Architecture: Just-in-Time Access at Scale.
- Hunt the residual attempts (refused NTLM, signing mismatches, suspicious tickets) with KQL Threat Hunting Playbooks: MITRE ATT&CK Mapping, UEBA, and Hunting Notebooks.