Understanding Password Hashes
Last updated
Last updated
Saving passwords in plaintext is risky. Instead, systems should store a hashed version of the password. Here's how it works: the system hashes the user's password and saves that hash. When the user logs in, the system hashes the entered password and compares it to the saved hash. If they match, the user is authenticated.
Password hashing differs by system and has changed with advances in security and computing speed. This module will explain how password hashing works, including Windows (LANMAN and NT), Linux/UNIX (various algorithms), and how modern systems are improving to protect passwords from attackers.
The first password hash we’ll discuss is LANMAN, an old system used in early Windows NT. Despite being outdated, it’s still found in many modern Windows networks due to keeping old features through updates.
The LANMAN password hashing method is weak and can easily be cracked, even with complex passwords. For instance, the password BuDdy12&
is converted to uppercase BUDDY12&
and padded to 14 bytes with NULL characters. This padded password is split into two 7-byte parts. Each part is used as a DES key to encrypt a fixed string. The two encrypted values are then combined to create the LANMAN hash.
LANMAN hashes are weak because they only use 7-character passwords and don’t preserve case, making them easy to crack. Modern hardware can break these hashes in about 15 minutes. Therefore, LANMAN is outdated, and we'll next look at NT hashes, which replace it.
The NT hash is a better but still imperfect way to store password hashes on Windows. It converts a password to Unicode (if needed), then hashes it with MD4 to create a 16-byte hash, which is saved in the SAM. NT hashes keep case sensitivity and only use NT hashes for passwords longer than 14 characters. Despite being stronger than LANMAN hashes, NT hashes have a drawback: they don’t use salts, making passwords more susceptible to quick recovery.
LANMAN and NT hashes don't use salts, which speeds up attacks (UNIX uses salts). Without salts, identical passwords have identical hashes, so attackers can precompute a dictionary of hashed passwords for quick comparison. NT hashes and NTLM hashes are often mixed up, but NTLM is an authentication method, while NT is the hashing function. Despite this, NT and NTLM are often used interchangeably in tools and documentation.
There are 8 users with their password hashes shown. By looking at these hashes, you can tell some details about the users and their passwords. For example, Cindy and Peter have the same password because their hashes are identical. In this case, like with LANMAN and NT hashes, no salt is used, which makes cracking the passwords easier. Salt adds randomness to the password before hashing, making it harder to crack.
Instead of hashing just the password, a random string called a salt is added to it before hashing. The salt adds extra randomness to the hash. The salt isn’t secret and the user doesn’t need to know or remember it.
In this example, Cindy and Peter's passwords are hashed without salt, creating the same hash. If an attacker gets the hashes, they can see that both have the same password, "Spring1111," because it creates the same hash.
In this example, a random salt is added to each user's password before hashing. Since the salts are different, Cindy and Peter's hashed passwords are unique, making it harder for attackers to guess them. The salt is stored in plain text with the hash so the system can verify the password.
Once attackers gain admin access, they can obtain domain hashes, but it's harder than copying the NTDS.dit file because it's encrypted and locked by the OS. To avoid detection, attackers often use built-in tools. For domain hashes, they prefer the Active Directory tool "ntdsutil," which is designed to manage and back up AD data, making it ideal for collecting password hashes.
To gather the NTDS.dit and SYSTEM registry hive data, we can run ntdsutil
, then issue the activate instance ntds
command, followed by ifm
. This will generate a backup of the data in the C:\ntds directory. An attacker will collect all of the data to a local system for password cracking.
After downloading the NTDS.dit file and SYSTEM registry hive, an attacker needs to decrypt the NTDS.dit data and extract password hashes using the registry keys. A tool for this is the secretsdump.py
script from the Impacket project. On Slingshot Linux, run secretsdump.py
with the -system
option for the SYSTEM hive, the -ntds
option for the NTDS.dit file, and use the LOCAL option.
To get local password hashes from a Windows 10 machine, we can use the Meterpreter hashdump
command. Just open a Meterpreter shell and run the hashdump
command.
We have a small issue with Microsoft’s new password hash protections, which cause the hashdump command to fail. To fix this, we need to move the Meterpreter shell to the lsass.exe process. First, find the lsass.exe process ID (ps -S lsass.exe), then use the migrate command to switch to that process. You can also combine these steps by running migrate -N lsass.exe.
If the migration works, run the hashdump command to get password hashes. However, migration can fail and end your session. If it fails, start a new session, migrate to another SYSTEM process first, then move to lsass.exe
.
Another way to get password hashes from Windows 10 is by using Mimikatz. First, get the contents of the HKLM\sam and HKLM\system registry hives, then use them with Mimikatz.
The tools we reviewed can retrieve Windows password hashes in the format username:userid:LANMAN:NTHASH . In the example, both Bob and Tom have hashes, but Tom's are empty, meaning no password is set. These empty hashes can't be used for attacks, possibly due to Tom's inactive account or a tool error when collecting the data.
The tools we reviewed get password hashes from Windows systems in a format like username:userid:LANMAN:NTHASH. For example, Bob and Tom both have LANMAN and NT hashes.
Tom's LANMAN and NT hash values are not valid, meaning his passwords are not set and can't be used for authentication. This is either because Tom's account is inactive or a tool failed to properly dump the password hashes.
When using password hash dump tools, note that empty LANMAN and NT hashes can indicate disabled accounts or tool issues. Remember this by the phrase "am all day baffled by difficult choices for encrypted data", the first letters of the first five words match the empty LANMAN hash, and the rest match the empty NT hash. Next, we'll explore how password hash storage has improved on UNIX and Linux systems.
Early UNIX and Linux systems stored weak password hashes in the /etc/passwd file using DES encryption, often without salt. Later systems moved password hashes to the /etc/shadow file, which is only accessible by the root user, making it more secure. The /etc/passwd file is still readable by all users.
UNIX and Linux systems have moved from using DES encryption to stronger methods like MD5, Blowfish, SHA-256, and now SHA-512. They also use salt values, starting with 4 bytes and then 8 bytes.
With root access, an attacker can view hashed passwords in the /etc/shadow
file. The hashed password is the second field, separated by colons. This field has three parts separated by dollar signs: the hash type ($1, $2, $5, or $6), the salt, and the actual hashed password.
We can see two entries from different /etc/shadow
files. The first one is for the user sec580
and uses an MD5 hash with an 8-byte salt. The second one is for sec504
and uses a SHA-512 hash. Although it looks like the hash for sec504
is base64-encoded, it's actually a modified version with different characters and no padding.
(no $ indicator)
DES
$1
MD5
$2
Blowfish
$5
SHA-256
$6
SHA-512
UNIX and Linux systems are better than Windows at storing password hashes because they use a salt and multiple hashing rounds.
An attacker tries to guess a password by taking the salt from the /etc/shadow
file, combining it with different guesses, and checking if the result matches the file's hash. They keep guessing until they find the correct password or run out of guesses.
Password cracking is easier for attackers because they can guess quickly. If the password is simple, they might try all possible passwords if given enough time. To make it harder, UNIX and Linux systems use multiple hashing rounds. For example, the attacker would need to hash the password 5,000 times in a row, making the process much slower.
Calculating the hash function 5,000 times is almost instant for a user but slows down attackers significantly. Yet, new tools and cracking methods have made this technique less effective against skilled attackers.