Copyright © 2003 Eric Glass
Permission to use, copy, modify, and distribute this document for any purpose and without any fee is hereby granted, provided that the above copyright notice and this list of conditions appear in all copies.
The most current version of this document may be obtained from http://davenport.sourceforge.net/ntlm.html.
Abstract
This article seeks to describe NTLM at an intermediate to advanced level of detail, suitable as a reference for implementors. It is hoped that this document will evolve into a comprehensive description of NTLM; at this time there are omissions, both in the author's knowledge and in his documentation, and almost certainly inaccuracies. However, this document should at least be able to provide a solid foundation for further research. The information presented herein was used as the basis for the implementation of NTLM in the open-source jCIFS library, available at http://jcifs.samba.org.
What is NTLM?
NTLM is an authentication protocol used in various Microsoft network protocol implementations and supported by the NTLM Security Support Provider ("NTLMSSP"). Originally used for authentication and negotiation of secure DCE/RPC, NTLM is also used throughout Microsoft's systems as an integrated single sign-on mechanism.
NTLM employs a challenge-response mechanism for authentication, in which clients are able to prove their identities without sending a password to the server. It consists of three messages, commonly referred to as Type 1 (negotiation), Type 2 (challenge) and Type 3 (authentication). It basically works like this:
- The client sends a Type 1 message to the server. This primarily contains a list of features supported by the client and requested of the server.
- The server responds with a Type 2 message. This contains a list of features supported and agreed upon by the server. Most importantly, however, it contains a challenge generated by the server.
- The client replies to the challenge with a Type 3 message. This contains several pieces of information about the client, including the domain and username of the client user. It also contains one or more responses to the Type 2 challenge.
The responses in the Type 3 message are the most critical piece, as they prove to the server that the client user has knowledge of the account password.
Local Authentication" section.
The target information is a security buffer containing a Target Information block, which is used in calculating the NTLMv2 response (discussed later). This is composed of a sequence of subblocks, each consisting of:
Field | Content | Description | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
Type | short | Indicates the type of data in this subblock:
|
||||||||
Length | short | Length in bytes of this subblock's content field | ||||||||
Content | Unicode string | Content as indicated by the type field. Always sent in Unicode, even when OEM is indicated by the message flags. |
The sequence is terminated by a terminator subblock; this is a subblock of type "0", of zero length. Subblocks of type "5" have also been encountered, apparently containing the "parent" DNS domain for servers in subdomains; it may be that there are other as-yet-unidentified subblock types as well.
The context and target information may be omitted, in which case the data block begins at offset 32 (immediately following the challenge). A minimal Type 2 message would look something like this:
4e544c4d53535000020000000000000000000000020200000123456789abcdef
This message contains the NTLMSSP signature, the NTLM message type, an empty target name, minimal flags (Negotiate NTLM and Negotiate OEM), and the challenge.
datagram-style authentication, however.
The LM/LMv2 and NTLM/NTLMv2 responses are security buffers containing replies created from the user's password in response to the Type 2 challenge; the process for generating these responses is outlined in the next section.
The domain name is a security buffer containing the authentication realm in which the authenticating account has membership. This is either Unicode or OEM, depending on the negotiated encoding.
The user name is a security buffer containing the authenticating account name. This is either Unicode or OEM, depending on the negotiated encoding.
The workstation name is a security buffer containing the client workstation's name. This is either Unicode or OEM, depending on the negotiated encoding.
The session key value is largely unknown, and is often empty when included; it is apparently relevant in newer signing and sealing mechanisms. The Open Group documentation states that it additionally plays a role in datagram-style authentication.
When "Negotiate Local Call" has been established in the Type 2 message, the security buffers in the Type 3 message are typically all empty (zero length). The client "adopts" the SSPI context sent in the Type 2 message, effectively circumventing the need to calculate an appropriate response.
Implementing CIFS, especially the section on authentication.The LM Response
The LM response is sent by most clients. This scheme is older than the NTLM response, and less secure. While newer clients support the NTLM response, they typically send both responses for compatibility with legacy servers; hence, the security flaws present in the LM response are still exhibited in many clients supporting the NTLM response.
The LM response is calculated as follows (see
Appendix A for a sample implementation in Java):
- The user's password (as an OEM string) is converted to uppercase.
- This password is either null-padded or truncated to 14 bytes.
- This "fixed" password is split into two 7-byte halves.
- These values are used to create two DES keys (one from each 7-byte half).
- Each of these keys is used to DES-encrypt the constant ASCII string "KGS!@#$%" (resulting in two 8-byte ciphertext values).
- These two ciphertext values are concatenated to form a 16-byte value - the LM hash.
- The 16-byte LM hash is null-padded to 21 bytes.
- This value is split into three 7-byte thirds.
- These values are used to create three DES keys (one from each 7-byte third).
- Each of these keys is used to DES-encrypt the challenge from the Type 2 message (resulting in three 8-byte ciphertext values).
- These three ciphertext values are concatenated to form a 24-byte value. This is the LM response.
This process is best illustrated with a detailed example. Consider a user with the password "SecREt01", responding to the Type 2 challenge "0x0123456789abcdef".
- The password (as an OEM string) is converted to uppercase, giving "SECRET01" (or "0x5345435245543031" in hexadecimal).
- This password is null-padded to 14 bytes, giving "0x5345435245543031000000000000".
- This value is split into two 7-byte halves, "0x53454352455430" and "0x31000000000000".
- These two values are used to create two DES keys. A DES key is 8 bytes long; each byte contains seven bits of key material and one odd-parity bit (the parity bit may or may not be checked, depending on the underlying DES implementation). Our first 7-byte value, "0x53454352455430", would be represented in binary as:
01010011 01000101 01000011 01010010 01000101 01010100 00110000
A non-parity-adjusted DES key for this value would be:
01010010 10100010 01010000 01101010 00100100 00101010 01010000 01100000
(the parity bits are shown in red above). This is "0x52a2506a242a5060" in hexadecimal. Applying odd-parity to ensure that the total number of set bits in each octet is odd gives:
01010010 10100010 01010001 01101011 00100101 00101010 01010001 01100001
This is the first DES key ("0x52a2516b252a5161" in hex). We then apply the same process to our second 7-byte value, "0x31000000000000", represented in binary as:
00110001 00000000 00000000 00000000 00000000 00000000 00000000
Creating a non-parity-adjusted DES key gives:
00110000 10000000 00000000 00000000 00000000 00000000 00000000 00000000
("0x3080000000000000" in hexadecimal). Adjusting the parity bits gives:
00110001 10000000 00000001 00000001 00000001 00000001 00000001 00000001
This is our second DES key, "0x3180010101010101" in hexadecimal. Note that if our particular DES implementation does not enforce parity (many do not), the parity-adjustment steps can be skipped; the non-parity-adjusted values would then be used as the DES keys. In any case, the parity bits will not affect the encryption process.
- Each of our keys is used to DES-encrypt the constant ASCII string "KGS!@#$%" ("0x4b47532140232425" in hex). This gives us "0xff3750bcc2b22412" (using the first key) and "0xc2265b23734e0dac" (using the second).
- These ciphertext values are concatenated to form our 16-byte LM hash - "0xff3750bcc2b22412c2265b23734e0dac".
- This is null-padded to 21 bytes, giving "0xff3750bcc2b22412c2265b23734e0dac0000000000".
- This value is split into three 7-byte thirds, "0xff3750bcc2b224", "0x12c2265b23734e" and "0x0dac0000000000".
- These three values are used to create three DES keys. Using the process outlined previously, our first value:
11111111 00110111 01010000 10111100 11000010 10110010 00100100
Gives us the parity-adjusted DES key:
11111110 10011011 11010101 00010110 11001101 00010101 11001000 01001001
("0xfe9bd516cd15c849" in hexadecimal). The second value:
00010010 11000010 00100110 01011011 00100011 01110011 01001110
Results in the key:
00010011 01100001 10001001 11001011 10110011 00011010 11001101 10011101
("0x136189cbb31acd9d"). Finally, the third value:
00001101 10101100 00000000 00000000 00000000 00000000 00000000
Gives us:
00001101 11010110 00000001 00000001 00000001 00000001 00000001 00000001
This is the third DES key ("0x0dd6010101010101").
- Each of the three keys is used to DES-encrypt the challenge from the Type 2 message (in our example, "0x0123456789abcdef"). This gives the results "0xc337cd5cbd44fc97" (using the first key), "0x82a667af6d427c6d" (using the second) and "0xe67c20c2d3e77c56" (using the third).
- These three ciphertext values are concatenated to form the 24-byte LM response:
0xc337cd5cbd44fc9782a667af6d427c6de67c20c2d3e77c56
There are several weaknesses in this algorithm which make it susceptible to attack. While these are covered in detail in the Hertel text, the most prominent problems are:
- Passwords are converted to upper case before calculating the response. This significantly reduces the set of possible passwords that must be tested in a brute-force attack.
- If the password is seven or fewer characters, the second value from step 3 above will be 7 null bytes. This effectively compromises half of the LM hash (as it will always be the ciphertext of "KGS!@#$%" encrypted with the DES key "0x0101010101010101" - the constant "0xaad3b435b51404ee"). This in turn compromises the three DES keys used to produce the response; the entire third key and all but one byte of the second will be known constant values.
The NTLM Response
The NTLM response is sent by newer clients. This scheme addresses some of the flaws in the LM response; however, it is still considered fairly weak. Additionally, the NTLM response is nearly always sent in conjunction with the LM response. The weaknesses in that algorithm can be exploited to obtain the case-insensitive password, and trial-and-error used to find the case-sensitive password employed by the NTLM response.
The NTLM response is calculated as follows (see
Appendix A for a sample Java implementation):
- The MD4 message-digest algorithm (described in RFC 1320) is applied to the Unicode mixed-case password. This results in a 16-byte value - the NTLM hash.
- The 16-byte NTLM hash is null-padded to 21 bytes.
- This value is split into three 7-byte thirds.
- These values are used to create three DES keys (one from each 7-byte third).
- Each of these keys is used to DES-encrypt the challenge from the Type 2 message (resulting in three 8-byte ciphertext values).
- These three ciphertext values are concatenated to form a 24-byte value. This is the NTLM response.
Note that only the calculation of the hash value differs from the LM scheme; the response calculation is the same. To illustrate this process, we will apply it to our previous example (a user with the password "SecREt01", responding to the Type 2 challenge "0x0123456789abcdef").
- The Unicode mixed-case password is "0x53006500630052004500740030003100" in hexadecimal; the MD4 hash of this value is calculated, giving "0xcd06ca7c7e10c99b1d33b7485a2ed808". This is the NTLM hash.
- This is null-padded to 21 bytes, giving "0xcd06ca7c7e10c99b1d33b7485a2ed8080000000000".
- This value is split into three 7-byte thirds, "0xcd06ca7c7e10c9", "0x9b1d33b7485a2e" and "0xd8080000000000".
- These three values are used to create three DES keys. Our first value:
11001101 00000110 11001010 01111100 01111110 00010000 11001001
Results in the parity-adjusted key:
11001101 10000011 10110011 01001111 11000111 11110001 01000011 10010010
("0xcd83b34fc7f14392" in hexadecimal). The second value:
10011011 00011101 00110011 10110111 01001000 01011010 00101110
Gives the key:
10011011 10001111 01001100 01110110 01110101 01000011 01101000 01011101
("0x9b8f4c767543685d"). Our third value:
11011000 00001000 00000000 00000000 00000000 00000000 00000000
Yields our third key:
11011001 00000100 00000001 00000001 00000001 00000001 00000001 00000001
("0xd904010101010101" in hexadecimal).
- Each of the three keys is used to DES-encrypt the challenge from the Type 2 message ("0x0123456789abcdef"). This yields the results "0x25a98c1c31e81847" (using our first key), "0x466b29b2df4680f3" (using the second) and "0x9958fb8c213a9cc6" (using the third key).
- These three ciphertext values are concatenated to form the 24-byte NTLM response:
0x25a98c1c31e81847466b29b2df4680f39958fb8c213a9cc6
The NTLMv2 Response
NTLM version 2 ("NTLMv2") was concocted to address the security issues present in NTLM. While its effectiveness in this regard is questionable, it does at least provide a more secure replacement for the LM response. When NTLMv2 is enabled, the NTLM response is replaced with the NTLMv2 response, and the LM response is replaced with the LMv2 response (which we will discuss next).
The NTLMv2 response is c