← All posts

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:

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:

  1. Set RestrictSendingNTLMTraffic = 1 (Audit all).
  2. Watch Operational events in Applications and Services Logs → Microsoft → Windows → NTLM (event ID 8001) to see which servers your machine legitimately sends NTLM to.
  3. Whitelist only what is truly needed with ClientAllowedNTLMServers, then flip the value to 2.
# 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:

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:

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.