I've still had my head pretty deep into cryptography and hashing as far as Windows and Active Directory is concerned, and I figured it was worth putting here in case you're interested. We're going to talk about things like NTLM and how Windows stores hashes, and more.
The term NTLM is a loaded one, as the acronym is often used to refer to several different things. It not only refers to Microsoft’s implementation of another standard algorithm for creating hashes, but it also refers to a network protocol. The NTLM used for storing password hashes on disk (aka NT hash) is a totally different thing than the NTLM used to transmit authentication data across a TCP/IP network. There’s the original LAN Manager protocol, which is worse than NT LAN Manager (NTLM or NTLMv1,) which is worse than NTLMv2, which is worse than NTLMv2 with Session Security and so on… but an NT hash is an NT hash is an NT hash. When we refer to either NTLMv1 or NTLMv2 specifically, we’re not talking about how the password gets stored on disk, we’re talking about network protocols.
Also, this information refers to Vista/2008+ era stuff. I don’t want to delve into the ancient history Windows NT 4 or 2000, so let’s not even discuss LAN Manager/LM. LM hashes are never stored or transmitted, ever, in an environment that consists of Vista/2008+ stuff. It’s extinct.
Unless some bonehead admin purposely turned it back on. In which case, fire him/her.
LOCAL MACHINE STUFF
So here we talk about what goes on in a regular Windows machine with no network connection. No domain. All local stuff. No network.
"SO REALLY, WTF IS AN NT HASH!?"
You might ask. An NT hash is simply the MD4 hash of the little endian UTF-16 encoded plaintext input. So really it’s MD4.
"So the Windows Security Accounts Manager (SAM) stores MD4 hashes of passwords to disk, then?"
Well no, not directly. The NT hashes, before being stored, are encrypted with RC4 using the machine’s "boot key," which is both hard to get at as well as being unique to each OS install. By "hard to get at," I mean that the boot key is scattered across several areas of the registry that require system level access and you have to know how to read data out of the registry that cannot be seen in Regedit, even if you run it as Local System. And it must be de-obfuscated on top of that. After hashing the boot key and other bits of data with MD5, you then create another RC4 key from the MD5 hash of the hashed bootkey, plus some more information such as the specific user's security identifier.
So the final answer is that Windows stores local SAM passwords to disk in the registry as RC4-encrypted MD4 hashes using a key that is unique to every machine and is difficult to extract and descramble, unless you happen to be using one of the dozen or so tools that people have written to automate the process.
Active Directory is a different matter altogether. Active Directory does not store domain user passwords in a local SAM database the same way that a standalone Windows machine stores local user passwords. Active Directory stores those password hashes in a file on disk named NTDS.dit. The only password hash that should be stored in the local SAM of a domain controller is the Directory Services Restore Mode password. The algorithms used to save passwords in NTDS.dit are much different than the algorithms used by standalone Windows machines to store local passwords. Before I tell you what those algorithms are, I want to mention that the algorithms AD uses to store domain password hashes on disk should not be in scope to auditors, because NTDS.dit is not accessible by unauthorized users. The operating system maintains an exclusive lock on it and you cannot access it as long as the operating system is running. Because of that, the online Directory Services Engine and NTDS.dit together should be treated as one self-contained ‘cryptographic module’ and as such falls under the FIPS 140-2 clause:
"Cryptographic keys stored within a cryptographic module shall be stored either in plaintext form or encrypted form. Plaintext secret and private keys shall not be accessible from outside the cryptographic module to unauthorized operators…"
So even plaintext secrets are acceptable to FIPS 140, as long as they stay within the cryptographic module and cannot be accessed by or sent to outsiders.
Active Directory stores not only the hashed password of domain users, but also their password history. This is useful for that “Remember the last 24 passwords” Group Policy setting. So there are encrypted NT hashes stored in NTDS.dit. Let’s just assume we have an offline NTDS.dit – again, this should not be of any concern to auditors – this is Microsoft proprietary information and was obtained through reverse engineering. It’s only internal to AD. FIPS should not be concerned with this because this all takes place "within the cryptographic module." Access to offline copies of NTDS.dit should be governed by how you protect your backups.
To decrypt a hash in NTDS.dit, first you need to decrypt the Password Encryption Key (PEK) which is itself encrypted and stored in NTDS.dit. The PEK is the same across all domain controllers, but it is encrypted using the boot key (yes the same one discussed earlier) which is unique on every domain controller. So once you have recovered the bootkey of a domain controller (which probably means you have already completely owned that domain controller and thus the entire domain so I'm not sure why you'd even be doing this) you can decrypt the PEK contained inside of an offline copy of NTDS.dit that came from that same domain controller. To do that, you hash the bootkey 1000 times with MD5 and then use that result as the key to the RC4 cipher. The only point to a thousand rounds of hashing is to make a brute force attack more time consuming.
OK, so now you’ve decrypted the PEK. So use that decrypted PEK, plus 16 bytes of the encrypted hash itself as key material for another round of RC4. Finally, use the SID of the user whose hash you are trying to decrypt as the key to a final round of DES to uncover, at last, the NT (MD4) hash for that user.
Now you need to brute-force attack that hash. Using the program ighashgpu.exe, which uses CUDA to enable all 1344 processing cores on my GeForce GTX 670 graphics card to make brute force attempts on one hash in parallel, I can perform over 4 billion attempts per second to eventually arrive at the original plaintext password of the user. It doesn’t take long to crack an NT hash any more.
As a side-note, so-called "cached credentials" are actually nothing more than password verifiers. They’re essentially a hash of a hash, and there is no reversible information contained in a "cached credential" or any information that is of any interest to an attacker. "Cached credentials" pose no security concern, yet most security firms, out of ignorance, still insist that they be disabled.
So there you have it. You might notice that nowhere in Windows local password storage or Active Directory password storage was the acronym SHA ever used. There is no SHA usage anywhere in the above processes, at all.
Now passing authentication material across the network is an entirely different situation!
I’ll start with the bad news. Remember earlier when I talked about brute-forcing the decrypted NT hash of another user? Well that last step is often not even necessary. NT hashes are password-equivalent, meaning that if I give Windows your hash, it’s as good as giving Windows your password in certain scenarios. I don’t even need to know what your actual password is. This is the pass-the-hash attack that you might have heard of. But it’s not as bad as it sounds.
The good news is that neither Windows nor Active Directory ever sends your bare NT hash over the wire during network transmission. And you cannot begin a pass-the-hash attack until you’ve already taken over administrative control of some domain joined machine. That means there is no such thing as using pass-the-hash to own an entire networked AD environment just from an anonymous observer sniffing network packets. That’s not how it works. (Fun video on PtH)
Now that we know what an NT hash is, it’s a good time to draw the distinction that whenever we talk about specifically NTLMv1 and NTLMv2, we’re not actually talking about NT hashes anymore. We’re talking about network communication protocols. The whole mess is often just called NTLM as a blanket term because it’s all implemented by Microsoft products and it’s all interrelated.
Both NTLMv1 and NTLMv2 are challenge-response protocols, where Client and Server challenge and respond with each other such that Server can prove that Client knows what his/her password is, without ever actually sending the password or its hash directly over the network. This is because Server already knows Client’s password (hash), either because it’s stored in the local SAM in the case of local Windows accounts, or because Server can forward Client’s data to a domain controller, and the domain controller can verify and respond to Server with “Yep, that’s his password, alright.”
With NTLMv1, you’ll see some usage of DES during network communication.
With NTLMv2, you’ll see some usage of HMAC-MD5.
There’s also NTLM2 Session, aka NTLMv2 With Session Security, but it uses the same encryption and hashing algorithms as NTLMv2.
It is possible to completely remove the usage of NTLM network protocols from an Active Directory domain and go pure Kerberos, but it will break many applications. Here is a fantastic article written by one of my favorite Microsoft employees about doing just that.
So let’s assume that hypothetically we blocked all usage of NTLM network protocols and went pure Kerberos. Kerberos in AD supports only the following encryption:
DES_CBC_CRC (Disabled by default as of Win7/2008R2)[Source]
DES_CBC_MD5 (Disabled by default as of Win7/2008R2)
RC4_HMAC_MD5 (Disabled by default as of Win7/2008R2)
Future encryption types
Of course, there are plenty of other Windows applications that pass authentication traffic over the network besides just AD. Remote Desktop is a great example. Remote Desktop traditionally uses RC4, but modern versions of Remote Desktop will negotiate a Transport Layer Security (TLS) connection wherever possible. (Also known as Network Level Authentication (NLA).) This is great news because this TLS connection uses the computer’s digital certificate, and that certificate can be automatically created and assigned to the computer by an Enterprise Certificate Authority, and that certificate can be capable of SHA256, SHA384, etc. However the Certificate Authority administrator defines it.
If you turn on FIPS mode, Remote Desktop can only use TLS 1.0 (as opposed to SSL) when NLA is negotiated, and it can only use 3DES_CBC instead of RC4 when TLS is not negotiated.
Other ciphers that are turned off when FIPS mode is turned on include:
That will apply to all applications running on Windows that rely upon Schannel.dll. The application will crash if it calls upon one of the above ciphers when FIPS mode is enabled.
So anyway, that’s about all I got right now. If you made it to the bottom of this post I should probably buy you a drink!