Technical Explanation of Network SMB Capture

Like many computing architectures, Windows passwords reflect not the most technically sophisticated design, but rather their own particular history of design flaws, vulnerability patches and the evolutionary restrictions imposed by serving a large installed-base. In this section, we take apart why it is so feasible to crack the LM hash that protects Windows passwords, and then talk about why the stronger NTLM hash, which was designed as an improvement on the LM hash and released with Windows NT Service Pack 3, is often irrelevant.

-------------------------- -----------------------------
|      16byte LM hash    | |   16byte NTLM hash (md4)  |
-------------------------- -----------------------------

We already know that you only have to go through 7 characters to retrieve passwords (up to 14 chars in length) in the LM hash. Furthermore, since there is no salting being done, constants appear, giving away information that speeds up an attack.

--------------------------------------------------------
|  1st 8bytes of LM hash  |  second 8bytes of LM hash  |
--------------------------------------------------------
    from first 7 chars        from second 7 chars

The first 8 bytes are derived from the first seven characters of the password and the second 8 bytes are derived from the 8th through 14th characters of the password. If the password is less than 7 characters then the second half will always be: 0xAAD3B435B51404EE. Let's assume for this example that the user's password has an LM hash of 0xC23413A8A1E7665f AAD3B435B51404EE (which I'll save everyone the nanosecond it would have taken for them to plug this into LC4 and have it tell them the password is "WELCOME").

Here's what happens to this hash on the network:

B --> A

  1. B sends an 8 byte challenge to A (let's assume it's 0x0001020304050607)
  2. Machine A takes the hash of 0xC23413A8A1E7665fAAD3B435B51404EE and adds 5 nulls to it, thus becoming 0xC23413A8A1E7665fAAD3B435B51404EE0000000000.
  3. The string 0xC23413A8A1E7665fAAD3B435B51404EE0000000000 is broken into three groups of 7:C23413A8A1E766 5fAAD3B435B514 04EE0000000000
  4. The 7 byte strings are str_to_key'd (if you will) into 8 byte odd parity DES keys. Now we have:
  5. | 8byteDESkey1 | | 8byteDESkey2 | | 8 byteDESkey3 |

  6. 8byteDESkey1 is used to encrypt the challenge 0x0001020304050607. Let's assume the result is 0xAAAAAAAAAAAAAAAA.
  7. 8byteDESkey2 is used to encrypt the challenge 0x0001020304050607. Let's assume the result is 0xBBBBBBBBBBBBBBBB.
  8. 8byteDESkey3 is used to encrypt the challenge 0x0001020304050607. Let's assume the result is 0xCCCCCCCCCCCCCCCC.
  9. The three 8byte values are concatenated (dumb!), and the 24 byte response of 0xAAAAAAAABBBBBBBBCCCCCCCC is returned to the server.
  10. The server does the same thing to the hash on it's end and compares the result to the 24 byte response. If they match, it was the correct original hash.
Why this is breakable:

The LM Hash for 7 or fewer character passwords:

-------------------- -------------------- --------------------
|  C23413A8A1E766  | |  5fAAD3B435B514  | |  04EE0000000000  |
-------------------- -------------------- --------------------

The first thing we check is to see if the user's password is shorter than 8 characters, by taking the 7 byte value of 0x04EE0000000000, turning it into an 8 byte odd parity DES key, and encrypting it against the 8 byte challenge of 0x0001020304050607. If we get the result of 0xCCCCCCCCCCCCCCCC then we are pretty sure it's shorter than 8 characters. In order to be sure we can run through 0x??AAD3B435B514 (i.e. just 256 possible combinations) to see that 5f shows us the result is 0xBBBBBBBBBBBBBBBB, proving the password is less than 8 characters and also giving us the last byte of the first half of the LM hash.

What if the test above proves we're dealing with an 8 character or greater password?

-------------------- -------------------- --------------------
|  C23413A8A1E766  | |  AC435F2DD90417  | |  CCD60000000000  |
-------------------- -------------------- --------------------

It takes us, in a worst case scenario, 65,535 checks to figure out that the 2bytes that are used in the last third are 0xCCD6. In a simplistic fashion, you could go through your 7 digit combinations of characters for the first third the same way you would the LM hash from the registry. This will yield not only the first third of the response, but also the first byte of the second third. Keep in mind that you already have the last two bytes that made up the third. You could approach the middle third in the same fashion.

In summary, the challenge response can be brute-forced for the LM hash. Microsoft made the decision to continue sending the LM hash response along with the NTLM response even when NT Service Pack 3 was installed, probably because eliminating the LM hash response would prevent Windows 95 and 98 machines from talking to NT machines. As a result, it is a moot point how secure or well done the NTLM hash might be. The strength of the more secure NTLM hash is made irrelevant by its position in a chain whose weakest link is the LM hash.