Most breaches do not stay where they land. An attacker phishes one workstation, dumps cached credentials, and within an 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: 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.
This guide hardens all three. We remove SMBv1, enforce SMB signing and encryption, clamp down on NTLM, then deploy virtualization-based Credential Guard so the secrets an attacker wants are no longer reachable from the OS. Everything targets Windows Server 2019/2022/2025 and Windows 10/11 in a domain. Test in a 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.
1. The lateral movement kill chain: SMB, NTLM, and credential theft
Before changing anything, be precise about what you are defending against. Three distinct techniques chain together:
- Pass-the-hash (PtH) — The attacker dumps the NTLM hash from LSASS (via Mimikatz,
comsvcs.dllminidump, or a stolen credential cache) and replays it directly. No plaintext password needed; NTLM authentication only ever proves possession of the hash. - SMB relay (NTLM relay) — The attacker coerces a victim to authenticate to a machine they control (PetitPotam, printer bug, a poisoned name-resolution response), then relays that NTLM exchange to a third server. If signing is not enforced, the relayed session is accepted as the victim.
- Pass-the-ticket — Kerberos TGTs or service tickets are lifted from memory and reused, including forged Golden/Silver tickets.
Each link has a countermeasure, and they are not interchangeable. SMB signing defeats relay but does nothing for PtH. Credential Guard defeats PtH and pass-the-ticket but does nothing for relay. You need the full set.
| Technique | Carrier | Primary mitigation |
|---|---|---|
| Pass-the-hash | NTLM over SMB | Credential Guard, restrict/disable NTLM |
| SMB / NTLM relay | NTLM over SMB | SMB signing, EPA / channel binding |
| Pass-the-ticket | Kerberos | Credential Guard, tiered admin |
2. Removing SMBv1 and enforcing SMB signing and encryption
SMBv1 has no signing worth the name, no encryption, and a decade of wormable bugs (EternalBlue). It has been off by default in Windows 10/Server 2019+, but it lingers in environments that once had a NAS or a copier that needed it. Confirm and remove it.
# Check current SMBv1 state (both the protocol and the optional feature)
Get-SmbServerConfiguration | Select-Object EnableSMB1Protocol
Get-WindowsOptionalFeature -Online -FeatureName SMB1Protocol | Select-Object State
# Disable the SMBv1 server protocol and remove the feature entirely
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart
Before you pull SMBv1, find what is still using it. The SMB server logs every SMBv1 access attempt when auditing is on:
Set-SmbServerConfiguration -AuditSmb1Access $true -Force
# Then review: Microsoft-Windows-SMBServer/Audit (Event ID 3000)
Get-WinEvent -LogName 'Microsoft-Windows-SMBServer/Audit' -MaxEvents 50 |
Where-Object Id -eq 3000
With SMBv1 gone, enforce signing and encryption on SMBv2/3. Signing stops relay and tampering by appending a keyed MAC to every packet. Encryption (SMB 3.x, AES-GCM/CCM) protects confidentiality on the wire.
# Server side: require signing for all inbound SMB sessions
Set-SmbServerConfiguration -RequireSecuritySignature $true -EnableSecuritySignature $true -Force
# Client side: require signing on all outbound connections
Set-SmbClientConfiguration -RequireSecuritySignature $true -EnableSecuritySignature $true -Force
# Require encryption server-wide (SMB 3.0+ clients only)
Set-SmbServerConfiguration -EncryptData $true -Force
EncryptData $true at the server level rejects any client that cannot negotiate SMB 3.x encryption, which can lock out older Linux/macOS SMB stacks. The safer pattern is per-share encryption on the data that actually needs it, leaving the server default for broad compatibility:
# Encrypt one share, not the whole server
Set-SmbShare -Name "FinanceData" -EncryptData $true -Force
Windows 11 24H2 and Windows Server 2025 require SMB signing by default for both client and server, and add SMB-over-QUIC and mandatory encryption options. On those builds, plan for signing being on whether you set it or not.
Roll signing out by Group Policy so it survives rebuilds. The four canonical policies live under Computer Configuration > Policies > Windows Settings > Security Settings > Local Policies > Security Options:
Microsoft network server: Digitally sign communications (always) = Enabled
Microsoft network client: Digitally sign communications (always) = Enabled
Microsoft network server: Digitally sign communications (if client agrees) = Enabled
Microsoft network client: Digitally sign communications (if server agrees) = Enabled
3. Restricting NTLM and auditing NTLM authentication traffic
NTLM is the substrate for both PtH and relay. You rarely get to disable it outright on day one — too many appliances, scanners, and line-of-business apps still authenticate by IP or with NTLM-only stacks. So audit first, then restrict.
Turn on NTLM auditing fleet-wide before blocking anything. These policies are under Computer Configuration > Policies > Windows Settings > Security Settings > Local Policies > Security Options, “Network security: Restrict NTLM: …”:
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, and in the NTLM/Operational log plus Security 4624 (Logon, with “Authentication Package: NTLM”) on servers. Harvest the outgoing-NTLM events to build your allow-list of legitimate NTLM consumers:
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
Once you know who genuinely needs NTLM, flip from audit to deny and carve out exceptions. On domain controllers:
Network security: Restrict NTLM: NTLM authentication in this domain
= Deny for domain servers (or "Deny all" once you are confident)
Network security: Restrict NTLM: Add server exceptions in this domain
= legacy-app01.corp.example.com
scanner-fleet*.corp.example.com
On member servers and clients, force NTLMv2 only and refuse the ancient LM/NTLMv1 responses, which are trivially crackable:
Network security: LAN Manager authentication level
= Send NTLMv2 response only. Refuse LM & NTLM (value 5)
For the registry-driven equivalent of that last one (useful in MDM/Intune):
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa' `
-Name 'LmCompatibilityLevel' -Value 5 -Type DWord
4. Enabling virtualization-based security and Credential Guard
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 derived credentials into the LSAIso isolated process, protected by a Hyper-V-based Virtual Secure Mode that the host OS — and therefore Mimikatz — cannot read. Even with SYSTEM, an attacker can no longer dump usable secrets for accounts that logged on under Credential Guard.
Requirements: UEFI with Secure Boot, VT-x/AMD-V plus SLAT (EPT/NPT), and ideally TPM 2.0 for key binding. On Windows 11 22H2+/Server 2025, VBS and Credential Guard are enabled by default on qualifying hardware. Everywhere else, deploy by policy.
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
“UEFI lock” is the important choice. It writes a variable to firmware so Credential Guard cannot be silently disabled by a registry edit from a compromised admin context — turning it back off requires physical/console access to clear the lock. Use it for production tier-0 and servers; use “Enabled without lock” only while piloting so you can disable remotely.
The registry equivalent, for imaging or Intune:
# Enable VBS, require Secure Boot, and turn on Credential Guard with UEFI lock
$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 1 -Type DWord # 1=Secure Boot, 3=+DMA
Set-ItemProperty -Path "$dg\Scenarios\CredentialGuard" -Name 'Enabled' -Value 1 -Type DWord
Reboot, then confirm it is not merely configured but actually running (the distinction matters — a missing hardware prerequisite leaves it configured-but-off):
$g = Get-CimInstance -ClassName Win32_DeviceGuard `
-Namespace 'root\Microsoft\Windows\DeviceGuard'
$g.SecurityServicesConfigured # 1 = Credential Guard configured
$g.SecurityServicesRunning # 1 = Credential Guard RUNNING <-- this is the one that counts
$g.VirtualizationBasedSecurityStatus # 2 = running
A value of 1 in the SecurityServicesRunning array is your proof. You can also confirm LsaIso.exe is present in the process list.
5. Deploying Remote Credential Guard for RDP sessions
Credential Guard protects the machine you sit at. The moment an admin RDPs into a server, the old behavior delegated their credentials to the remote host — so compromising any server an admin touched yielded that admin’s secrets. Remote Credential Guard fixes this by keeping the credentials on the client and using Kerberos to single-sign-on into the remote session without ever sending a reusable credential to the target. (For jump hosts where you do not even trust the client, Restricted Admin mode is the stricter sibling: it logs you in as the remote machine’s network identity with no credential delegation at all.)
Enable Remote Credential Guard on the servers that will accept such connections:
# On the RDP target: allow Remote Credential Guard delegation
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa' `
-Name 'DisableRestrictedAdmin' -Value 0 -Type DWord
On the clients initiating RDP, require it 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
Then connect with the flag (Kerberos and line-of-sight to a KDC are required; this does not work for cross-domain-without-trust or saved-credential scenarios):
mstsc.exe /remoteGuard /v:server01.corp.example.com
Now an attacker who fully owns server01 gets the machine, but not the domain-admin hash of whoever administered it.
6. Mitigating SMB relay with EPA and channel binding
SMB signing kills SMB relay. But NTLM relay also targets LDAP, HTTP (AD CS web enrollment, Exchange), 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.
For domain controllers, enforce LDAP signing and LDAP channel binding (the PetitPotam-to-AD-CS attack relayed exactly here). 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
For AD CS, the certificate enrollment web endpoints are the classic relay target. Enforce HTTPS and EPA on the CA web enrollment / NDES sites:
# Enforce EPA (Required) on the CertSrv web enrollment app in IIS
Set-WebConfigurationProperty `
-Filter '/system.webServer/security/authentication/windowsAuthentication/extendedProtection' `
-PSPath 'IIS:\Sites\Default Web Site\CertSrv' `
-Name 'tokenChecking' -Value 'Require'
Pair that with disabling NTLM on those endpoints where possible (Kerberos-only enrollment), and the PetitPotam relay path is closed end to end.
Verify
Do not trust that policy applied; prove each control is live.
# 1) SMBv1 is gone
(Get-SmbServerConfiguration).EnableSMB1Protocol # expect: False
(Get-WindowsOptionalFeature -Online -FeatureName SMB1Protocol).State # expect: Disabled
# 2) SMB signing required, both sides
(Get-SmbServerConfiguration).RequireSecuritySignature # expect: True
(Get-SmbClientConfiguration).RequireSecuritySignature # expect: True
# 3) An active SMB connection is actually signed/encrypted
Get-SmbConnection | Select-Object ServerName, Dialect, Signed, Encrypted
# 4) NTLMv2-only enforced
(Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa').LmCompatibilityLevel # expect: 5
# 5) Credential Guard is RUNNING (not just configured)
(Get-CimInstance Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard).SecurityServicesRunning # expect array containing 1
For an end-to-end test, attempt a benign relay or a credential dump in an isolated lab. With Credential Guard running, an LSASS minidump no longer yields NTLM hashes for interactive logons; the wdigest plaintext field is empty and the secrets live in LsaIso. With signing required, an NTLM relay attempt fails at the SMB layer with a signing mismatch rather than authenticating as the victim. Confirm via the SMB and NTLM operational logs that the attempts were rejected, not merely unattempted.
Enterprise scenario
A multinational manufacturer ran an annual red-team exercise. The 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 session, and pass-the-hashed their way to a domain controller in 38 minutes. The platform team’s mandate was blunt: make that exact path stop working, without breaking the SCADA gateways that still spoke SMBv2 and NTLM and could not be patched on 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. Credential Guard with UEFI lock went onto every Windows endpoint and server fleet-wide via the Device Guard GPO — that alone removed the dumpable hash that started the chain, and the OT gateways were unaffected because they were never the credential source. SMB signing was made mandatory everywhere (signing, unlike encryption, is supported by SMBv2). The OT subnet was carved into its own AD site with an NTLM server-exception list naming exactly the gateway hostnames, while “Deny all” NTLM applied to the rest of the domain.
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, and the one NTLM authentication they coerced was refused everywhere except the explicitly excepted OT gateways, which held no privileged credentials. Time-to-domain-admin went from 38 minutes to “not achieved.” The lesson the team wrote up: the fix was not a single silver bullet but the combination — Credential Guard removed the secret, signing removed the relay, and surgical NTLM exceptions kept the unpatchable OT kit alive without leaving a domain-wide hole.