If your GPO did not do what you think:

There are two separate reasons NTLMv1 can still be running in an environment that looks hardened. The Silverfort bypass via the Netlogon ParameterControl flag affects application servers regardless of your domain policy. The tattooed registry issue affects any machine that had a previous GPO write the value directly. Both are invisible unless you actively look. The steps below cover both.

The Finding

Most admins set LMCompatibilityLevel to 5 via GPO a few years ago and moved on. Job done, NTLMv1 blocked. Except in early 2025 Silverfort's research team showed that on-prem applications can bypass that policy entirely by setting a flag in the Netlogon Remote Protocol that explicitly permits NTLMv1. The domain controller accepts it without question. Your GPO does nothing to stop it. Microsoft confirmed the behaviour, declined to call it a vulnerability, and responded by announcing the full removal of NTLMv1 starting with Windows 11 24H2 and Windows Server 2025.

If you are running anything older you are on your own.

There is a second problem that predates this research. Old GPOs that previously set LmCompatibilityLevel leave the value tattooed in the registry even after you change or remove the policy. If you inherited an environment there could be machines sitting at level 2 or 3 right now because a GPO from five years ago wrote the value and nobody cleaned it up. You would not know unless you actually checked.

The safe order is audit first, enforce second. Skipping the audit and going straight to enforcement is how you cause mass account lockouts at 9am on a Monday.

The Fix

Step 1 — Turn on NTLM audit logging before touching anything

Push these three settings via your Default Domain Controllers Policy:

Computer Configuration → Windows Settings
→ Security Settings → Local Policies → Security Options

Network Security: Restrict NTLM:
  Audit NTLM authentication in this domain
  → Enable all

Network Security: Restrict NTLM:
  Audit Incoming NTLM Traffic
  → Enable auditing for all accounts

Network Security: Restrict NTLM:
  Audit Outgoing NTLM traffic to remote servers
  → Audit all

Leave this running for at least two weeks. Watch Event ID 4624 on member servers and check the Package Name field. That field tells you whether the authentication was NTLMv1 or NTLMv2. Event ID 4776 on domain controllers shows credential validation attempts but does not capture the NTLM version, so 4624 on the member servers is where you need to look.

Step 2 - Check for tattooed registry values

Before you set a new policy, check what is actually sitting in the registry on your domain controllers and a sample of workstations:

Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
-Name LmCompatibilityLevel -ErrorAction SilentlyContinue

If you get back a value lower than 5 on a machine that should be covered by your new GPO, something has tattooed it. You will need to correct that via a GPO preference that forces the value rather than just setting a policy.

Step 3 - Set LMCompatibilityLevel to 5

Once you have confirmed what is using NTLMv1 and dealt with any legacy dependencies, push this via your Default Domain Controllers Policy and a separate workstation GPO:

Computer Configuration → Windows Settings
→ Security Settings → Local Policies → Security Options
→ Network security: LAN Manager authentication level
→ Send NTLMv2 response only. Refuse LM and NTLM

Or via registry if you prefer GPO Preferences:

HKLM\SYSTEM\CurrentControlSet\Control\Lsa
Value: LmCompatibilityLevel
Type: DWORD
Data: 5

No reboot required. Takes effect immediately.

Step 4 - Verify NTLMv1 is acutally gone

After the GPO applies run this on a domain controller:

Get-WinEvent -FilterHashtable @{ LogName='Security'; Id=4624 } | Where-Object { $_.Message -match 'NTLM V1' } | Select-Object TimeCreated, Message ```

No results means NTLMv1 is not showing up in auth logs. Keep monitoring for another two weeks to catch anything that only authenticates on a schedule like scheduled tasks or backup jobs.

One Action Today

Run the Step 2 PowerShell command on at least one domain controller right now and check what value LmCompatibilityLevel is actually sitting at.

Keep Reading