NTLM Coercion and Relay: Why Your Windows Machine Should Refuse to Send NTLM
A single UNC path or PetitPotam-style trigger can force Windows to hand an attacker a relayable NTLM credential. Here is how the RestrictSendingNTLMTraffic control shuts that door - and how WinSentinel audits it.
Most Windows credential attacks people worry about need the attacker to already be on the box: dump LSASS, pull hashes, pass-the-hash. But there is an older, quieter class of attack that needs none of that. It just needs your machine to voluntarily send an NTLM authentication somewhere the attacker can catch it. That is NTLM coercion and relay, and it is one of the most reliable lateral-movement techniques on Windows networks.
The fix is not glamorous. It is a single registry value that tells Windows to stop sending NTLM to remote servers at all. WinSentinel now audits it as part of the LSA hardening module.
How coercion works
NTLM is a challenge-response protocol. When your machine connects to a server that asks for authentication, Windows will - by default - happily perform an NTLM handshake on your behalf. The problem is how easy it is to make your machine connect somewhere. Any of these can trigger an outbound authentication:
- A booby-trapped UNC path (
\\attacker\share) in an email, a shortcut, an Office document, or a web page. - A PetitPotam-style RPC call that forces a machine (often a domain controller) to authenticate back to the caller.
- The printer bug (
MS-RPRN) and its many cousins that abuse legitimate RPC interfaces to coerce authentication. - LLMNR/NBT-NS name-resolution poisoning that steers a stray lookup toward the attacker.
In every case, the attacker ends up holding an NTLMv2 response from your account or your machine account. They can crack it offline, or - far more dangerous - relay it, unmodified, to a third host that accepts NTLM (LDAP, SMB, AD CS web enrollment) and authenticate as you without ever knowing your password.
The whole attack chain works because your machine is willing to send NTLM to whoever asks. Take away that willingness and the chain breaks at step one.
The control: RestrictSendingNTLMTraffic
Windows exposes exactly the switch you want under the LSA MSV1_0 provider:
HKLM\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0
RestrictSendingNTLMTraffic (DWORD)
0 = Allow all (the default - send NTLM to anyone)
1 = Audit all (log outbound NTLM, but still send it)
2 = Deny all (refuse to send NTLM to remote servers)
The hardened state is 2 (Deny all). At that setting, a coercion trigger produces nothing useful: your machine simply will not emit an NTLM response for a remote server, so there is nothing to capture, crack, or relay.
Roll it out without breaking logins
Do not jump straight to Deny in a live environment - some legacy apps and appliances still depend on outbound NTLM. Instead:
- Set
RestrictSendingNTLMTraffic = 1(Audit all). - Watch Operational events in Applications and Services Logs → Microsoft → Windows → NTLM (event ID 8001) to see which servers your machine legitimately sends NTLM to.
- Whitelist only what is truly needed with
ClientAllowedNTLMServers, then flip the value to2.
# Audit first
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0' `
-Name RestrictSendingNTLMTraffic -Type DWord -Value 1
# ...review NTLM event 8001, then deny...
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0' `
-Name RestrictSendingNTLMTraffic -Type DWord -Value 2
Pair it with the rest of the NTLM hardening
Refusing to send NTLM is the strongest single move, but it works best alongside the controls WinSentinel already checks in the same LSA module:
- LmCompatibilityLevel = 5 - send NTLMv2 only, refuse LM/NTLMv1 (kills offline-crackable downgrades).
- NoLMHash = 1 - never store the trivially-cracked LM hash.
- RunAsPPL = 1 - protect LSASS memory so captured creds are not compounded by a dump.
- WDigest UseLogonCredential = 0 - no plaintext passwords cached in memory.
- On the receiving side, enable SMB signing and LDAP channel binding/signing so relayed sessions are rejected even if one leaks.
How WinSentinel audits this
Run a local audit and the LSA Hardening module reads RestrictSendingNTLMTraffic straight from the registry and grades it:
winsentinel --audit
You will get one of three findings under Credentials:
- Pass - the value is
2(Deny all). Outbound NTLM is off; coercion has nothing to steal. - Warning (audit only) - the value is
1. NTLM is logged but still sent; finish your review and move to Deny. - Warning (allowed) - the value is
0or absent, the Windows default. Your machine will send NTLM to any server that asks. The finding ships with the exact PowerShell to start auditing and then deny.
This is a single-machine registry check, so it is part of the free, open-source WinSentinel core - no license, no fleet required. Install it and run one audit:
dotnet tool install --global WinSentinel.Cli
winsentinel --audit
If you manage more than one machine, WinSentinel Pro rolls this same finding up across your whole fleet so you can see - and enforce - "every node denies outbound NTLM" in one view. But the check itself, on the machine in front of you, is free forever.