NTLM Fully Explained for Security Professionals
Introduction
This article is co-opted from my personal notes on NTLM, and took around a hundred hours to write. NTLM is convoluted, the documentation is lackluster, and most explanations violate Feynman’s Razor. Consequently, the resources out there tend to be wrong. This resource is an expensive attempt to be right.
Generally speaking, most security work does not require a low-level understanding—a functional one will suffice. But if you have been tempted (or tricked) into looking at NTLM more closely, this article may help.
Information was primarily sourced directly from Microsoft specification documents, with gaps filled from select third party resources when possible, and deduction when not. Every effort has been made to ensure that this article is as accurate as possible. Please reach out with any corrections; my contact information is available on the home page.
New Technology LAN Manager
NTLM is a suite of security protocols used for authentication within Windows environments. It is succeeded by Kerberos, but NTLM is still enabled in Windows by default (though that is changing with Windows 11). NTLM is not a standalone protocol; it is used to implement authentication within another protocol. NTLM appears within application protocols such as SMB, LDAP, SMTP, HTTP/S, and so on.
In NTLM, knowledge of a user’s password hash is equivalent to knowledge of that user’s password. While the hash types used by NTLM (NT hash and LM hash) are easy to crack, cracking a hash is not actually required to authenticate as a user. You simply Pass the Hash itself.
Furthermore, no version of NTLM provides mutual authentication. Clients cannot verify that a server is legitimate. If an attacker can manipulate a client into authenticating to an attacker-controlled server, the attacker may be able to learn the user’s password hash or perform relay attacks.
Due to NTLM’s security issues, modern Active Directory prefers Kerberos authentication for all domain users. Even when NTLM is disabled for the domain, however, remote authentication to local user accounts (such as the built-in Administrator) must use NTLM. This is because AD Kerberos authentication currently does not support local accounts, though this too is changing with Windows 11.
There are two main versions of NTLM: v1 and v2. In short, NTLMv2 makes it more computationally difficult for an attacker to obtain a user’s password hash and crack the user’s password from that hash. This is accomplished primarily through the use of stronger cryptography, a client challenge, and a timestamp. But NTLMv2 does not and cannot address the underlying security issues with NTLM, which is why Kerberos is recommended.
NTLM is implemented via the NTLM SSP. As a Security Support Provider (SSP), and thus as an authentication mechanism available to the Security Support Provider Interface (SSPI), NTLM authentication always results in both the client and server possessing a secret session key. This session key can be used by the parent application protocol for performing signing or encryption operations on future application messages, such as SMB/LDAP Signing or LDAPS/HTTPS Channel Binding.
Common Terminology
NTLM is colloquially used to refer to any of five hash types and two protocols:
- LM Hash
- Trivial to crack, not case sensitive, disabled from Windows 7/Server 2008 onwards
- Can be used in Pass the Hash attacks
- ex)
e52cac67419a9a224a3b108f3fa6cb6d
- NT Hash, AKA NTLM hash
- Easy crack, stored in the SAM database on machines or in the NTDS database on DCs
- Can be used in Pass the Hash attacks
- ex)
8846f7eaee8fb117ad06bdd830b7586c
- “NTLM Hash” (colloquial term)
- Can refer to the NT hash, but can also refer to the combination of the LM Hash and NT Hash
- ex)
e52cac67419a9a224a3b108f3fa6cb6d:8846f7eaee8fb117ad06bdd830b7586c
- NTLMv1 protocol AKA Net-NTLMv1 protocol
- Challenge-response authentication, relies on the NT Hash (and/or the LM Hash)
- NTLMv2 protocol AKA Net-NTLMv2 protocol
- Challenge-response authentication, relies on the NT Hash (and/or the LM Hash)
- NTLMv1 hash AKA Net-NTLMv1 hash AKA LMv1 or NTLMv1 challenge response
- Not direct hashes of user passwords; produced for challenge/response in NTLMv1
- Can not be used in pass the hash attacks, but can still be relayed or cracked
- This is most accurately called the “NTLMv1 challenge response”, which itself contains the real NTLMv1 hash, but this usage isn’t common
- NTLMv2 hash AKA Net-NTLMv2 hash AKA LMv2 or NTLMv2 challenge response
- Not direct hashes of user passwords; produced for challenge/response in NTLMv2
- Can not be used in pass the hash attacks, but can still be relayed or cracked
- This is most accurately called the “NTLMv2 challenge response”, which itself contains the real NTLMv2 hash, but this usage isn’t common
As a note, try not to worry too much about the precise meaning of “NTLM hash” as used by others. These terms will not be used accurately. Just expect imprecision, and infer meaning via context.
The “NTLM hash” is often presented within the following format:
[Username]
|
v
Bob:500:aad3b435b51404eeaad3b435b51404ee:58a478135a93ac3bf058a5ea0e8fdb7
^ ^ ^
| | |
[RID] | |
[ ---------- LM Hash* --------- ] |
[ --------- NT Hash --------- ]
[ ------------------------ NTLM Hash ------------------------- ]
*N.B: In Windows 7/Server 2008 and beyond, the LM hash will always be aad3b...
. This is an LM hash of an empty string. This is to effectively disable the use of the LM hash while maintaining backwards compatibility with systems that still expect it.
The NTLM Exchange
NTLM is a challenge-response authentication protocol. First, the client performs a three way handshake with the server. The server then performs a two-way handshake with a Domain Controller:
- The client sends a
NEGOTIATE_MESSAGE
packet to the server to initiate NTLM authentication. The packet contains the client’s username and any required NTLM options, such as cryptography settings supported by the client. - The server responds with a
CHALLENGE_MESSAGE
packet containing an 8 byte random number, AKA the “server challenge”. - The client encrypts the server challenge using the LM and/or NT hash as input. If NTLMv2 is being used, an 8 byte, client-generated random number (called the “client challenge”) is also used as input. The encrypted output, known as the “challenge response”, is sent to the server in an
AUTHENTICATE_MESSAGE
packet. - The server forwards the server challenge, the client’s challenge response, and the client’s username to a Domain Controller via a
NETLOGON_NETWORK_INFO
packet. This message is encrypted with the server’s machine account password hash, which both the server and Domain Controller know. - The Domain Controller, which knows the user’s password, encrypts the server challenge using the user’s password, just like the user did in step 3. If the result matches the encrypted challenge(s) forwarded by the server, then the Domain Controller replies to the server with a
NETLOGON_VALIDATION_SAM_INFO4
packet. Like the previous message, this message is encrypted with the server’s machine account password hash. The message contains the user’s PAC (which describes the user and their privileges) and an NTLM session key. The server then grants access to the user.
Detailed Analysis
Challenge Response Types
At a high level, this is essentially the NTLM process:
- The client initiates authentication with the server.
- The server sends the client a random number called the server challenge.
- The client encrypts the server challenge using a user’s password hash as a key, and sends this ciphertext to the server as a challenge response.
The exact cryptographic operations performed during this process depend on two factors: the type of user password hash and the NTLM version. These two pieces ultimately decide the type of challenge response that is sent.
First, there are two types of user password hashes: the LM hash and the NT hash. The LM hash is produced via DES encryption, while the NT hash is produced via MD4 hashing. The NT hash is cryptographically stronger than the LM hash.
There are two versions of NTLM: NTLMv1 and NTLMv2. NTLMv1 uses DES encryption, while NTLMv2 uses HMAC-MD5 hashing.
Between these combinations of hash types and NTLM versions, there are five types of challenge response:
- The LMv1 Response, which uses the LM Hash for NTLMv1 authentication
- Oldest type of response and least secure; compatible with very old machines.
- The NTLMv1 Response, which uses the NT Hash for NTLMv1 authentication
- Improves on the LMv1 Response by using the NT hash; otherwise identical.
- The LMv2 Response, which uses the NT Hash (not a typo) for NTLMv2 authentication
- Built for NTLMv2 compatability with older servers
- The NTLMv2 Response, which uses the NT Hash for NTLMv2 authentication
- Most secure NTLM authentication type, but still a lot worse than Kerberos
- The NTLMv1 with ESS Response, which uses the NT Hash for NTLMv1 authentication with an NTLMv2-style client challenge.
- This is a security improvement over an NTLMv1 response. Still worse than the NTLMv2 Response, but does not require the server to be NTLMv2 compatible.
NTLMv1 vs NTLMv2
The first significant security improvement made by NTLMv2 is the use of HMAC-MD5 for encrypting the server challenge, as opposed to NTLMv1’s use of DES.
The second improvement of NTLMv2 over NTLMv1 is the introduction of the “blob”, a variable length chunk of data ranging around 64 bytes. Among other things, the blob importantly contains a timestamp and a client-generated random challenge. The blob is used as part of the cryptographic input for the NTLMv2 Response, and is therefore cryptographically-protected, though a copy is also sent in cleartext.
The timestamp in the blob makes it more difficult for attackers to replay NTLMv2 AUTHENTICATE_MESSAGE
packets, as the server can discard any message which is too old, as defined by the MaxLifeTime variable controlled by the server’s parent application. An attacker can still replay NTLMv2 AUTHENTICATE_MESSAGE
packets in real-time, but only for the limited duration in which they are valid. That’s still bad, but not as bad as it could be.
The client challenge in the blob makes it more difficult for attackers to crack NTLM responses through the use of rainbow tables. We can explain this through an example:
Imagine that an attacker exists on the local network, can eavesdrop on all packets, and wishes to learn a victim user’s password hash.
As mentioned, in NTLMv1, the client encrypts the server challenge with their password hash.
Now, the attacker could deploy a malicious server and manipulate the client into authenticating to it, either passively through network poisoning attacks or actively through coercion attacks such as PetitPotam.
When the client initiates authentication with this attacker-controlled server, the attacker can supply a fixed server challenge (such as 1122334455667788
). The client will encrypt this challenge with their password hash to create the challenge response and send it to the attacker-controlled server.
The attacker can then consult a precomputed rainbow table of every possible LMv1/NTLMv1 response for every possible password hash for that fixed server challenge. This allows the attacker to instantly crack the challenge response and learn the user’s password hash. This attack is feasible due to the LMv1/NTLMv1’s 56-bit DES keyspace being relatively small at 2^56. The specific fixed server challenge provided above is the server challenge for which crack.sh notoriously created and freely offered a rainbow table, allowing attackers to instantly crack LMv1/NTLMv1 challenge responses.
In NTLMv2, however, the attacker cannot feasibly compute a rainbow table, as they would have to compute every possible LMv2/NTLMv2 response for every possible password hash for every possible client challenge for a fixed server challenge. The inclusion of the client challenge in the equation renders this attack impossible.
“Negotiation”
Between NTLMv1, LMv1, NTLMv1 ESS, LMv2, and NTLMv2, how is a particular NTLM challenge response selected by a client? Through a registry setting called “LM Compatability Level” present on both the client and server. This setting determines which NTLM versions and which hash types are advertised by the client in the NEGOTIATE_MESSAGE
and by the server in the CHALLENGE_MESSAGE
. The client and the server state their compatability and will select the most secure option that they both support. Deceivingly, the client and the server do not really “negotiate”; they are bound by the LM Compatability Level set in their registries, and have therefore already decided on which responses they are willing to send and/or receive.
There is an exception, however, in Extended Session Security (ESS). If the server is offering NTLMv1 in its CHALLENGE_MESSAGE
, it will also specify whether or not it supports Extended Session Security (ESS). If it does, then the client can optionally elect to use ESS if it supports it. If it doesn’t, or chooses not to, the server will happily accept NTLMv1 without ESS. ESS is therefore the only component of NTLM authentication that is truly negotiated over the network.
Session Keys and Extended Session Security (ESS)
What is ESS? Unfortunately, this is a highly complex question to answer, and almost everyone has it wrong. But if you really wish to know, we will begin with the role of session keys in NTLM.
As a byproduct of the authentication process, NTLM establishes secret session keys on the client and server. These session keys are derived in part from the user’s password, which the server does not know (but the domain controller does). Consequently, the session key is always calculated by the domain controller.
The server sends the domain controller a NETLOGON_NETWORK_INFO
message containing the client challenge, the server challenge, and the client’s challenge response. This message is encrypted using the server’s machine account password hash. Then the domain controller validates the client’s challenge response, calculates the session key, and sends a message back to the server containing the session key. This message is also encrypted using the server’s machine account hash.
Since the client can calculate the session key using their knowledge of the password hash, and the server has just been sent the session key by the domain controller, both the client and server now share a mutual cryptographic secret.
Applications (such as SMB) may use the NTLM session keys to sign or encrypt future messages. This is called “session security”. All versions of NTLM fully support session security except for LMv1 and NTLMv1, which support encryption but not signing. An attacker who learns the session key could forge valid signatures for modified messages or decrypt application traffic.
In NTLMv1, the attacker learns the session key if they learn the LM hash, NT hash, or user password. The LM hash or NT hash can be learned by cracking the LMv1 or NTLMv1 challenge response, respectively. As mentioned, cracking these is made dramatically easier if the attacker operates a malicious server with a fixed server challenge (e.g. 1122334455667788
), allowing the use of a rainbow table which has been precomputed for this server challenge.
In NTLMv2, the attacker learns the session key if they learn the NT hash or user password. The NT hash can be learned by cracking the NTLMv2 hash. The NTLMv2 hash can be learned by cracking the LMv2/NTLMv2 challenge response. Due to NTLMv2’s use of a random client challenge, the attacker cannot feasibly precompute a rainbow table. This upgrade to session security is called “Extended Session Security”, or ESS. NTLMv2 always uses and supports ESS.
ESS was backported to NTLMv1 via “NTLMv1 with ESS”, which modifies the NTLMv1 challenge response computation and session key computation to include a client challenge, like NTLMv2. Naturally, this makes NTLMv1 ESS challenge responses (and session keys) harder to crack. Since ESS is already a part of NTLMv2, the term “ESS” is typically only used to describe NTLMv1 with ESS.
There’s one last caveat with ESS: while NTLMv1 supports clients who wish to authenticate exclusively via their LM hash, NTLMv1 with ESS does not and requires the use of an NT hash.
Message Integrity Code (MIC)
In the previous section, it was discussed that the NTLM authentication process results in the client and server both possessing a copy of a secret session key. An optional use of this session key available for NTLMv2 Responses is the Message Integrity Code (MIC), also known as a Message Authentication Code (MAC).
In NTLM, the MIC exists so that servers can validate the integrity of AUTHENTICATE_MESSAGE
packets sent by clients. To be precise, the MIC ensures that the AUTHENTICATE_MESSAGE
sent by the client cannot be modified in transit. This is useful as attackers need to modify details of the message when, for example, relaying NTLM cross-protocol, e.g. relaying an SMB client to an LDAP server.
Here’s how the MIC works: The MIC uses the secret session key as part of its computation, which means that only the client and server (who know the session key) can create valid MICs.
Specifically, the MIC is created by the client in two steps:
1. The full contents of the NEGOTIATE_MESSAGE, CHALLENGE_MESSAGE, and AUTHENTICATE_MESSAGE are concatenated
3. This concatenation is HMAC-MD5 hashed using the session key as a key
This MIC is then placed within the AUTHENTICATE_MESSAGE
. This is the very last step in creating the AUTHENTICATE_MESSAGE
. The version of the AUTHENTICATE_MESSAGE
used to calculate the MIC is the entire message before the MIC has been added.
Once the client has sent the AUTHENTICATE_MESSAGE
to the server, the server now has the client’s copy of the MIC. Then, the server calculates its personal copy of the MIC using its own knowledge of the session key. If the server finds that the MIC it calculated matches the MIC sent by the client, then the server knows that the AUTHENTICATE_MESSAGE
is legitimate. This is because the valid MIC can only be produced by someone who knows the session key, which in theory only includes the client and server.
If the AUTHENTICATE_MESSAGE
packet has been modified in any way, the client-sent MIC will not match the server-generated MIC, and the server can refuse the authentication. If the client-sent MIC itself is modified in any way, then the server-generated MIC will not match, and the server can refuse the authentication. And if the AUTHENTICATE_MESSAGE
does not have a MIC at all, then the server can refuse the authentication.
For example, imagine that an attacker has copied an AUTHENTICATE_MESSAGE
packet sent by a legimate client to SMB server “A”. The attacker attempts to relay the message to LDAP server “B”. Since the attacker is attempting to relay cross-protocol, they’ll need to change some of the flags in the AUTHENTICATE_MESSAGE
. If they make any changes, however, then the MIC calculated by the client in the AUTHENTICATE_MESSAGE
will not match the MIC computed by the server, and the packet will be discarded.
Notably, the MIC is sent in cleartext, and is fully visible to the attacker. So why couldn’t the attacker make their changes, recalculate their own MIC, and replace the MIC in the message? Because the attacker does not know the session key. They would have to successfully guess the 16 byte session key, of which there are 2^96 possible values.
This all said, checking the MIC is optional for the server, and only performed if the client indicates that the MIC should be checked. The client indicates this within the MsvAvFlags field, which is provided within the “AvPairs” section of the blob. Since the blob is cryptographically protected within the NTLMv2 Response, an attacker cannot modify this flag, and therefore cannot remove the MIC. Well, except for the Mic Drop attacks, but don’t worry about that.
Signing & Extended Protection for Authentication (EPA)
In addition to the MIC, NTLM authentication is protected from relay attacks by two primary defences:
- Application protocol signing (“Signing”).
- Extended Protection for Authentication, AKA Channel Binding.
These defences are authentication protocol agnostic, and therefore not strictly tied to NTLM, but are nonetheless vital mitigations for NTLM’s intrinsic vulnerability to relay attacks.
Signing
At the end of an NTLM authentication exchange, both the client and server will possess a session key that can be passed to the application protocol. The application protocol (be it SMB, LDAP, or otherwise) can use the session key to sign or encrypt future messages. If the message is signed, then interceptors can read the message, but they cannot modify it.
Signing is critical for preventing relay attacks. Without signing, if an attacker intercepts an SMB message containing a valid NTLM AUTHENTICATE_MESSAGE
, they could freely modify the commands contained within the SMB message to take malicious actions as the user whose traffic was intercepted. If signing is required by the server, however, any modification to the SMB message will be detected. This is because the attacker does not know the user’s password, meaning they do not know the session key, meaning they cannot create valid signatures that will be accepted by the server.
Signing is deployed in a network by ensuring that all servers require signed messages for authenticated traffic. This must be performed per application protocol.
Signing’s Blindspot
Signing is not supported for every application protocol, however. In particular, while SMB, LDAP, and HTTP all support signing, LDAPS and HTTPS do not. Per Microsoft’s SSPI documentation:
[Signing] is not always an option. In some cases, the format of the application protocol message is fixed by standards designed for bearer tokens.
In fact, LDAPS and HTTPS were left vulnerable to relay attacks for some time due to their lack of signing support. This vulnerability, named CVE-2017-8563, was discovered by Preempt and drove Microsoft to implement Extended Protection for Authentication (EPA):
[When signing is not an option], Extended Protection for Authentication (EPA), also known as Channel Binding, can protect against forwarding over a TLS/SSL channel.
For TLS-secured protocols like LDAPS and HTTPS, which support channel binding, signing is [intentionally left unimplemented](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/2c3ea153-eff9-46a7-8614-19b677efa4e0](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/2c3ea153-eff9-46a7-8614-19b677efa4e0):
…Active Directory does not permit [signing/sealing] protection mechanisms to be employed on an SSL/TLS-protected LDAP connection.
These protocols must instead rely on EPA, discussed below.
Extended Protection for Authentication (EPA)
Extended Protection for Authentication (EPA) is an extension to the NTLM protocol. Though used synonymously with Channel Binding, it includes two forms of binding:
- Channel Binding, as standardized by RFC 5056 - Channel Bindings and RFC 5929 - Channel Bindings for TLS.
- Service Binding, as standardized nowhere, and used rarely.
Both of these protections function by attaching server-specific identifiers to the NTLM AUTHENTICATE_MESSAGE
via the blob. The blob is cryptographically protected by the user’s password, meaning that an attacker cannot modify these identifiers, and recipients can therefore reliably determine whether they were the intended target of a message. That is, they check the identifier contained within the AUTHENTICATE_MESSAGE
’s blob against their own identifier. If they mismatch, the server knows that the authentication attempt was not originally intended for them, and was thus relayed.
Sidenote: As EPA depends upon the blob, and the blob is only available in NTLMv2, EPA cannot protect NTLMv1 traffic.
Service Binding uses the service’s SPN as an identifier, while Channel Binding uses a hash of the service’s TLS certificate. Service Binding does not technically require the presence of TLS, but Channel Binding does.
In both of its forms, EPA provides a stronger security guarantee than signing. While signing prevents relaying modified messages, it does not prevent relaying unmodified messages. EPA prevents both. An attacker typically does not have much to gain from relaying unmodified messages, but it’s worth mentioning that EPA is “stronger” than signing in this regard.
SPN Validation AKA Service Binding
NTLM as an authentication protocol is not aware of hostnames, but clients can optionally provide (and servers can demand) an attribute within the blob in the AUTHENTICATE_MESSAGE
called the “MsvAvTargetName”. Its value is the Service Prinicipal Name (SPN) of the service to which the client intends to connect. If Service Binding is required, then this attribute must be set.
When MsvAvTargetName is set, then the SPN is included within the cryptographically-protected blob in the AUTHENTICATE_MESSAGE
, guarding this value against modification from attackers on the network.
While NTLMv2’s inclusion of timestamps reduces the duration in which an attacker can relay AUTHENTICATE_MESSAGE
packets, there is still a tight window of time in which an attacker can replay these messages to any server and authenticate as the victim user. But if all servers require that the SPN set in the AUTHENTICATE_MESSAGE
packet matches the service to which the client is attempting to connect, each server can discard any packets with a mismatching SPN. This greatly reduces the surface of replay attacks.
Unfortunately, Service Binding is not set by default, and the only officially documented use of Service Binding is in SMB. Evidently, Service Binding has undocumented compatability with HTTP, but it cannot be used concurrently with Channel Binding. Furthermore, Service Binding relies on the SPN, which is theoretically easier to “steal” (e.g. via SPN-jacking) than the private key associated with a server’s certificate.
For these reasons, Service Binding remains largely unpromoted. Instead, it is recommended to stop relay attacks with Channel Binding when TLS is available, and Signing when TLS is not.
Channel Binding
Channel Binding is what is typically meant when people mention EPA. Like Service Binding, it uses a server-specific identifier. In Channel Binding, this identifier is an MD5 hash of the server’s certificate, stored as the value for the blob’s “MsvAvChannelBindings” attribute.
Imagine that a client is initiating an NTLM-authenticated LDAPS session with a server, and an attacker is sitting between these two hosts. The two hosts will establish a TLS tunnel, within which LDAP messages will be exchanged, within which NTLM messages will be exchanged. For relay attacks, the attacker requires the ability to decrypt the TLS traffic. The only way to do this is to establish two TLS tunnels: the attacker becomes the TLS server for the client, and becomes the TLS client for the server. The attacker can now receive and relay the contained LDAP and NTLM messages.
Now, in a standard TLS handshake, the server must send the client a certificate containing the server’s public key. The client then generates a session token and uses the server’s public key to encrypt it. The client sends the encrypted session token to the server, which then decrypts it using the server’s private key. The client and server now possess a session key to be used for encrypting future communications with each other.
Critically, the server will not be able to decrypt the session key if it does not possess the private key corresponding to the certificate it presented. This means that only the true owner of a certificate will be able to establish a TLS tunnel with it.
Channel Binding works via the client placing a hash of the server’s certificate within a cryptographically protected section of the authentication message. In the case of NTLM, the client places the hash of the server’s certificate within the blob contained within the NTLM AUTHENTICATE_MESSAGE
. The blob is cryptographically-protected by the user’s password, and therefore cannot be modified by the attacker. Thus, the integrity of the certificate is used to protect the integrity of the NTLM authentication, “binding” the two together.
To demonstrate: remember that in order to decrypt the TLS traffic sent by the client, the attacker will need to present the client with its own certificate. The client will then hash the attacker’s certificate and place it within the NTLM AUTHENTICATE_MESSAGE
’s blob, which the attacker cannot modify. Now, when the attacker relays that AUTHENTICATE_MESSAGE
to the server, the server will check the blob and discover that the contained certificate hash does not match its own certificate hash. The server now knows that it was not the originally intended recipient of the message, indicating that the message was relayed. The server then discards the message, thus killing the relay attempt.
Cryptographic Computations
The computation of each hash and challenge response is described here in detail. This is useful for understanding the underlying differences between NTLMv1 (LMv1/NTLMv1/NTLMv1 with ESS Responses), and NTLMv2 (LMv2/NTLMv2 Responses). Later, the blob and “AvPairs” is also discussed.
User Password Hashes
LM Hash
As mentioned prior, the LM hash will often begin with aad3b...
. This is an LM hash of an empty string, and serves to effectively disable the use of the LM hash while maintaining backwards compatibility with systems that still expect it.
Because the password is converted to all-uppercase, the LM hash is case-insensitive. It also limits passwords to 14 characters and is trivial to crack. This is a disaster of a hash.
1. User's password converted to uppercase
2. Null padded to 14 bytes
3. Split into two 7 byte halves
4. Each 7 byte half is used as a DES key to encrypt the ASCII string "KGS!@#$%", yielding two 8 byte ciphertext values
5. These two 8 byte ciphertext values are concatenated, resulting in the 16 byte LM hash
NT Hash
This is the preferred user password hash of NTLM, and is almost always used in favor of the LM hash. It cannot be called secure, but it’s at least superior to LM.
1. The user's password is MD4 hashed, resulting in the 16 byte NT hash
NTLMv1 Challenge Responses
LMv1 Response
Relies on DES. This was the first version of the NTLM response and predates the NTLMv1 Response. Typically only used by the oldest clients, and requires that the LM hash is actually used rather than the empty aad3b...
LM hash.
1. The 16 byte LM hash is null-padded to 21 bytes
2. This 21 byte value is split into 7-byte thirds
3. Each third is used as a DES key to encrypt the challenge provided by the server, yielding three 8 byte ciphertext values
4. These three 8 byte ciphertext values are concatenated, resulting in the 24 byte LM Response
NTLMv1 Response
Relies on DES. More secure than LMv1, less secure than everything else.
1. The 16 byte NT Hash (AKA MD4 hash of user password) is null-padded to 21 bytes
2. This 21 byte value is split into 7-byte thirds
3. Each third is used as a DES key to encrypt the server challenge, yielding three 8 byte ciphertext values
4. These three 8 byte ciphertext values are concatenated, resulting in the 24 byte NTLMv1 Response
NTLMv1 with ESS Response
Essentially the NTLMv1 Response, but takes advantage of the LM field to include a client challenge in the response ala NTLMv2.
1. The 8 byte client challenge is null-padded to 24 bytes and placed in the LM response field of the AUTHENTICATE packet from the client
2. The 8 byte server challenge is concatenated with the 8 byte client challenge, yielding the "session nonce"
3. The session nonce is MD5 hashed, yielding a 16 byte hash
4. This 16 byte hash is truncated to 8 bytes, yielding the NTLMv1 ESS hash
5. The 16 byte NT hash (AKA MD4 hash of user password) is null-padded to 21 bytes
6. This 21 byte value is split into 7-byte thirds
7. Each third is used as a DES key to encrypt the NTLMv1 ESS hash, resulting in three 8 byte ciphertext values
8. These three 8 byte ciphertext values are concatenated, resulting in the 24 byte NTLMv1 ESS Response
NTLMv2 Challenge Responses
LMv2 Response
The LMv2 Response is special. It’s a clever workaround for the following scenario: a client and a domain controller both understand NTLMv2, but the server only understands LMv1. The LMv2 Response allows the client to authenticate using a truncated version of NTLMv2 over LMv1.
This works because the LMv1 response is 24 bytes, and we can cram an NTLMv2 response in there as long as we shorten the blob to just the client challenge. As the server itself does not validate the client’s response, but instead relies on a Domain Controller, the server does not need to actually understand NTLMv2 to support it. It just needs to relay what it “thinks” is an LMv1 Response to the Domain Controller, who will be wise to the workaround.
The LMv2 Response is less secure than the NTLMv2 Response, what with the truncation of the blob, but is at least way more secure than the LMv1 Response.
1. The client-specified username (case insensitive) is concatenated with the server-specified server name (case sensitive)
2. This value is HMAC-MD5 hashed using the NT hash as the key, yielding the 16 byte NTLMv2 hash
3. The 8 byte server challenge is concatenated with an 8 byte client challenge
4. This value is HMAC-MD5 hashed using the NTLMv2 hash as the key, yielding a 16 byte value
5. This value is concatenated with the 8 byte client challenge, resulting in the 24 byte LMv2 response
NTLMv2 Response
This is the strongest authentication available in NTLM. If NTLM is necessary within a network, ideally it should only ever be NTLMv2. Really though, Kerberos should be used instead.
1. The client-specified username (case insensitive) is concatenated with the server-provided server name (case sensitive)
2. This value is HMAC-MD5 hashed using the NT hash as the key, yielding the 16 byte NTLMv2 hash
3. The ~64 byte "blob" is constructed, containing a timestamp, a client challenge, and the target name
4. The 8 byte server challenge is concatenated with the ~64 byte blob
5. This value is HMAC-MD5 hashed with the NTLMv2 hash as the key, yielding a 16 byte value
6. This 16 byte value is concatenated with the ~64 byte blob, resulting in the NTLMv2 response
Session Keys
LMv1 Session Key
Used when the client only send an LMv1 response without an NTLMv1 response.
1. The 16 byte LM hash is truncated to 8 bytes
2. This value is null-padded to 16 bytes, resulting in the 16 byte LM Session Key
NTLMv1 Session Key
Used whenever the client sends an NTLMv1 response.
1. The NT hash (itself an MD4 hash of the user password) is MD4 hashed, resulting in the 16 byte NTLMv1 Sesssion Key
LMv2 Session Key
Used when the client sends only an LMv2 response without an NTLMv2 response. Note that the server can compute a copy of the NTLMv2 hash without receiving an NTLMv2 response from the client.
1. The server challenge is concatenated with the client challenge, yielding the "session nonce"
2. The session nonce is HMAC-MD5 hashed using the NTLMv2 hash as the key, yielding a 16 byte hash
3. This hash is HMAC-MD5 hashed using the NTLMv2 hash as the key, resulting in the 16 byte LMv2 Session Key
NTLMv2 Session Key
Used when the client sends an NTLMv2 response.
1. The server challenge is concatenated to the NTLMv2 blob (which contains a client challenge)
2. This ~72 byte value is HMAC-MD5 hashed using the NTLMv2 hash as the key, yielding a 16 byte hash
3. This hash is HMAC-MD5 hashed using the NTLMv2 hash as the key, resulting in the 16 byte NTLMv2 Session Key
NTLMv1 with ESS Session Key
Used when the client sends an NTLMv1 response and requests ESS.
1. The NT hash (itself an MD4 hash of the user password) is MD4 hashed, resulting in the 16 byte NTLMv1 Sesssion Key
2. The server challenge is concatenated with the client challenge, yielding the "session nonce"
3. The session nonce is HMAC-MD5 hashed using the NTLMv1 session key as the key, resulting in the 16 byte NTLMv1 with ESS Session Key
The Blob and “AV_Pairs”
Okay, so this isn’t really a cryptographic computation, but it’s involved in NTLMv2’s, and I wanted to throw a bone to those who are curious about what exactly is the deal with the blob, and to those who have seen the term “AV_Pairs” and been confused.
The blob is, at minimum, 32 bytes long, and contains following (in order):
THE BLOB (AKA "NTLMv2_CLIENT_CHALLENGE" in MS-NLMP)
--------
1 byte - RespType - response type ID, always 0x01
1 byte - HiRespType - max response ID understoond, always 0x01
2 bytes - Reserved1 - reserved, must be 0x0000
4 bytes - Reserved2 - reserved, must be 0x00000000
8 bytes - TimeStamp - the timestamp used in NTLMv2
8 bytes - ChallengeFromClient - the client challenge in NTLMv2
4 bytes - Reserved3 - reserved, must be 0x00000000
n bytes - Any number of AV_PAIRs
As you can see, almost all of the “other things” in the blob either take static values or are reserved as empty. The one exception is that “n bytes” long AV_PAIRs stuff.
Essentially, an AV_PAIR, AKA Attribute-Value Pair, is a data structure. It stores pairs of attributes and their values. An AV_PAIR is roughly 8 bytes long and has three fields: AvId
, AVLen
, and Value
:
AvId
identifies the name of the attribute whose value is being provided. It is 2B.AvLen
specifies the length in bytes of theValue
field. Usually 2B, but can be nB.Value
provides the value for this AV pair. Can be any number of bytes (nB).
“AvPairs” is the specific term for the section of the blob in the AUTHENTICATE_MESSAGE
that can contain AV_PAIR data structures. Specifically, AvPairs is a byte array of AV_PAIRs.
It’s also worth noting that AV_PAIRs can be sent outside of the blob in the CHALLENGE_MESSAGE
sent by the server. Unlike the AUTHENICATE_MESSAGE
, this is not referred to as an “AvPairs” section in the CHALLENGE_MESSAGE
. Instead, the AV_PAIRs in the CHALLENGE_MESSAGE
are sent in the “TargetInfo” field, which the AUTHENTICATE_MESSAGE
does not have. Try not to worry about this.
The AvPairs section is used to transmit client and server information, such as hostnames. It is also where the presence of a MIC can be indicated, and where an SPN for the target server can be provided. Here is each specific AvId
provided in the Microsoft documentation (MS-NLMP):
AvIds
--------
MsvAvEOL - indicates that this is last AV_PAIR in list, val is 0
MsvAvNbComputerName - server's NetBIOS computer name
MsvAvNbDomainName - server's NetBIOS domain name
MsvAvDnsComputerName - client's FQDN of the computer
MsvAvDnsDomainName - FQDN of the domain
MsvAvDnsTreeName - FQDN of the forest
MsvAvFlags - can contain the following info for the client/server:
* 0x01: tells client that their authentication is constrained
* 0x02: tells server to check the MIC
* 0x04: tells server to check SPN in MsvAvTargetName
MsvAvTimestamp - Contains the server local time, sent in CHALLENGE
MsvAvSingleHost - Identifies (I think) the client OS or hardware
MsvAvTargetName - The SPN of the target server.
MsvAvChannelBindings - An MD5 channel bindings hash (RFC4121).
NTLM Compatability Table
NTLM compatability is configured via the LmCompatibilityLevel
registry setting, which can be set to 6 different levels. This setting has different implications depending on whether the host is acting as an NTLM client or as an NTLM server in a particular authentication transaction. For example, a host set to level 5 will only deal in NTLMv2, regardless of whether that host is acting as a client or as a server.
Level | Client Implications | Server Implications |
---|---|---|
0 | Send LMv1 and NTLMv1 challenge responses | Accept LMv1, NTLMv1, LMv2, and NTLMv2 authentication |
1 | Send LMv1 and NTLMv1 challenge responses, and useNTLMv1 Extended Sesssion Security if server supports it | Accept LMv1, NTLMv1, LMv2, and NTLMv2 authentication |
2 | Send NTLMv1 challenge responses only, and useNTLMv1 Extended Sesssion Security if server supports it | Accept LMv1, NTLMv1, LMv2, and NTLMv2 authentication |
3 | Send LMv2 and NTLMv2 challenge responses only, and useNTLMv2 Sesssion Security if server supports it | Accept LMv1, NTLMv1, LMv2, and NTLMv2 authentication |
4 | Send LMv2 and NTLMv2 authentication only, and useNTLMv2 Sesssion Security if server supports it | Accept NTLMv1, LMv2, and NTLMv2 authentication |
5 | Send LMv2 and NTLMv2 authentication, and useNTLMv2 Sesssion Security if server supports it | Accept LMv2 and NTLMv2 authentication only |
Based on this table, the following general conclusions can be drawn about the NTLM negotiation process:
- The client is pre-configured for either NTLMv1 or NTLMv2; it cannot be compatible with both. This can only be changed via the registry and is not negotiated. Within the NTLM version set, however, the client will negotiate the type of challenge response sent.
- The server is pre-configured with whether or not it will accept LMv1 and/or NTLMv1 challenge responses. The server will always accept NTLMv2 if it understands it.
- Lastly, when NTLMv1 is used, Extended Session Security is always negotiated. The client will always request it, but the server can always decline to support it.
Tools & Exploitation
Note: this section is brief, and only barely scratches the surface of NTLM attacks. Please refer to other sources for fuller coverage of NTLM-based attacks, including those linked under references.
Recall that the client only proves its knowledge of the hash, and not of the actual password. Consequently, hashes and passwords are functionally equivalent, and mere possession of the hash is enough to fully authenticate. This results in an NTLM vulnerability called Passing the Hash.
Additionally, NTLM does not implement mutual authentication: clients do not authenticate that the server is legitimate. An attacker can therefore leverage passive network poisoning (e.g. Responder) or coerced authentication (e.g. PetitPotam, WebDAV, ShadowCoerce) to relay NTLM authentication (AUTHENTICATE_MESSAGE
packets) with ntlmrelayx. Relaying authentication is defeated in SMB by SMB Signing, and in LDAP by LDAP Signing and Channel Binding. You still acquire NTLM Challenge Responses from your network poisoning and authentication coercing, however, which you may be able to crack to learn the user’s NT hash or LM hash, which you could also crack to learn the user’s password. For example, NTLMv1 Multi Tool can be used to extract the DES ciphertext from the NTLMv1 challenge response, which is then passed to hashcat for cracking.
As mentioned in the MIC section, there are attacks that can remove the MIC from NTLMv2 AUTHENTICATE_MESSAGE
packets: “Drop the MIC” (CVE-2019-1040) and “Drop the MIC 2” (CVE-2019-1166). This allows an attacker to bypass the restrictions imposed by a MIC, such that an attacker gains the ability to modify NTLMv2 messages when relaying them. These attacks are implemented in ntlmrelayx as optional flags.
References
The best, 10/10 resources for understanding NTLM:
The NTLM Authentication Protocol and Security Support Provider - Glass
Implementing CIFS: Chapter 2, Section 8 “Authentication” - Hertel
Other resources for understanding NTLM:
Attacking AD: NTLM Basics - zer1t0
Supplementary material:
https://en.wikipedia.org/wiki/NTLM
https://www.thehacker.recipes/ad/movement/ntlm/relay
https://www.crowdstrike.com/blog/active-directory-ntlm-attack-security-advisory/
https://github.com/hashcat/hashcat/blob/master/src/modules/module_05600.c