Skip to content

What an NTLM hash actually is

NTLM is the MD4 of a UTF-16LE password: unsalted, fast, password-equivalent. How it differs from NetNTLMv2, where it lives, and why length is the only defence.

Published on 5 min read

The word "NTLM" gets thrown at three different things that behave nothing alike, and the confusion gets people stuck for hours. Let us pin down what the actual hash is before anything else.

NTLM is MD4 of the password, full stop

An NTLM hash is computed by taking the user's password, encoding it as UTF-16 little-endian, and running it through MD4 once. That is the whole algorithm. No salt. No iteration count. No work factor. The output is 32 hex characters.

Read that again, because every consequence flows from it. There is no salt, so two users with the same password have the identical hash, and precomputed lookups work. There is no iteration, so it is blisteringly fast on a GPU, comparable to raw MD5 throughput in the tens of billions per second. And it is computed directly from the password with nothing else mixed in, which makes it password-equivalent: possessing the hash is operationally as good as possessing the password for Windows authentication. That last property is the one that matters most, and we will come back to it.

NetNTLMv1/v2 is a completely different thing

Here is the trap. NetNTLMv1 and NetNTLMv2 are not the stored hash. They are challenge-response authentication blobs exchanged over the network during an SMB or HTTP negotiation. The server sends a challenge, the client combines it with a keyed function of the NTLM hash, and the response goes back. What you capture off the wire with Responder or an SMB relay is this response, not the NTLM hash itself.

The practical differences are total. A NetNTLMv2 blob includes a server challenge, a client challenge, and timestamps, so it is long and clearly not 32 hex. You cannot pass-the-hash with a captured NetNTLMv2; you can only try to crack it offline to recover the password, then use that. Cracking it is also slower because of the keyed construction. People constantly say "I dumped some NTLM hashes" when they mean they captured NetNTLMv2 responses, and then they wonder why -m 1000 rejects the input. Different format, different mode, different attack.

The stored NTLM hash is -m 1000. NetNTLMv2 is -m 5600. NetNTLMv1 is -m 5500. Keep them straight.

Where stored NTLM hashes live

On a standalone Windows box, NTLM hashes sit in the SAM hive, protected by the SYSKEY/bootkey. On a domain controller they live in NTDS.dit, the Active Directory database, one entry per domain account. And at runtime they can be pulled from the memory of the LSASS process, which is what tools like Mimikatz and the sekurlsa family target.

Each location implies a different access requirement. SAM means local admin on a workstation. NTDS.dit means domain controller compromise or a DCSync right. LSASS means code execution as SYSTEM on a live host. Knowing which source a hash came from tells you both how it was obtained and what you can do with it next.

A 32-hex string tells you nothing on its own

NTLM is 32 hex characters. So is MD5. So is an MD4 digest of anything. You cannot tell them apart by looking. This is the canonical case where format detection by shape fails and you must disambiguate by source.

If the value came out of secretsdump.py against a DC, or out of an LSASS dump, it is NTLM and you crack it with -m 1000. If it came out of a web app database column, it is far more likely MD5 at -m 0. Same 32 characters, different mode, and feeding NTLM to -m 0 simply will not crack. When you are unsure, walk through how to find the right hashcat mode and lean on provenance over appearance.

Pass-the-hash: why the hash is the prize

Because NTLM is password-equivalent, you often do not need to crack it at all. The NTLM authentication protocol proves knowledge of the hash, not the plaintext, so you can authenticate by presenting the hash directly. That is pass-the-hash, and it is why a dumped NTLM hash is a credential in its own right. Crack it only when you want the plaintext for reuse elsewhere or to satisfy a password-complexity narrative in the report.

LM is the legacy ghost

Older systems also stored an LM hash alongside NTLM. LM is even weaker: it uppercases the password, pads to 14 characters, splits into two 7-byte halves, and DES-encrypts each independently. Those two halves crack near-instantly with -m 3000, and recovering both gives you the uppercased password, from which the true-case version is a short hop. LM should be disabled everywhere by now, but NoLMHash is not universally set on legacy estates, so you still find it. If you see an aad3b435... half in a dump, that is the empty-LM sentinel telling you LM storage was off for that account.

What defenders should do

You cannot salt NTLM and you cannot slow it down. The protocol is what it is, and Microsoft is only now phasing it out. So the entire defensive burden falls on password length. Unsalted plus fast means a weak password is recovered in seconds and a reused one cracks every account that shares it. A 9-character password is gone; a long passphrase pushes brute force past feasibility even at NTLM's GPU speeds.

Enforce long minimums, kill LM storage with NoLMHash, protect LSASS with Credential Guard, monitor for DCSync, and move toward Kerberos and the deprecation of NTLM where your estate allows. The hash itself will never be strong. Your only lever is making the input too big to guess.

Related articles

Why an NTLM hash is password-equivalent, how pass-the-hash works with Impacket, NetExec and Mimikatz, and the controls that actually stop lateral movement.
How AS-REP roasting lets an unauthenticated attacker pull a crackable krb5asrep hash from accounts with preauth disabled, and how defenders catch it.
Poison LLMNR and NBT-NS with Responder to capture a NetNTLMv2 challenge response, crack it with hashcat mode 5600, and know when to relay instead.