BindView Security Advisory: Vulnerability in Windows NT's SYSKEY feature
BindView Security Advisory: Vulnerability in Windows NT's SYSKEY feature
BindView Security Advisory
--------
Windows NT's SYSKEY feature
Issue date: December 16, 1999
Contact: Todd Sabin <tsabin@bos.bindview.com>
Topic:
Vulnerability in Windows NT's SYSKEY encryption
Overview:
SYSKEY does not fully protect the SAM from off-line attacks.
Specifically, dictionary and brute-force password cracking are still
possible, even when SYSKEY is enabled and the attacker is not in
possession of the SystemKey.
Affected Systems:
All Windows NT 4.0 machines and pre-RC3 W2K machines with SYSKEY
enabled.
Details:
SYSKEY is an optional Windows NT feature that was added in NT4.0 SP3.
It adds further encryption to the password hashes in the SAM database.
This encryption is meant to protect the SAM from 'off-line' attacks,
where an attacker has gotten a copy of the SAM (e.g., by stealing a
backup tape, repair disk, or the entire machine), but does not have
the System Key. Without SYSKEY enabled, such an attacker would be
able to directly recover all of the password hashes, and could then
use them to authenticate on the network, or brute force them to obtain
the plaintext passwords. Tools are currently available to do this.
SYSKEY is supposed to defend against these attacks, but we have
discovered that, due to implementation flaws, it falls well short.
Effects of SYSKEY on registry:
How does SYSKEY change what is stored in the SAM? Let's look at an
example. Here's a (partial) hex dump of the registry value
This is part of the SAM entry for the Administrator account on a test
machine. The password hashes start at offset 0x20c. The first 16
bytes are the LMHash, the next 16 bytes are the NTHash, and the bytes
after that are the hashes of the password history (including the
current password), for both the NTHash and LMHash values. Actually,
these are the obfuscated password hashes, although that's unimportant
at this point. The data is roughly the real password hashes DES
encrypted with the user's RID as the key. Code to undo the
obfuscation can be found in pwdump.
So, assuming all we have is the encrypted, obfuscated password hashes,
what can we do? The more binary inclined may already see the punch
line coming. It turns out that the hashes are encrypted with the same
rc4 keystream, and consequently, that simply xoring them together
will remove the encryption, and leave you with the xor of the
obfuscated LM and NT hashes:
Some work with a disassembler reveals the complete details of the
encryption. For each user, the system uses a different key, which is
computed by taking the MD5 sum of the global 128-bit encryption key
(aka the password encryption key) concatenated with the user's 4-byte
RID. However, this key is then used to rc4-encrypt the user's
obfusc. LMHash, NTHash, and two password histories, all independently,
using the same keystream.
Attack:
Due to this flawed implementation, it is possible to conduct
dictionary and brute force attacks against a SYSKEY protected SAM. An
initial attack would be as follows:
For each candidate password {
Compute LMHash(password) and NTHash(passwd)
Obfuscate the hashes as they are stored in the registry
Xor the two results
Compare with the xor of the SYSKEY encrypted versions of same
if they match, we've found the password.
}
Note that since the above calculation involves the user's RID, the
attack must be done for one user at a time. However, this attack
can be improved upon by taking a closer look at the details.
Starting from the beginning, we know this:
NTHash is MD4 of the user's unicode password. LMHash is the DES
encryption of "KGS!@#$%", using the password as the key. Since DES
keys are only 56 bits, the password is broken into two 7 byte halves,
then each half is used as a key. This leaves us with two 128 bit
hashes, NTHash, and LMHash.
When stored in the registry, the hashes are further obfuscated by DES
encrypting them, using a function of the user's RID as a key. Again,
since the hashes are 128 bits, there are two DES encryptions done.
The two halves are actually encrypted using different DES keys, but
they're both functions of the RID. For details on this encryption,
see Jeremy Allison's pwdump.
where k1 and k2 are known functions of the user's RID.
Now, with syskey, there's a layer of rc4 encryption on top of that.
Fortunately (for attackers), it reuses the keystream. So, stored in
the registry is:
Now, if we assume for the moment that the passwords are <= 7
characters, then we can proceed as follows:
since the LMHash is computed in halves, the second half will be fixed
and known to us. Therefore, we can go through every user in the SAM
and compute
des(k2,2nd half lmhash), take that, xor it with
des(k2,2nd half lmhash) ^ des(k2,2nd half nthash) to get
des(k2,2nd half nthash), then take that, and decrypt it with k2
to get 2nd half nthash. We can then look that up in our dictionary.
If we find a match, we can then verify that we have the correct
password as in the first attack above. Since we've removed the user's
RID through the above operations, we can conduct our attack against
all users at once, for passwords which are <= 7 characters.
Furthermore, we can precompute the dictionary; it will be good against
all users on all machines.
What about passwords that are longer than 7 characters? Taking 8
character passwords as an example, we can still precompute a
dictionary of NTHashes of 8 char passwords, and keep it sorted by the
eighth character. Or perhaps think of it as 256 (or less if you're
narrowing the search space) separate dictionaries. One for each 8th
char. Now you can go through all users and try each of the 256
dictionaries, again computing the known 2nd half of lmhash and going
from there. So we've reduced the strength of 8 char passwords to the
strength of 1 char passwords modulo lots of space, and perhaps a large
constant. This can be extended to longer passwords as well.
Note that it's also possible to attack the password histories, using
the same technique.
Recommendations:
Follow Microsoft's instructions for installing the hotfix if you've
enabled SYSKEY.
Keep your backup tapes and repair disks safe, even if you've enabled
SYSKEY.