NTLMless: The Death of NTLM in Windows
Thirty years of pass-the-hash, NTLM relay, PetitPotam, and ESC8 -- and the Kerberos engineering that finally lets Microsoft turn NTLM off by default.
Permalink1. Eight Minutes
A defender has done every retrofit Microsoft has shipped over twenty years. SMB signing enforced on every member server. EPA enabled on every IIS endpoint. Credential Guard on. Restrict NTLM in audit mode. KB 5005413 applied to AD CS. An attacker with no credentials joins their network, runs Coercer against a domain controller, and a handful of seconds later holds a Kerberos ticket-granting ticket for the Domain Admin account [1, 2]. Total elapsed time: less than the time it took you to read this paragraph. Total prerequisites for the chain: that NTLM still exists as a fallback path on Windows.
The chain has a name. ESC8, from Will Schroeder and Lee Christensen's "Certified Pre-Owned" whitepaper, published June 17, 2021 [2, 3]. Its coercion primitive has another name. PetitPotam, from Lionel Gilles, published the next month [4, 5]. Together they take a fully retrofitted Active Directory environment to Domain Admin in four steps.
Pause on what is and is not true here. SMB signing did not fail; SMB signing was not in the chain. EPA failed because it was deployed on IIS authentication endpoints generally but the /certsrv/ deployment lagged [7]. Credential Guard did not fail; Credential Guard protects the NT-hash, and the attacker never touched a hash. Restrict NTLM in audit mode worked exactly as labelled: it audited.
The retrofits are not wrong. They patch the named primitives. The chain exploits the existence of the fallback path, not a primitive. Every protective control is honest about what it does and silent about what it does not.
Diagram source
sequenceDiagram
autonumber
actor A as Attacker (no creds)
participant DC as Domain Controller
participant R as ntlmrelayx listener
participant CA as AD CS /certsrv/
participant KDC as KDC (PKINIT)
A->>DC: EfsRpcOpenFileRaw(UNC=\attacker\share)
DC->>R: NTLM AUTHENTICATE (SYSTEM = DC<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mi>a</mi><mi>c</mi><mi>h</mi><mi>i</mi><mi>n</mi><mi>e</mi><mi>a</mi><mi>c</mi><mi>c</mi><mi>o</mi><mi>u</mi><mi>n</mi><mi>t</mi><mo stretchy="false">)</mo><mi>R</mi><mo>−</mo><mo>></mo><mo>></mo><mi>C</mi><mi>A</mi><mo>:</mo><mi>R</mi><mi>e</mi><mi>l</mi><mi>a</mi><mi>y</mi><mi>N</mi><mi>T</mi><mi>L</mi><mi>M</mi><mo separator="true">,</mo><mi>e</mi><mi>n</mi><mi>r</mi><mi>o</mi><mi>l</mi><mi>l</mi><mi>M</mi><mi>a</mi><mi>c</mi><mi>h</mi><mi>i</mi><mi>n</mi><mi>e</mi><mi>c</mi><mi>e</mi><mi>r</mi><mi>t</mi><mi>a</mi><mi>s</mi><mi>D</mi><mi>C</mi></mrow><annotation encoding="application/x-tex"> machine account)
R->>CA: Relay NTLM, enroll Machine cert as DC</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em"></span><span class="mord mathnormal">ma</span><span class="mord mathnormal">c</span><span class="mord mathnormal">hin</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">cco</span><span class="mord mathnormal">u</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mclose">)</span><span class="mord mathnormal" style="margin-right:0.0077em">R</span><span class="mord">−</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">>></span><span class="mspace" style="margin-right:0.2778em"></span></span><span class="base"><span class="strut" style="height:0.6833em"></span><span class="mord mathnormal" style="margin-right:0.0715em">C</span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2778em"></span></span><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em"></span><span class="mord mathnormal" style="margin-right:0.0077em">R</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.0359em">y</span><span class="mord mathnormal" style="margin-right:0.109em">N</span><span class="mord mathnormal" style="margin-right:0.1389em">T</span><span class="mord mathnormal">L</span><span class="mord mathnormal" style="margin-right:0.109em">M</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em"></span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal" style="margin-right:0.109em">M</span><span class="mord mathnormal">a</span><span class="mord mathnormal">c</span><span class="mord mathnormal">hin</span><span class="mord mathnormal" style="margin-right:0.0278em">ecer</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.0278em">sD</span><span class="mord mathnormal" style="margin-right:0.0715em">C</span></span></span></span>
CA-->>R: Client certificate for DC<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>R</mi><mo>−</mo><mo>></mo><mo>></mo><mi>K</mi><mi>D</mi><mi>C</mi><mo>:</mo><mi>P</mi><mi>K</mi><mi>I</mi><mi>N</mi><mi>I</mi><mi>T</mi><mi>A</mi><mi>S</mi><mo>−</mo><mi>R</mi><mi>E</mi><mi>Q</mi><mi>w</mi><mi>i</mi><mi>t</mi><mi>h</mi><mi>D</mi><mi>C</mi></mrow><annotation encoding="application/x-tex">
R->>KDC: PKINIT AS-REQ with DC</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7667em;vertical-align:-0.0833em"></span><span class="mord mathnormal" style="margin-right:0.0077em">R</span><span class="mord">−</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">>></span><span class="mspace" style="margin-right:0.2778em"></span></span><span class="base"><span class="strut" style="height:0.6833em"></span><span class="mord mathnormal" style="margin-right:0.0715em">K</span><span class="mord mathnormal" style="margin-right:0.0278em">D</span><span class="mord mathnormal" style="margin-right:0.0715em">C</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2778em"></span></span><span class="base"><span class="strut" style="height:0.7667em;vertical-align:-0.0833em"></span><span class="mord mathnormal" style="margin-right:0.1389em">P</span><span class="mord mathnormal" style="margin-right:0.0715em">K</span><span class="mord mathnormal" style="margin-right:0.0785em">I</span><span class="mord mathnormal" style="margin-right:0.109em">N</span><span class="mord mathnormal" style="margin-right:0.0785em">I</span><span class="mord mathnormal" style="margin-right:0.1389em">T</span><span class="mord mathnormal">A</span><span class="mord mathnormal" style="margin-right:0.0576em">S</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em"></span></span><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em"></span><span class="mord mathnormal" style="margin-right:0.0077em">R</span><span class="mord mathnormal" style="margin-right:0.0576em">E</span><span class="mord mathnormal" style="margin-right:0.0269em">Qw</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal" style="margin-right:0.0278em">D</span><span class="mord mathnormal" style="margin-right:0.0715em">C</span></span></span></span> cert
KDC-->>A: TGT for DC$ -> request service tickets at will This is the question that drives the rest of the article: how did Windows arrive at a state where the most catastrophic modern Active Directory attack chain depends on a thirty-year-old fallback nobody wants?
2. Origins: Why NTLM Existed at All
Rewind to 1987. IBM and Microsoft ship LAN Manager 1.0 for OS/2. PCs are still mostly file-and-print islands on Token Ring or 10BASE-2 coax; networking exists, but "domain" is a word for what a single server controls. LAN Manager needs an authentication scheme that can run on hardware with 640 KB of RAM, no DES export licence, and roughly zero institutional knowledge about cryptography. What it produces, the LM hash, is a near-perfect snapshot of every constraint and assumption of its moment [8].
The construction is short enough to write out. Take the password. Uppercase it. Pad or truncate to exactly fourteen ASCII characters. Split into two seven-byte halves. Convert each half into a 56-bit DES key (the eighth bit of each byte is a parity bit). Use each key to DES-encrypt the eight-byte constant KGS!@#$%. Concatenate the two eight-byte ciphertexts. That is the LM hash [8, 9].
The LAN Manager password hash from 1987. Constructed by uppercasing the password, truncating or padding to 14 characters, splitting into two 7-byte halves, and DES-encrypting the constant KGS!@#$% with each half as a key. The two halves are independent, the password is case-insensitive, and there is no salt. Every property of this construction enables an attack class that survives into NTLMv2 [8].
KGS!@#$% is what you get when somebody types "KGS" and then mashes shift-1, shift-2, shift-3, shift-4, shift-5 on a 1980s American IBM keyboard. The constant is in the protocol because the protocol predates the cryptographic-engineering norm that constants should look random. It would not survive a 2026 design review; in 1987 nobody asked.
Every choice tells a story about 1987. Uppercase, because some clients normalised case anyway and the developers wanted authentication to "just work" across mixed locale settings. Fourteen characters, because that was the field width DOS dictated. Two halves, because a 56-bit DES key already maxed out the practical computation; nobody was going to chain two DES operations through a feedback function with that much per-keystroke latency. No salt, because the deployment model was one server, one user database, and identical-password collisions were a feature for the help desk, not a leak.
The result is password-equivalent: anyone who possesses the LM hash is the user, forever, regardless of how the wire protocol presents the credential.
Six years later, July 27, 1993, Windows NT 3.1 ships. NTLM(v1) arrives with it [9]. The NT-hash is what you would design if you started over with mid-1990s assumptions but were not yet willing to abandon DES at the response layer. It is simpler than the LM hash and stronger in exactly one place: NT-hash = MD4(UTF-16LE(password)) [10, 9]. No truncation. No case folding. Sixteen bytes of output. The hash is still password-equivalent; what changes is that the input to the hash is now whatever Unicode string the user typed, in full.
The wire protocol around the NT-hash is the famous three-message handshake. NEGOTIATE from the client. CHALLENGE from the server (an eight-byte random nonce). AUTHENTICATE from the client, carrying a DES-based response computed from the NT-hash and the server challenge. The whole exchange is self-contained: nothing in the three messages binds the authentication to a particular transport, a particular client, a particular server, or a particular service [11]. That property -- the absence of binding -- is the property NTLM relay will eat for the next twenty-five years.
MD4(UTF-16LE(password)). Sixteen bytes. The single long-term secret that every NTLM authentication ever performed for a given user derives from. Possession of the NT-hash is mathematically equivalent to possession of the password for every authentication purpose. NTLMv2 changes the response computation but not the hash [10, 9].
Diagram source
timeline
title NTLM and Windows authentication, 1987-2027
1987 : LAN Manager 1.0 ships : LM hash construction
1993 : Windows NT 3.1 : NTLMv1 + NT-hash MD4(UTF-16LE(pwd))
1998 : NT 4.0 SP4 : NTLMv2 with HMAC-MD5 and AV_PAIRS
2000 : Windows 2000 : Kerberos is the default; NTLM demoted to fallback
2008 : MS08-068 patches SMB self-relay (CVE-2008-4037)
2015 : Windows 10 RTM ships Credential Guard
2019 : CVE-2019-1040 Drop the MIC (Simakov/Zinar)
2021 : PetitPotam (Gilles) + ESC8 (Schroeder/Christensen)
2023 : Palko commits to removing NTLM (October 11)
2024 : NTLM marked deprecated (June); NTLMv1 removed in 24H2/Server 2025
2025 : KB 5064479 enhanced NTLM auditing
2026 : Phase 1 (audit) + IAKerb/Local KDC pre-release (Phase 2)
2027 : Phase 3 -- NTLM disabled by default (next major Windows release) The third revision arrives with NT 4.0 Service Pack 4, October 1998. NTLMv2 throws away DES at the response layer and replaces it with HMAC-MD5. It introduces a client challenge (so the response is no longer purely a function of the server's choice). It introduces AV_PAIRS, a small TLV structure carrying the target name, a timestamp, and -- in much later retrofits -- the channel binding hash and message integrity field [11, 9]. NTLMv2 defeats pre-computation attacks against the response. It does not change the long-term secret. The NT-hash is still the NT-hash; possession is still authority.
An intermediate variant, NTLM2 Session Security, shipped in NT 4.0 SP4 alongside NTLMv2 and is the dead end most often confused for v2. It added an 8-byte client challenge to the NTLMv1 DES envelope without touching the long-term hash, hoping to defeat pre-computation while preserving wire compatibility. It survived only as a transitionalLMCompatibilityLevel setting; nothing in the modern attack catalogue treats NTLM2 SS as a distinct target [11, 12].
| Property | LM hash (1987) | NTLMv1 (1993) | NTLMv2 (1998) |
|---|---|---|---|
| Hash function for the long-term secret | DES of constant with password halves | MD4(UTF-16LE(password)) | MD4(UTF-16LE(password)) |
| Case-sensitive | No (uppercase only) | Yes | Yes |
| Max input length | 14 characters (truncated) | Unlimited Unicode | Unlimited Unicode |
| Salted | No | No | Per-exchange client challenge + timestamp |
| Response keyed MAC | DES (3 keys, 56-bit each) | DES (3 keys, 56-bit each) | HMAC-MD5 |
| Binds to target server name | No | No | AV_PAIR MsvAvTargetName (retrofit) |
| Binds to TLS endpoint | No | No | AV_PAIR MsvAvChannelBindings (retrofit) |
| Possession of hash = authority | Yes | Yes | Yes |
The two production response constructions on top of the same NT-hash. NTLMv1 chains three 56-bit DES operations across K1 = NT-hash[0:7], K2 = NT-hash[7:14], K3 = NT-hash[14:16] || \x00\x00\x00\x00\x00, encrypting the eight-byte server challenge under each. The third sub-key has only 16 bits of real entropy. NTLMv2 replaces all three DES operations with one HMAC-MD5 over server_challenge || client_challenge || timestamp || av_pairs, keyed by NTOWFv2 = HMAC_MD5(NT-hash, UNICODE(Upper(user) || domain)) [11, 9].
Then comes Windows 2000, and Kerberos. Microsoft's plan was simple: in a domain, Kerberos handles everything; NTLM stays around as a compatibility blanket for the cases Kerberos cannot cover yet [13]. The trouble was that "the cases Kerberos cannot cover yet" turned out to be a permanent set, not a transitional one. Twenty-three years later, the same four cases would be the table-of-contents of Microsoft's NTLM-removal plan [14]:
- No domain-controller line-of-sight. A laptop on a hotel Wi-Fi authenticating to a corporate file share through a VPN tunnel terminator has no Kerberos KDC to talk to. NTLM does not need one.
- Local accounts. A user signing into a workgroup machine or a domain-joined machine's local SAM has no domain at all; Kerberos has nothing to authenticate against.
- No service principal name. Kerberos requires a known SPN for the target service. Connect to a server by raw IP, by an alias DNS name not yet in the SPN database, or by a CNAME the operator forgot to register -- there is no SPN, so Kerberos cannot run.
- Hard-coded NTLM. Application code that calls
AcquireCredentialsHandleW(..., "Ntlm", ...)or RPC code that asks forRPC_C_AUTHN_WINNTdirectly bypasses the negotiator and forces NTLM regardless of what is available.
The Simple and Protected GSS-API Negotiation Mechanism. When two parties want to authenticate but do not know which security mechanism they share, SPNEGO offers a list and picks the best one both support. On Windows the SSPI provider is called Negotiate, and it has historically chosen Kerberos when possible and NTLM otherwise [10, 13]. The "otherwise" path is where every modern NTLM attack lives.
Each fallback case is one shutter through which NTLM continues to leak into a Kerberos-by-default world. The demotion was supposed to be terminal. Why did the four fallback cases turn out to cover most of the real-world authentication surface, and what does that look like on the wire?
3. The Wire: Three Messages and One Hash
Most defenders have never read an NTLM authentication off the wire. The cryptography is short enough to fit on one screen, and the structural property that drives the next 28 years of attacks is visible inside those three messages. The point of this section is to make that property impossible to miss.
NEGOTIATE, CHALLENGE, AUTHENTICATE
The client opens with NEGOTIATE, advertising its capability flags: which signing modes it supports, whether it is willing to do session security, whether it is asking for extended session keys, and so on. The server replies with CHALLENGE. The body of CHALLENGE contains a single 64-bit nonce (the server challenge) and a TLV blob called TargetInfo: a list of attribute-value pairs the server wants to bind into the authentication [11].
The client computes its response and sends AUTHENTICATE. That message contains the user name, the workstation name, the response itself, the AV_PAIRS the client wants to echo back, a Message Integrity Code field (HMAC-MD5 of the concatenation of all three NTLM messages), and -- in EPA-enforced deployments -- a hash of the TLS endpoint certificate placed in the MsvAvChannelBindings AV_PAIR [11, 15].
Diagram source
sequenceDiagram
autonumber
participant C as Client
participant S as Server
C->>S: NEGOTIATE (capability flags)
S->>C: CHALLENGE (server nonce 8B, TargetInfo AV_PAIRS)
Note over C: NTOWFv2 = HMAC_MD5(NT-hash, UNICODE(Upper(user) plus domain))
Note over C: NTProofStr = HMAC_MD5(NTOWFv2, ServerChallenge plus temp) where temp = version plus Z(6) plus Time plus ClientChallenge plus Z(4) plus ServerName plus Z(4)
C->>S: AUTHENTICATE (user, NTProofStr, temp, MIC, CBT)
Note over S: Server replays the same HMAC_MD5 with its copy of the NT-hash to verify The NTLMv2 response, verbatim
[MS-NLMP] §3.3.2 gives the response algorithm in three lines of pseudocode [11]:
The temp byte string carries two version bytes, six zero bytes, the 8-byte FILETIME, the 8-byte client challenge, four zero bytes, the AV_PAIR list the spec calls ServerName, and a final four zero bytes. The client sends NTProofStr || temp as the response. The server, which holds its own copy of NT-hash for the user (cached or fetched from the domain controller), recomputes the same three lines and checks equality. That is the entire response protocol.
Notice what NTOWFv2 is. It is a function of two inputs: the NT-hash, and a normalised user/domain string. Both inputs are static once the user logs in. Knowing the NT-hash is sufficient to compute every NTLMv2 response forever, against every server, for every challenge, until the password changes [16, 10].
AV_PAIRS, MIC, and channel binding -- retrofits all the way down
AV_PAIRS is a TLV structure. The server places target NetBIOS, target DNS, a timestamp, and various flags into the TargetInfo of CHALLENGE. The client echoes the structure into AUTHENTICATE and adds two retrofit fields when both ends agree to use them [11]:
MsvAvFlagsis a bit field signalling that the client has computed a MIC and is therefore willing to bind all three NTLM messages together.MsvAvChannelBindingsholds a hash of the server's TLS endpoint certificate when the authentication is happening over an HTTPS-style transport that the client can see. This is the Extended Protection for Authentication (EPA) channel-binding-token mechanism [15].
The MIC field itself is added to AUTHENTICATE. It is HMAC_MD5(ExportedSessionKey, NEGOTIATE || CHALLENGE || AUTHENTICATE). ExportedSessionKey coincides with SessionBaseKey in the common case; when NTLMSSP_NEGOTIATE_KEY_EXCH is set, the client generates a random session key, encrypts it under KeyExchangeKey, and ExportedSessionKey is the random key. The MIC always uses ExportedSessionKey, and it is intended to make tampering with any of the three messages detectable [11].
A length-prefixed TLV list carried inside the TargetInfo byte string of NTLM CHALLENGE and the AV-list byte string of AUTHENTICATE. AV_PAIRS hold the target server names, a timestamp, the MsvAvFlags, the MsvAvChannelBindings (EPA), and the optional MsvAvTargetName (SPN). NTLMv2 reserved AV_PAIRS in 1998 but most of the fields are 2009-2019-era retrofits onto the original wire format [11].
A 16-byte HMAC-MD5, keyed by ExportedSessionKey, computed over the concatenation of the NTLM NEGOTIATE, CHALLENGE, and AUTHENTICATE messages and embedded in AUTHENTICATE. (ExportedSessionKey equals SessionBaseKey unless NTLMSSP_NEGOTIATE_KEY_EXCH is negotiated; the MIC always uses the exported key.) Introduced as a retrofit so that a man-in-the-middle relay could not silently strip the signing-required flags from the negotiate phase. Drop-the-MIC (CVE-2019-1040) demonstrated that the presence of the MIC was itself a negotiated property and could be stripped [11, 19].
A hash of the server's TLS endpoint certificate placed in MsvAvChannelBindings so the authentication is bound to the specific TLS channel the client believed it was talking over. When both ends enforce CBT, an attacker who terminates one TLS channel and opens a different TLS channel to the real server cannot reuse the captured NTLM response. Microsoft documents three enforcement modes: None, Partial, and Full [15].
Run it
The whole thing fits in a few dozen lines of JavaScript. The point of the runnable demo is not to teach you to crack hashes; it is to make the password-equivalence claim land as code rather than as an assertion.
// Demonstrates the [MS-NLMP] NTLMv2 response algorithm.
//
// The point: NTProofStr is a deterministic function of the NT-hash plus
// values that travel in the clear or that the attacker controls. If you
// possess the NT-hash, you can compute NTProofStr for any (challenge,
// client_challenge, timestamp, av_pairs). That is the protocol-level
// proof of password-equivalence.
//
// In a real client, NT-hash = MD4(UTF-16LE(password)). MD4 is removed from
// most modern browser/Node crypto providers, so we use a precomputed
// NT-hash for password "Summer2026!" and focus on the structural property
// that matters: knowledge of those 16 bytes is sufficient forever.
const crypto = require("crypto");
// Precomputed NT-hash for password "Summer2026!" (16 bytes, hex):
// reference value verified against impacket's NTOWFv1() helper offline.
const ntHash = Buffer.from("41aed72cec76816423703d8e545eea31", "hex");
const user = "alice", domain = "CONTOSO";
// NTOWFv2 = HMAC-MD5(NT-hash, UNICODE(Upper(user) || domain))
const userDomain = Buffer.from((user.toUpperCase() + domain), "utf16le");
const ntowfv2 = crypto.createHmac("md5", ntHash).update(userDomain).digest();
// NTProofStr = HMAC-MD5(NTOWFv2, ServerChallenge || temp)
// where temp = ResponserVersion(0x01) || HiResponserVersion(0x01) || Z(6) ||
// Time(8) || ClientChallenge(8) || Z(4) || ServerName || Z(4)
const serverChal = Buffer.from("0123456789abcdef", "hex");
const clientChal = Buffer.from("fedcba9876543210", "hex");
const ts = Buffer.alloc(8); // any 8-byte FILETIME
const serverName = Buffer.from("00000000", "hex"); // empty AV_PAIR list
const tempBuf = Buffer.concat([
Buffer.from("01010000000000000000", "hex"), // version 1.1 || Z(6)
ts, clientChal,
Buffer.from("00000000", "hex"), // Z(4)
serverName,
Buffer.from("00000000", "hex"), // Z(4)
]);
const ntProofStr = crypto.createHmac("md5", ntowfv2)
.update(Buffer.concat([serverChal, tempBuf])).digest();
console.log("NT-hash :", ntHash.toString("hex"));
console.log("NTOWFv2 :", ntowfv2.toString("hex"));
console.log("NTProofStr :", ntProofStr.toString("hex"));
console.log("");
console.log("Now change serverChal/clientChal/ts and rerun: NTProofStr changes,");
console.log("but only the *first* line of input (the NT-hash) is a secret. The");
console.log("rest travels in the clear inside the three NTLM messages. Possessing");
console.log("ntHash IS possessing the credential -- forever, on every server."); Press Run to execute.
The demo prints three lines, then a punchline. The lines are not impressive; the punchline is.
The NT-hash is not a credential; it is the credential. Knowing the hash IS authentication. Every pass-the-hash tool ever written, from Paul Ashton's modified Samba in 1997 to the present, is a different packaging of the same realisation: an authentication that is a deterministic function of a static secret turns possession of that secret into permanent authority [16].
If possession of the hash is the protocol, the last 28 years of attacks are not surprises -- they are obvious next steps. What are those steps?
4. The Three-Decade Attack Cascade
Five generations of attacks. Each one is named, each one is dated, each one took Microsoft years to respond to, and each Microsoft response always closed the primitive and left the class alive. They are not five surprises; they are five logical consequences of the wire protocol you just read.
Generation 1 -- 1997: Pass-the-Hash (Paul Ashton)
The first published exploit of password-equivalence comes from Paul Ashton, posted to the Bugtraq mailing list in 1997. Ashton ships a patch against the Samba SMB client that takes a 16-byte NT-hash directly on the command line, instead of asking for a cleartext password [16]. The patch is a one-paragraph change against an open-source codebase, and that fact -- the brevity of the change -- is the lesson.
The NTLM response function has no input that depends on knowing the plaintext password. Replacing the plaintext-password input with a literal NT-hash input does not change the bytes that go on the wire. The server cannot tell the difference.
Microsoft's response, for more than a decade, is do not lose your hashes. There is no protocol fix because there is no protocol bug to fix; the design is doing exactly what it was designed to do. The response is operational guidance: tier your admins, scrub LSASS, do not run privileged sessions on workstations.
Generation 2 -- 2001: NTLM Relay (Sir Dystic / SMBRelay)
If you do not have to steal the hash to use the credential, you also do not have to steal the live exchange. You can simply relay it. On March 31, 2001, at the @lanta.con conference, Sir Dystic of the Cult of the Dead Cow (Josh Buchbinder) releases SMBRelay: a small program that accepts an SMB connection on port 139, opens a second SMB connection back to another server, and shuttles the NEGOTIATE / CHALLENGE / AUTHENTICATE messages between the two sides [20, 21].
The attack works because the three NTLM messages are not bound to a particular client, server, or service. Whoever sits between them can replay the credential against whatever destination the attacker chooses, as that user, for the duration of the exchange.
The colourful provenance matters. The Cult of the Dead Cow released SMBRelay alongside Back Orifice 2000; "Sir Dystic" is the same Josh Buchbinder who later wrote the SMBProxy authentication-relay framework. The point is not the chrome -- it is that the relay class was disclosed publicly at a conference in 2001, with working code on the cDc website, and Microsoft did not ship a fix for the trivial case (self-relay) until November 2008 [20, 21].Microsoft's response is incomplete and slow. SMB signing exists from Windows 2000 onward, but it is off by default on member servers for more than a decade [22]. MS08-068, in November 2008, finally patches the self-relay case (CVE-2008-4037): the SMB server now refuses to accept an authentication that the client itself just generated against the same server [23, 24]. NVD's record for CVE-2008-4037 explicitly calls the original fix "insufficient for CVE-2000-0834" -- meaning the patch closed exactly the self-relay case and nothing else [24]. Seven years to fix the simplest variant; the cross-server relay class is still wide open.
Generation 3 -- 2008-2014: Credential Theft as a Service
By 2008, the operational guidance "do not lose your hashes" stops being defensible. On February 29, 2008, Hernan Ochoa releases the Pass-the-Hash Toolkit v1.3, two native Windows binaries called iam.exe and whosthere.exe that read the NT-hash out of LSASS memory and inject it into a new logon session [25, 26]. PtH stops being a Linux-and-Samba trick and becomes a Windows-everywhere reality.
Three years later, Benjamin Delpy publishes Mimikatz. The first version is closed-source, released in May 2011 [27, 28]. By April 6, 2014, the GitHub repository goes public with the version string "mimikatz 2.0 alpha (x86) release 'Kiwi en C' (Apr 6 2014 22:02:03)" [29]. The repo description is a near-perfect summary of what LSASS is to an attacker: "extract plaintexts passwords, hash, PIN code and kerberos tickets from memory. mimikatz can also perform pass-the-hash, pass-the-ticket or build Golden tickets" [29]. LSASS becomes the universal credential oracle.
Delpy did not intend Mimikatz to be a weapon. Wired's Andy Greenberg documents the trajectory in detail: Delpy "released it publicly in May 2011, but as a closed source program," and "in mid-2011, he learned for the first time... that Mimikatz had been used in an intru" -- the DigiNotar breach. Police raided his Moscow conference hotel room. He went open-source partly because closed-source was no longer protecting anyone and partly to make the security industry confront what was in LSASS [27].Microsoft's response is structural and specific. Credential Guard ships in Windows 10 RTM (Enterprise and Education editions), July 29, 2015 [30]. It uses Virtualization-Based Security to isolate lsaiso.exe in a separate VTL1 partition; the kernel can no longer read NTLM hashes or Kerberos TGTs even at SYSTEM-level privilege. Protected Users and Restricted Admin in Server 2012 R2 / Windows 8.1 narrow the surface further. LSASS-as-PPL adds a process-protection layer between user-mode debuggers and the LSASS address space [30].
Credential Guard works -- against the credential-theft class. It does nothing against credential-use. An attacker who never extracts a hash, because they never need to, sails right past it. Relay does not need the hash. Coercion does not need the hash. ESC8 does not need the hash. That is the next generation.
Generation 4 -- 2018-2021: Forced-Authentication Coercion
In 2018 at DerbyCon 8, Lee Christensen releases SpoolSample, known publicly as "PrinterBug." The GitHub description is exact: "PoC tool to coerce Windows hosts authenticate to other machines via the MS-RPRN RPC interface" [31]. The trick is that the Print Spooler service runs as SYSTEM, accepts a remote RPC call (RpcRemoteFindFirstPrinterChangeNotificationEx) that takes a UNC path, and dutifully NTLM-authenticates back to whatever path the caller named -- on behalf of the machine account. Any Windows service running as SYSTEM that accepts a UNC path is a confused deputy that will authenticate on demand.
Marina Simakov and Yaron Zinar of Preempt (now CrowdStrike) publish "Drop the MIC" on June 11, 2019. The vulnerability is CVE-2019-1040: a tampering bug where "a man-in-the-middle attacker is able to successfully bypass the NTLM MIC (Message Integrity Check) protection" [32, 19]. The bypass works by stripping the NTLMSSP_NEGOTIATE_SIGN and NTLMSSP_NEGOTIATE_ALWAYS_SIGN flags from the initial NEGOTIATE, removing the MIC field from AUTHENTICATE, and removing the Version field that drives MIC detection.
Servers that should have required a MIC silently accept the modified message. The MIC -- the retrofit integrity layer that was supposed to make tampering detectable -- turns out to be itself untethered to the negotiation [32].
Lionel Gilles (topotam77) publishes PetitPotam in July 2021, CVE-2021-36942. The GitHub repository description reads: "PoC tool to coerce Windows hosts to authenticate to other machines via MS-EFSRPC EfsRpcOpenFileRaw or other functions" [4, 5]. The decisive new property compared to SpoolSample is that PetitPotam needs no credentials against a domain controller: LSARPC accepts unauthenticated binds, so the coercion can be triggered by an attacker who has merely joined the network.
In 2022, Remi Gascou (p0dalirius) publishes Coercer, a Python script that consolidates the coercion class across MS-RPRN, MS-EFSR, MS-DFSNM, MS-FSRVP, and many more RPC interfaces. The README describes it succinctly: "A python script to automatically coerce a Windows server to authenticate on an arbitrary machine through many methods" [1].
Generation 5 -- 2021: ADCS Web-Enrollment Relay (ESC8)
On June 17, 2021, Will Schroeder and Lee Christensen of SpecterOps publish "Certified Pre-Owned," a whitepaper and matching blog post that maps eight new attack classes against Active Directory Certificate Services [2, 3]. ESC1 through ESC7 are template and configuration weaknesses. ESC8 is the keystone of this article.
ESC8 says: AD CS Web Enrollment endpoints (/certsrv/) accept NTLM authentication. Coerce a server's machine account to authenticate to your relay listener; relay the authentication to /certsrv/; enroll the relayed identity for a machine-template certificate; use that certificate to perform PKINIT against the KDC and request a TGT [2]. The NTLM-vs-Kerberos boundary stops being a meaningful one. NTLM is the protocol on the front side of the attack; Kerberos is the trust token on the back side; the certificate is the conduit between them.
The point of ESC8 is not just that it works. The point is that it works against a perfectly retrofitted environment. SMB signing did not enter the chain. LDAP signing did not enter the chain. EPA was supposed to enter the chain on the /certsrv/ side but was unevenly deployed. Credential Guard never had a hash to protect.
Diagram source
flowchart TD
A[Gen 1 -- 1997 Pass-the-Hash
Paul Ashton, modified Samba]
A --> A1[Response: operational guidance
Do not lose your hashes]
A1 --> B[Gen 2 -- 2001 SMBRelay
Sir Dystic, atlanta.con]
B --> B1[Response: MS08-068 2008
Patches self-relay only]
B1 --> C[Gen 3 -- 2008-2014 LSASS extraction
Ochoa PtH Toolkit, Delpy Mimikatz]
C --> C1[Response: Credential Guard 2015
Closes theft; not use]
C1 --> D[Gen 4 -- 2018-2021 Coercion
SpoolSample, Drop-the-MIC, PetitPotam, Coercer]
D --> D1[Response: KB 5005413, EPA
Closes primitive; not class]
D1 --> E[Gen 5 -- 2021 ESC8
Schroeder/Christensen Certified Pre-Owned]
E --> E1[Response: remove NTLM] Diagram source
sequenceDiagram
autonumber
actor A as Attacker
participant V as "Victim SYSTEM service (Spooler, EFSR, DFSNM)"
participant R as Attacker NTLM relay
participant T as "Target service (LDAP, SMB, certsrv)"
A->>V: RPC call with UNC path \attacker\share
V->>R: NTLM NEGOTIATE (as machine account)
R->>T: Open new authenticated session
T->>R: NTLM CHALLENGE
R->>V: Forward CHALLENGE
V->>R: NTLM AUTHENTICATE (signed by machine account)
R->>T: Forward AUTHENTICATE -- T treats attacker session as the victim | Generation | Primitive | Public date | Microsoft response | What survived |
|---|---|---|---|---|
| 1. Pass-the-Hash | Use the hash directly | 1997, Paul Ashton, Bugtraq [16] | Operational guidance | Hash is still password-equivalent on the wire |
| 2. NTLM relay (SMB) | Forward live exchange | March 31, 2001, Sir Dystic, @lanta.con [20] | MS08-068 (Nov 2008) -- self-relay only [23, 24] | Cross-server, cross-protocol relay |
| 3. LSASS extraction | Steal hashes from memory | Feb 2008 (Ochoa); May 2011 closed / Apr 2014 open (Delpy) [25, 29, 27] | Credential Guard (Jul 29, 2015) [30] | Hash use outside LSASS path; SYSTEM-level Mimikatz on the SAM |
| 4. Coercion | Make SYSTEM authenticate on demand | 2018 SpoolSample [31]; 2019 Drop-the-MIC [32, 19]; 2021 PetitPotam [4, 5]; 2022 Coercer [1] | Per-interface patches; KB 5005413 EPA recipe [7] | The pattern of "SYSTEM holds an unanchored credential" |
| 5. ESC8 ADCS Web Enrollment relay | NTLM coerce -> /certsrv/ -> TGT via PKINIT | June 17, 2021, Schroeder/Christensen, "Certified Pre-Owned" [2, 3] | KB 5005413; AD CS hardening; eventually Phase 3 of NTLM removal | Kerberos relay class on the other side (KrbRelay/KrbRelayUp) [33] |
"KrbRelayUp -- a universal no-fix local privilege escalation in windows domain environments where LDAP signing is not enforced (the default settings)." -- Dec0ne, KrbRelayUp README [33]
The reader who started Section 4 believing "if I patch each named NTLM attack, the protocol is safe" finishes Section 4 believing something else. Every retrofit patches a primitive; none addresses the existence of the fallback path. The next attack is always one cross-protocol step away. The retrofit strategy is structurally incapable of closing the class.
By the end of 2021, NTLM-the-protocol cannot be removed because four use cases require it, and NTLM-the-fallback cannot be kept because ESC8 turned it into a domain-takeover oracle. Something has to change. What?
5. The Retrofit Strategy and Its Funeral
Before naming the answer, name the strategy that failed. Microsoft's defensive cadence between 2001 and 2021 splits into three families, each effective against a named primitive, each defeated by an unanchored cousin of that primitive.
Family A -- Per-protocol message authentication
SMB signing. LDAP signing and sealing. The idea is to anchor the content of each authenticated request inside a per-session signature derived from the authentication. SMB signing introduces an HMAC over every SMB message keyed by a per-session SigningKey; LDAP signing and sealing do the equivalent for LDAP operations [22].
Family A works when the target protocol enforces it. SMB-to-SMB relay against an SMB server with required signing fails; LDAP-to-LDAP relay against an LDAP server with required signing fails. The strategy assumes the attacker stays in the same protocol family. Cross-protocol relay -- SMB authentication relayed to LDAP, or SMB authentication relayed to /certsrv/ -- defeats it. The MS-EFSR coercion can produce an authentication that originates "as if from SMB" and gets accepted by an unrelated HTTPS service that ignores the SMB signing flag entirely [19, 2].
Family B -- Per-channel binding tokens and the MIC
EPA (channel binding) and the NTLMv2 MIC are the response to cross-protocol relay. Both try to tie the authentication to the specific channel the client believes it is using. EPA places a hash of the TLS endpoint certificate into the MsvAvChannelBindings AV_PAIR; an HTTPS server with EPA required compares it to its own certificate's hash and rejects the authentication if they do not match [15]. The MIC binds all three NTLM messages together so a relay cannot strip the signing-required flags from NEGOTIATE after the client sets them [11].
Family B works when both ends agree to enforce. Drop-the-MIC (CVE-2019-1040) demonstrated that the presence of the MIC was negotiated and could be stripped, so a server that supported MIC-less clients silently accepted MIC-less messages from a relay [32, 19]. EPA suffers from the same enforcement-asymmetry: when an IIS endpoint runs with policyEnforcement="None" or "Partial", the binding is not checked. KB 5005413 published the explicit <extendedProtectionPolicy policyEnforcement="Always" /> recipe for /certsrv/ because field deployments had been running with weaker settings [7].
Family C -- Credential isolation
Credential Guard. LSASS-as-PPL. Protected Users. Restricted Admin. These attack the theft surface. Credential Guard moves the NT-hash into lsaiso.exe inside VTL1; the kernel can no longer read it. Microsoft now ships it enabled by default on Windows 11 22H2 and Server 2025 on hardware that meets the requirements [30].
Family C is honest about what it covers. It does nothing about coercion flows that never touch the NT-hash. PetitPotam and ESC8 do not need a hash; the relay session uses the live NTLM exchange and is never persisted. Credential Guard cannot help.
| Family | What it closes | What it does not close | Defeating attack |
|---|---|---|---|
| A. Per-protocol message auth (SMB/LDAP signing) | Same-protocol relay against the target | Cross-protocol relay; targets that do not enforce | LDAP relay from SMB coercion [19]; ESC8 relay to /certsrv/ |
| B. Channel binding (EPA) + MIC | Same-channel relay through TLS termination | MIC stripping in negotiation; EPA at None/Partial; non-TLS targets | Drop-the-MIC [19]; under-enforced EPA [7] |
| C. Credential isolation (Credential Guard, LSASS-PPL) | Hash theft from running LSASS | Hash use in live relay; SAM extraction from disk; coercion | ESC8 + PetitPotam [4, 2]; SAM hive offline [30] |
Every retrofit Microsoft has shipped against NTLM attacks one primitive of NTLM. None address the existence of NTLM as a fallback path. ESC8 was the funeral of the retrofit strategy because ESC8 turned a fully retrofitted environment into a domain takeover without defeating any retrofit.
To remove ESC8 without rebuilding AD CS, Microsoft has to remove NTLM. To remove NTLM, Microsoft has to remove the four reasons NTLM existed as a fallback in the first place. What does that look like in shippable form?
6. The Breakthrough: Closing the Fallback
October 11, 2023. Matthew Palko, Windows IT Pro Blog. "The evolution of Windows authentication." For the first time in twenty-three years, Microsoft publicly commits to removing NTLM, not restricting it, and names the three load-bearing features that make removal possible [14].
The plan starts where every honest plan starts -- by stating the problem in its own words. There are four fallback reasons NTLM persisted: no DC line-of-sight, no domain at all (local accounts), no SPN for the target, and hard-coded NTLM in application code [14]. Each gets an engineered answer. The four-to-three correspondence (three protocols plus one refactor) is the new architecture.
"Our end goal is eliminating the need to use NTLM at all to help improve the security bar of authentication for all Windows users." -- Matthew Palko, Microsoft Windows IT Pro Blog, October 11, 2023 [14]
IAKerb -- closing "no DC line-of-sight"
IAKerb stands for Initial and Pass Through Authentication Using Kerberos V5 and the GSS-API. The IETF draft has a four-author list -- Benjamin Kaduk, Jim Schaad, Larry Zhu, and Jeffrey E. Altman -- and a quiet history [34].
The premise is simple. A client wants to authenticate to an application server with Kerberos but cannot reach a KDC -- maybe the client is behind a firewall, maybe the KDC is only reachable from the server's side of a VPN. IAKerb wraps the Kerberos AS-REQ and TGS-REQ messages inside GSS-API tokens and asks the application server to proxy them to a KDC that the server can reach. The client never opens a direct TCP/UDP connection to a KDC; the application server acts as the carrier.
Initial and Pass Through Authentication Using Kerberos V5 and the GSS-API. A GSS-API-wrapped Kerberos exchange in which the client cannot reach a KDC directly and the application server proxies AS-REQ / TGS-REQ on the client's behalf. Defined by draft-ietf-kitten-iakerb (IETF kitten WG, currently a Dead WG Document). MIT Kerberos has shipped IAKerb since 1.9 (2010); Apple ships GSS_IAKERB_MECHANISM since macOS 10.14. Microsoft is implementing IAKerb in Windows 11 / Server 2025 [34, 14, 35].
Local KDC -- closing "no domain at all"
Local accounts in the machine SAM have never had a KDC. Workgroup machines have no domain at all. Both cases force NTLM today. The fix is conceptually trivial: run a tiny Kerberos KDC against the local SAM, exposed only through IAKerb-wrapped exchanges so the wire protocol is the same as the trust-traversing case [14, 35].
This is the late-adopter move that surprises Linux-side practitioners. MIT Kerberos has had IAKerb since 1.9 (released in 2010). Samba has been working on a localkdc for years. At FOSDEM 2025 (February 2, 2025), Alexander Bokovoy and Andreas Schneider gave a talk explicitly framed as "localkdc -- a general local authentication hub" [36, 37]. Schneider's companion blog post the next week summarised the work: a parallel local-authentication hub for Linux that interoperates with the IAKerb wire format Windows is now adopting [37].
A small Kerberos Key Distribution Center process that runs against a machine's local user database (the SAM on Windows; a file or sssd on Linux) and is exposed only through IAKerb. It lets local-account authentications use Kerberos under the same Negotiate / NEGOEX wire envelope used by domain authentications -- removing one of the four reasons NTLM persisted. Shipping in Windows 11 / Server 2025 [14, 35]; parallel Linux/Samba work coordinated under the FOSDEM 2025 localkdc umbrella [36, 37].
NEGOEX -- carrying IAKerb under the existing Negotiate API
You do not want to teach every application a new SSPI provider. Existing code calls AcquireCredentialsHandle("Negotiate", ...); that should keep working, and IAKerb should be one of the mechanisms Negotiate is willing to pick. The piece of plumbing that makes this possible is NEGOEX: SPNEGO Extended Negotiation [38, 39].
NEGOEX adds a pair of meta-data messages on top of the standard SPNEGO NegTokenInit / NegTokenResp exchange, so that mechanisms (like IAKerb) that need a richer negotiation can ride inside the Negotiate envelope. The Microsoft Open Specification [MS-NEGOEX] is currently at revision 4.0 (April 23, 2024), with the original revision dated July 9, 2020 [38]. The expired Microsoft IETF draft draft-zhu-negoex from January 2011 is the historical anchor; four Microsoft authors -- Michiko Short, Larry Zhu, Kevin Damour, and Dave McPherson -- are listed verbatim in the draft metadata [39].
A correction is owed here. Scope notes inherited from earlier in this project cited "RFC 8143" as the NEGOEX standard. RFC 8143 is actually titled "Using Transport Layer Security (TLS) with Network News Transfer Protocol (NNTP)" and updates RFC 4642; it has nothing to do with NEGOEX [40]. The correct primary references for NEGOEX are [MS-NEGOEX] and draft-zhu-negoex, both used consistently throughout this article [38, 39].
The SPNEGO Extended Negotiation security mechanism. Adds a meta-data exchange inside the SPNEGO envelope so that richer mechanisms (like IAKerb) can be negotiated without changing the SSPI surface. Primary sources: Microsoft Open Specification [MS-NEGOEX] revision 4.0 (April 2024); expired IETF draft draft-zhu-negoex (January 2011). Despite a common scope-doc error, RFC 8143 is not NEGOEX; RFC 8143 is "Using TLS with NNTP" [38, 39, 40].
Negotiate-everywhere refactor -- closing "hard-coded NTLM"
The last fallback case is the most prosaic: application code that calls AcquireCredentialsHandleW(..., "Ntlm", ...) or RPC code that asks for RPC_C_AUTHN_WINNT. Both bypass Negotiate and force NTLM no matter what is on the wire. The fix is editorial -- audit Windows internals, replace each hard-coded Ntlm call with Negotiate -- and very large in surface area. Dan Cuomo's "Active Directory improvements in Windows Server 2025" post summarises the Windows Server Summit 2024 session in one sentence: "we have created completely new Kerberos features to minimize use of NTLM in your environments. This session explains and demonstrates IAKerb, Local KDC, IP SPN, and the roadmap to the end of NTLM" [35].
| Fallback reason | Closure mechanism | Primary source | Ship target |
|---|---|---|---|
| No DC line-of-sight | IAKerb (GSS-wrapped Kerberos through the app server) | draft-ietf-kitten-iakerb (Dead WG, revived by Microsoft) [34] | Windows 11 / Server 2025 [14, 35] |
| No domain at all (local accounts) | Local KDC over IAKerb | Palko 2023; Samba localkdc parallel [14, 36] | Windows 11 / Server 2025 |
| No SPN | IP-SPN policy under Negotiate | [MS-NEGOEX]; Cuomo 2024 session [38, 35] | Windows Server 2025 |
| Hard-coded NTLM | Audit + replace AcquireCredentialsHandle("Ntlm") with Negotiate | Palko 2023 [14] | Editorial, ongoing through Phase 2 |
Diagram source
flowchart LR
R1[No DC line-of-sight] --> M1[IAKerb
draft-ietf-kitten-iakerb]
R2[No domain at all
local accounts] --> M2[Local KDC
over IAKerb]
R3[No SPN for target] --> M3[IP-SPN policy
under Negotiate]
R4[Hard-coded NTLM
in app code] --> M4[Negotiate-everywhere
refactor]
M1 --> N[NEGOEX
SPNEGO extension]
M2 --> N
M3 --> N
N --> P[Negotiate SSPI
same call sites] Diagram source
sequenceDiagram
autonumber
participant C as Client (no KDC reach)
participant S as Application server (KDC reach)
participant K as KDC
C->>S: SPNEGO NegTokenInit with NEGOEX MetaData, mechs=[Kerberos, IAKerb]
S-->>C: NegTokenResp, server picks IAKerb
C->>S: IAKerb token wrapping AS-REQ
S->>K: AS-REQ
K-->>S: AS-REP
S-->>C: IAKerb token wrapping AS-REP -> client now has TGT
C->>S: IAKerb token wrapping TGS-REQ for service ticket
S->>K: TGS-REQ
K-->>S: TGS-REP (service ticket)
S-->>C: IAKerb token wrapping TGS-REP
Note over C,S: From now on, ordinary AP-REQ / AP-REP over Kerberos -- no NTLM needed krb5 library shipped IAKerb in 1.9 (released December 2010) -- well before Microsoft. Apple's Heimdal-derived GSS framework has shipped GSS_IAKERB_MECHANISM since macOS 10.14 (Mojave, 2018). The cross-platform interoperability story is therefore better in 2026 than it has been in years: a Linux client using MIT 1.9+ or an Apple client using macOS 10.14+ can already speak IAKerb to a Windows Server 2025 Local KDC. The parallel Samba localkdc effort closes the symmetric case: a Linux machine acting as the IAKerb server [36, 37].
The reader who started Section 6 believing "NTLM is too entrenched to remove" finishes Section 6 believing something else. The entrenchment is exactly four named cases, and each one has been given an engineered answer. Removal is now a sequencing problem, not an architecture problem.
The engineering existed by October 2023. The shipping commitment came in January 2026. What is Microsoft actually shipping, and on what schedule?
7. The Three-Phase Roadmap
January 29, 2026. The Windows IT Pro Blog publishes "Advancing Windows security: Disabling NTLM by default" under the byline mariam_gewida [41]. The post documents Microsoft's published roadmap and opens with a caveat that the rest of this article works hard not to forget.
The plan has three phases. They are sequenced; each phase produces the inputs the next phase needs.
Phase 1 (now) -- Audit
Phase 1 is auditing. The deliverable is enhanced NTLM logging in Windows 11 24H2 and Windows Server 2025, documented in KB 5064479 (published July 11, 2025) [42]. The new logging surface is Applications and Services Logs > Microsoft > Windows > NTLM > Operational, gated by two GPOs called "NTLM Enhanced Logging" and "Log Enhanced Domain-wide NTLM Logs." For each NTLM authentication, the event tells the administrator three things: who called (the process), why (the negotiated SSPI provider chose NTLM), and where (the target service). The KB also names per-event warning classes for NTLMv1, MIC-less, and EPA-not-supported authentications [42].
Phase 1 also closes the oldest residual: NTLMv1. Microsoft's deprecation page added an NTLM entry in June 2024 with verbatim language: "All versions of NTLM, including LANMAN, NTLMv1, and NTLMv2, are no longer under active feature development and are deprecated. Use of NTLM will continue to work in the next release of Windows Server and the next annual release of Windows. Calls to NTLM should be replaced by calls to Negotiate" [43].
The same row adds: "NTLMv1 is removed starting in Windows 11, version 24H2 and Windows Server 2025" -- the November 2024 update note [43, 44]. The KB 4090105 pre-24H2 NTLMv1 auditing surface (Event ID 4624 with Package Name (NTLM only): NTLM V1) remains valid for legacy environments [45].
Phase 2 (H2 2026) -- IAKerb + Local KDC + Negotiate-first refactor in pre-release
Phase 2 puts the engineered closures from Section 6 into pre-release. IAKerb and Local KDC ship for Windows Insiders and Server preview channels. The Negotiate-first refactor lands -- Microsoft's own subsystems audit their AcquireCredentialsHandleW("Ntlm", ...) and RPC_C_AUTHN_WINNT call sites and replace them with Negotiate calls. Per-machine policy controls for NTLM scope make finer-grained restriction possible. IP-SPN policy lands so the "no SPN" case can be closed without naming every server by FQDN [41, 35].
The Microsoft outreach mechanism for Phase 2 is the ntlm@microsoft.com mailbox; the January 2026 post names it explicitly as the channel for surfacing cross-forest, federated, and ISV-edge cases that need engineering help before Phase 3 [41].
Phase 3 (next major Windows / Windows Server release) -- Disabled by default
Phase 3 is the default-off flip. Network NTLM authentication is disabled by default in the next major Windows and Windows Server release. The disablement is a configuration, not a binary removal: NTLM remains in the OS, callable through Negotiate only when a policy explicitly re-enables it for a named scope [41]. The Hacker News' summary of the roadmap published February 2026 documents the same three-phase structure for industry-press consumption [46].
Diagram source
flowchart LR
P1[Phase 1 -- NOW
KB 5064479 enhanced auditing
NTLMv1 removed in 24H2 / WS2025] --> P2
P2[Phase 2 -- H2 2026
IAKerb + Local KDC pre-release
Negotiate-first refactor
Per-machine NTLM scope policy] --> P3
P3[Phase 3 -- next major Windows
Network NTLM disabled by default
Re-enablement requires explicit policy] | Phase | Deliverable | Date / target | Prerequisite | Primary |
|---|---|---|---|---|
| Phase 1 | Enhanced NTLM auditing | KB 5064479, July 11, 2025 | Windows 11 24H2 / Server 2025 | [42] |
| Phase 1 | NTLMv1 removal | Windows 11 24H2 / Server 2025, November 2024 | NTLM family deprecation (June 2024) | [43, 44] |
| Phase 2 | IAKerb + Local KDC pre-release | H2 2026, Windows Insider channel | Phase 1 audit data identifies callers | [41, 35] |
| Phase 2 | Negotiate-first refactor of Windows subsystems | H2 2026 | Phase 1 audit data | [14, 41] |
| Phase 2 | IP-SPN policy for "no SPN" case | Windows Server 2025 + flighting | NEGOEX in Negotiate | [35] |
| Phase 3 | Network NTLM disabled by default | Next major Windows / Server release | All Phase 2 features GA | [41] |
Phase 3 is the first default configuration in 30 years that does not include NTLM. It is not the first configuration in 30 years without authentication-relay attacks. Why not?
8. What Disabling NTLM Cannot Buy You
A blunt section. Phase 3 is real progress. It is not the end of authentication attacks on Windows. Three structural ceilings survive the transition; the article will not pretend otherwise.
Disabled is not removed
Phase 3 still ships NTLM in the OS. The default is off; the policy lockout is exactly as strong as the domain's tier-0 administrative segregation, not stronger. An attacker who reaches a domain controller with Group Policy edit rights can flip the policy and re-enable NTLM for the scope they want. The wording in the January 2026 post is precise: "during phase 3, NTLM will remain present in the OS and can be explicitly re-enabled via policy if you still need it" [41].
This is the design choice Microsoft has to make, because removing NTLM binaries entirely would brick every third-party application that hard-codes Ntlm and every legacy device that has not been firmware-updated since 2018. "Disabled by default with policy override" is the only configuration that has any chance of getting deployed.
Kerberos has its own relay class
The relay class does not depend on NTLM. KrbRelay, KrbRelayUp, RBCD abuse, unconstrained-delegation abuse, S4U2Self / S4U2Proxy chains -- the entire taxonomy survives the move to Kerberos with different named primitives. Dec0ne's KrbRelayUp README, quoted at the end of Section 4, calls the class a universal no-fix local privilege escalation; the rest of the README enumerates the LDAP-signing default and the RBCD primitive that drive the post-NTLM relay surface [33].
What changes is the protocol. What does not change is that an application server that receives an authenticated message without enforcing message integrity or channel binding can be coerced into accepting an attacker-relayed authentication. The named primitives change. The class survives.
Local SAM hashes remain password-equivalent
The Local KDC reads the SAM. An attacker with SYSTEM-level access to the same machine reads the SAM too. Once they have the hash in hand, they can either feed it to a Local KDC running on a machine they control, or they can attempt offline cracking. IAKerb does not change either of those facts; what it changes is whether the wire exposes the password-equivalent secret. Defence in depth -- TPM-backed key wrapping, Credential Guard for VBS isolation of process credentials, BitLocker for the cold-boot scenario -- remains necessary [30].
Phase 3 is a transition between tradeoffs, not a transition out of them. The exit from NTLM-the-protocol is not the exit from the authentication-relay class, or from the chip-layer credential class. The arc closes one specific 30-year-old attack surface and opens different conversations about the next.
If the structural classes survive, what practical problems remain that an administrator should worry about between today and Phase 3?
9. Open Problems and the 2026-2027 Edge
Five named problems sit between Phase 1 (now) and Phase 3 GA. Each one has a primary source and a "best partial result" available today.
-
ESC8 field deployment of EPA on
/certsrv/is uneven. Microsoft published KB 5005413 on July 30, 2021 with the dispositive recipe:<extendedProtectionPolicy policyEnforcement="Always" />on every/certsrv/virtual directory, plus disabling plain HTTP. Server 2025 hardening pushes EPA to required-by-default in many AD CS templates. Many environments are not on Server 2025 yet, and CISA's Known Exploited Vulnerabilities catalog still lists CVE-2021-36942 as actively exploited. CVE-2022-26925 ("Windows LSA Spoofing Vulnerability") is the LSARPC NTLM-relay variant that emerged after the initial PetitPotam patches; it is on the same KEV list [7, 5, 47]. -
Third-party and legacy-app hard-coded NTLM. Microsoft's Negotiate-everywhere refactor covers Microsoft's own code. Independent software vendors must do the same audit for theirs. Phase 1's enhanced auditing surface (KB 5064479) is the practical instrument for identifying the callers: every NTLM authentication carries the calling process name and a reason code [42]. The post-Phase-3 default-off configuration will surface these as outages on any environment that has not run the audit first.
-
Cross-forest and federated IAKerb edges. Single-forest IAKerb is well-defined. Multi-forest, federated, and partner-trust scenarios get implementation-defined quickly: NEGOEX has to carry IAKerb tokens through
Negotiateacross trust boundaries where the proxying server may not be in the same forest as the KDC. Microsoft'sntlm@microsoft.comoutreach mailbox exists precisely to surface these edge cases before Phase 3 [34, 41]. -
Linux and macOS parallel. MIT Kerberos has had IAKerb since 1.9 (2010). Apple ships
GSS_IAKERB_MECHANISMsince macOS 10.14. The Samba andlocalkdceffort from Bokovoy and Schneider (FOSDEM 2025) is the parallel open-source path: a Linux machine that can act as the IAKerb application server for a Windows client, or vice versa, under the sameNegotiateenvelope [36, 37]. The interoperability story should be better in 2026-2027 than it has been in twenty years. -
Policy pressure. EU NIS2 mandates cybersecurity risk-management measures for entities in critical sectors; the Cyber Resilience Act adds mandatory security requirements for products with digital elements. Both frameworks make legacy authentication a documented compliance concern [48, 49]. Deprecation of NTLM under Microsoft's own deprecation page (
ms-deprecated-features) gives a clean audit surface that did not exist before; an organisation can point to KB 5064479 audit data showing NTLM call sites with named callers and target services, and demonstrate progress on retirement [43].
All five problems converge to one question for the AD engineer reading this article: what should I do this quarter?
10. What an AD Engineer Should Do This Quarter
Six numbered actions, ordered by impact. No filler, no compliance boilerplate.
The Phase 1 audit is the load-bearing piece. Action 1 produces the data that makes Actions 2-6 prioritise correctly. The following snippet sketches the audit-event query logic an administrator would express in PowerShell -- the JavaScript runs the same logic so you can think through edge cases interactively.
// Sketch of the triage logic an administrator would run against
// "Applications and Services Logs > Microsoft > Windows > NTLM > Operational"
// after enabling the KB 5064479 enhanced auditing GPOs. The point of running
// this in JavaScript is to make the rules explicit so you can think through
// edge cases without standing up a Windows event channel.
const sampleEvents = [
{ process: "C:\\app\\legacy.exe", reason: "NoSPN", target: "ldap/dc01.example.local", count: 142 },
{ process: "C:\\Program Files\\Backup\\agent.exe", reason: "ExplicitNtlm", target: "cifs/backup02.example.local", count: 9 },
{ process: "C:\\Windows\\System32\\spoolsv.exe", reason: "NoDcReach", target: "cifs/attacker.example.local", count: 1 },
{ process: "C:\\Windows\\System32\\lsass.exe", reason: "LocalAccount", target: "host\\WORKGROUP-PC01", count: 38 },
{ process: "C:\\Windows\\System32\\svchost.exe", reason: "NoSPN", target: "host/aliased.example.local", count: 7 },
];
function triage(events) {
const out = [];
for (const e of events) {
let severity = "info";
let actions = [];
if (e.reason === "ExplicitNtlm") {
severity = "high";
actions.push("Fix caller: replace AcquireCredentialsHandle('Ntlm') with 'Negotiate'");
}
if (e.reason === "NoSPN") {
severity = "medium";
actions.push("Register an SPN for the target or enable IP-SPN policy");
}
if (e.reason === "LocalAccount") {
severity = "medium";
actions.push("Plan Local KDC enrollment in Phase 2 pilot");
}
if (/spoolsv\.exe$/i.test(e.process) && /attacker/i.test(e.target)) {
severity = "critical";
actions.push("Suspicious: Spooler authenticating to non-domain UNC. Likely coercion attempt -- isolate, then disable Spooler on this host");
}
out.push({ process: e.process, severity, actions });
}
return out;
}
for (const row of triage(sampleEvents)) {
console.log(`[${row.severity.toUpperCase()}] ${row.process}`);
for (const a of row.actions) console.log(" -> " + a);
} Press Run to execute.
One-line Windows Insider flighting flip for Phase 2 pilot
On a non-production Windows 11 Insider machine, the per-machine NTLM scope policy lives under HKLM\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0. Microsoft's pre-release documentation will name the value used to gate the Phase 2 IAKerb / Local KDC behaviours; consult the Windows Insider release notes that ship with the Phase 2 flight rather than hard-coding a value here -- the keys are subject to change up to GA. Use the ntlm@microsoft.com outreach channel for any environment-specific question [41].
This is the work. The Phase 3 deadline is the next major Windows release; the Phase 1 audit window is right now. If you wait, the cut-over surfaces breakage as outage. If you audit, the cut-over is uneventful.
11. Frequently Asked Questions
Frequently asked questions
Is NTLMv2 safe to keep using?
No. NTLMv2 is the version Drop-the-MIC, PetitPotam, and ESC8 all attack [19, 2]. The HMAC-MD5 response is strong against the response side, but the password-equivalence of the NT-hash and the lack of binding to the underlying transport are the structural properties every modern attack exploits. NTLMv2 is the least bad NTLM, not a safe NTLM.
Can I just disable NTLM today?
Phase 1 controls let you audit. Phase 2 features (IAKerb, Local KDC, IP-SPN, the Negotiate refactor) are what make disabling survivable for most organisations. If you go straight to RestrictNTLM:Deny without running the KB 5064479 audit first, you will outage legacy applications and possibly your help-desk laptops. The honest answer is: audit now, pilot Phase 2 in H2 2026, default-off at Phase 3 [41, 42].
Does Credential Guard fix this?
No. Credential Guard fixes credential theft from LSASS. It does nothing about credential use (relay), coercion (PetitPotam), or cross-protocol chains (ESC8). It is necessary -- ESC8 + Mimikatz is worse than ESC8 alone -- but it is not sufficient against the relay class [30].
Does removing NTLM eliminate relay attacks?
No. KrbRelay and KrbRelayUp demonstrate the relay class survives on Kerberos. What changes is the named primitives, not the existence of relay. Defence is the same shape after Phase 3 as before: LDAP signing and channel binding everywhere, EPA enforced on every authentication endpoint, message integrity required at every level [33].
Why did Microsoft wait thirty years?
Because the four fallback reasons (no DC, local accounts, no SPN, hard-coded NTLM) had no engineered answer until IAKerb, Local KDC, NEGOEX, and the Negotiate refactor existed in shippable form. The standards work, the IETF drafts (one of which was marked Dead WG Document in 2019 and is being revived), the MIT 1.9 parity, and the Apple precedent all had to exist before Microsoft had a credible removal path that did not break enterprise deployments [14, 34].
Can Linux and macOS clients ride this transition?
Yes. MIT Kerberos has had IAKerb since 1.9 (December 2010). Apple ships GSS_IAKERB_MECHANISM since macOS 10.14 (Mojave, 2018). The Samba localkdc effort from Bokovoy and Schneider (FOSDEM 2025) is the parallel open-source path for a Linux local KDC. Heterogeneous Windows-domain estates with Linux file servers and macOS clients are positioned to interoperate with Phase 3 better than they did with NTLMv2 [36, 37].
NTLM was the answer to a 1987 problem and a 1993 problem. It survived because removing it required engineering four orthogonal capabilities that did not exist. They exist now. The next major Windows release ships without it on by default. The attacks that follow it -- KrbRelayUp, RBCD chains, S4U2Self abuse, certificate-template misconfiguration -- target a different protocol with a different vocabulary. The relay class persists. The protocol it targets is no longer NTLM.
If you read this article as part of a sequence, the prior pieces cover the access-control model (SeAccessCheck and its inputs), the chip-layer credential story (TPM, Pluton, Credential Guard, BitLocker), and the application-identity layer (Authenticode, signed binaries, AppLocker, smart application control). NTLM removal is one strand of the broader move from "trust the perimeter" to "tie every credential to a token, a chip, or a Kerberos ticket whose lifetime you can name." Each strand by itself is incomplete; together they are how the next decade of Windows authentication looks.
Study guide
Key terms
- LM hash
- 1987 LAN Manager hash. Uppercase the password, pad/truncate to 14 characters, split into two 7-byte halves, DES-encrypt KGS!@#$% with each half. Password-equivalent, case-insensitive, no salt.
- NT-hash
- MD4(UTF-16LE(password)). Sixteen bytes. The long-term secret every NTLM response derives from. Possession equals authority.
- NTLMv2
- HMAC-MD5 response over server_challenge || client_challenge || timestamp || av_pairs, keyed by NTOWFv2 = HMAC_MD5(NT-hash, UNICODE(Upper(user)||domain)). Ships in NT 4.0 SP4, October 1998.
- SPNEGO / Negotiate
- The GSS-API negotiation mechanism Windows uses to pick between Kerberos and NTLM. The Windows SSPI provider is called Negotiate.
- MIC
- Message Integrity Code -- HMAC-MD5 keyed by ExportedSessionKey over the concatenation of all three NTLM messages. Defeated by Drop-the-MIC (CVE-2019-1040).
- EPA / CBT
- Extended Protection for Authentication / Channel Binding Token. A hash of the TLS endpoint certificate placed in the MsvAvChannelBindings AV_PAIR.
- Pass-the-Hash
- Using a stolen NT-hash directly as the credential, without ever knowing the cleartext password. First published by Paul Ashton in 1997.
- NTLM relay
- Forwarding a live NTLM exchange between a victim client and a third-party target. First public PoC: Sir Dystic's SMBRelay (March 31, 2001).
- Coercion
- Causing a Windows service running as SYSTEM to NTLM-authenticate to an attacker-controlled destination via an RPC method that takes a UNC path. SpoolSample (2018), PetitPotam (2021), Coercer (2022).
- ESC8
- Coerced NTLM relayed to AD CS Web Enrollment (/certsrv/), yielding a certificate that yields a TGT via PKINIT. Schroeder + Christensen, Certified Pre-Owned, June 17, 2021.
- IAKerb
- Initial and Pass Through Authentication Using Kerberos V5 and the GSS-API. Lets a client with no KDC reach proxy AS-REQ / TGS-REQ through an application server.
- Local KDC
- A small Kerberos KDC against the local SAM, exposed via IAKerb. Shipping in Windows 11 / Server 2025.
- NEGOEX
- SPNEGO Extended Negotiation. Adds a meta-data exchange inside the SPNEGO envelope so IAKerb can be negotiated under Negotiate. NOT RFC 8143 (which is NNTP+TLS); the correct primaries are [MS-NEGOEX] and draft-zhu-negoex.
References
- (2022). Coercer. https://github.com/p0dalirius/Coercer ↩
- (2021). Certified Pre-Owned: Abusing Active Directory Certificate Services. SpecterOps. https://posts.specterops.io/certified-pre-owned-d95910965cd2 - June 17, 2021 release defining ESC1-ESC8. ↩
- (2021). Certified Pre-Owned: Abusing Active Directory Certificate Services (whitepaper). SpecterOps. https://specterops.io/assets/resources/Certified_Pre-Owned.pdf ↩
- (2021). PetitPotam. https://github.com/topotam/PetitPotam ↩
- (2021). CVE-2021-36942 -- Windows LSA Spoofing Vulnerability (PetitPotam). NIST NVD. https://nvd.nist.gov/vuln/detail/CVE-2021-36942 ↩
- Impacket. Fortra (originally Core Security). https://github.com/fortra/impacket ↩
- (2021). KB5005413 -- Mitigating NTLM Relay Attacks on Active Directory Certificate Services (AD CS). Microsoft Support. https://support.microsoft.com/en-us/topic/kb5005413-mitigating-ntlm-relay-attacks-on-active-directory-certificate-services-ad-cs-3612b773-4043-4aa9-b23d-b87910cd3429 ↩
- Wikipedia -- LAN Manager. https://en.wikipedia.org/wiki/LAN_Manager ↩
- Wikipedia -- NT LAN Manager. https://en.wikipedia.org/wiki/NT_LAN_Manager ↩
- Microsoft NTLM (Win32 Security). Microsoft Learn. https://learn.microsoft.com/en-us/windows/win32/secauthn/microsoft-ntlm ↩
- [MS-NLMP]: NT LAN Manager (NTLM) Authentication Protocol. Microsoft Open Specifications. https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/b38c36ed-2804-4868-a9ff-8dd3182128e4 - Canonical wire specification for NTLMv1/v2 including NTOWFv2 derivation, AV_PAIRS, MIC, and channel binding fields. ↩
- Network security: LAN Manager authentication level. Microsoft Learn. https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/security-policy-settings/network-security-lan-manager-authentication-level ↩
- NTLM Overview. Microsoft Learn. https://learn.microsoft.com/en-us/windows-server/security/kerberos/ntlm-overview ↩
- (2023). The evolution of Windows authentication. Microsoft Windows IT Pro Blog. https://techcommunity.microsoft.com/blog/windows-itpro-blog/the-evolution-of-windows-authentication/3926848 - October 11, 2023 -- first public Microsoft commitment to removing NTLM rather than restricting it; names IAKerb + Local KDC + Negotiate-everywhere refactor. ↩
- Extended Protection for Authentication Overview. Microsoft Learn. https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/extended-protection-for-authentication-overview ↩
- Wikipedia -- Pass the hash. https://en.wikipedia.org/wiki/Pass_the_hash ↩
- Hashcat example_hashes wiki page. https://hashcat.net/wiki/doku.php?id=example_hashes ↩
- hashcat. https://github.com/hashcat/hashcat ↩
- (2019). CVE-2019-1040 -- NTLM MIC bypass (Drop the MIC). NIST NVD. https://nvd.nist.gov/vuln/detail/CVE-2019-1040 ↩
- (2001). The SMB Man-In-the-Middle Attack / SMBRelay. Cult of the Dead Cow. https://cultdeadcow.com/tools/smbrelay.html ↩
- Wikipedia -- SMBRelay. https://en.wikipedia.org/wiki/SMBRelay ↩
- Overview of Server Message Block signing. Microsoft Learn. https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/overview-server-message-block-signing ↩
- (2008). MS08-068 -- Vulnerability in SMB Could Allow Remote Code Execution. Microsoft Security Bulletin. https://learn.microsoft.com/en-us/security-updates/securitybulletins/2008/ms08-068 ↩
- (2008). CVE-2008-4037 -- SMB Credential Reflection Vulnerability (MS08-068). NIST NVD. https://nvd.nist.gov/vuln/detail/CVE-2008-4037 ↩
- (2008). Pass-The-Hash toolkit v1.3. https://hexale.blogspot.com/2008/02/release-pass-hash-toolkit-v13.html ↩
- (2008). Pass-The-Hash Toolkit for Windows (2016 re-archive). Core Security. https://coresecurity.com/sites/default/files/private-files/publications/2016/05/Ochoa_2008-Pass-The-Hash.pdf ↩
- How Mimikatz Became the Go-To Hacker Tool. Wired. https://www.wired.com/story/how-mimikatz-became-go-to-hacker-tool/ ↩
- Wikipedia -- Mimikatz. https://en.wikipedia.org/wiki/Mimikatz ↩
- (2014). mimikatz. https://github.com/gentilkiwi/mimikatz ↩
- Credential Guard overview. Microsoft Learn. https://learn.microsoft.com/en-us/windows/security/identity-protection/credential-guard/ ↩
- (2018). SpoolSample (PrinterBug). https://github.com/leechristensen/SpoolSample ↩
- (2019). From the Archives: Drop the MIC -- CVE-2019-1040. CrowdStrike (originally Preempt). https://www.crowdstrike.com/en-us/blog/from-the-archives-drop-the-mic-cve-2019-1040/ ↩
- (2022). KrbRelayUp. https://github.com/Dec0ne/KrbRelayUp ↩
- Initial and Pass Through Authentication Using Kerberos V5 and the GSS-API (IAKERB). IETF kitten WG. https://datatracker.ietf.org/doc/draft-ietf-kitten-iakerb/ - IETF draft marked Dead WG Document on 2019-08-29 by Robbie Harwood; Microsoft is reviving the protocol for Windows 11 / Server 2025. ↩
- (2024). Active Directory improvements in Windows Server 2025. Microsoft Windows OS Platform Blog. https://techcommunity.microsoft.com/blog/windowsosplatform/active-directory-improvements-in-windows-server-2025/4202383 ↩
- (2025). localkdc -- a general local authentication hub. FOSDEM. https://archive.fosdem.org/2025/schedule/event/fosdem-2025-5618-localkdc-a-general-local-authentication-hub/ ↩
- (2025). Local authentication hub. https://blog.cryptomilk.org/2025/02/09/local-authentication-hub/ ↩
- [MS-NEGOEX]: SPNEGO Extended Negotiation (NEGOEX) Security Mechanism. Microsoft Open Specifications. https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-negoex/0ad7a003-ab56-4839-a204-b555ca6759a2 - Microsoft Open Specification for the SPNEGO extension that carries IAKerb under the existing Negotiate API. Replaces the scope-doc misattribution to RFC 8143. ↩
- (2011). SPNEGO Extended Negotiation (NEGOEX) Security Mechanism (Internet-Draft). IETF. https://datatracker.ietf.org/doc/html/draft-zhu-negoex - Expired Microsoft IETF draft (January 2011) documenting NEGOEX meta-data exchange inside SPNEGO. ↩
- (2017). RFC 8143 -- Using Transport Layer Security (TLS) with NNTP. IETF. https://datatracker.ietf.org/doc/rfc8143/ - Cited only as the negative anchor for the scope-doc misattribution: RFC 8143 is unrelated to NEGOEX. ↩
- (2026). Advancing Windows security: Disabling NTLM by default. Microsoft Windows IT Pro Blog. https://techcommunity.microsoft.com/blog/windows-itpro-blog/advancing-windows-security-disabling-ntlm-by-default/4489526 - January 29, 2026 -- the three-phase roadmap. Author is mariam_gewida, not Palko (who wrote the October 2023 predecessor). ↩
- (2025). KB 5064479 -- Overview of NTLM auditing enhancements in Windows 11 version 24H2 and Windows Server 2025. Microsoft Support. https://support.microsoft.com/en-us/topic/overview-of-ntlm-auditing-enhancements-in-windows-11-version-24h2-and-windows-server-2025-b7ead732-6fc5-46a3-a943-27a4571d9e7b ↩
- Deprecated features for Windows client (NTLM row). Microsoft Learn. https://learn.microsoft.com/en-us/windows/whats-new/deprecated-features ↩
- Upcoming changes to NTLMv1 in Windows 11 version 24H2 and Windows Server 2025. Microsoft Support. https://support.microsoft.com/en-us/topic/upcoming-changes-to-ntlmv1-in-windows-11-version-24h2-and-windows-server-2025-c0554217-cdbc-420f-b47c-e02b2db49b2e ↩
- Audit use of NTLMv1 on a Windows Server-based domain controller (KB 4090105). Microsoft Learn. https://learn.microsoft.com/en-us/troubleshoot/windows-server/windows-security/audit-domain-controller-ntlmv1 ↩
- (2026). Microsoft Begins NTLM Phase-Out With Three-Stage Plan to Move Windows to Kerberos. The Hacker News. https://thehackernews.com/2026/02/microsoft-begins-ntlm-phase-out-with.html ↩
- (2022). CVE-2022-26925 -- Windows LSA Spoofing Vulnerability (LSARPC NTLM relay). NIST NVD. https://nvd.nist.gov/vuln/detail/CVE-2022-26925 ↩
- The NIS2 Directive. European Commission Digital Strategy. https://digital-strategy.ec.europa.eu/en/policies/nis2-directive - Official European Commission overview of Directive (EU) 2022/2555 (NIS2) establishing cybersecurity risk-management obligations for entities in 18 critical sectors across the EU. ↩
- Cyber Resilience Act. European Commission Digital Strategy. https://digital-strategy.ec.europa.eu/en/policies/cyber-resilience-act - Official European Commission overview of the Cyber Resilience Act (CRA) entered into force on 10 December 2024; mandatory cybersecurity requirements for products with digital elements. ↩