Skip to content

LSA secrets and cached domain credentials

The SECURITY hive stores service passwords, the machine account, DPAPI keys, and offline logon caches. Here is how the LSA key unlocks them — and why DCC2 is salted but still dumpable.

Published on 2 min read
LSA secrets and cached domain credentials

The SECURITY hive is the richest of the three local hives. Beyond password hashes it holds LSA secrets — service account passwords, the machine account password ($MACHINE.ACC), DPAPI system keys, auto-logon credentials — and the cached domain logons that let a laptop authenticate offline.

The LSA key

Everything in SECURITY is encrypted under the LSA key, which is itself encrypted under the boot key. On Vista and later:

encrypted = SECURITY\Policy\PolEKList
tmpKey    = SHA-256(bootKey ‖ encrypted[:32] × 1000)
plain     = AES-CBC(tmpKey, encrypted[32:])
LSAKey    = plain.secret[52:84]

The 1000-round SHA-256 is a small key-stretching step. On pre-Vista systems the key lived in PolSecretEncryptionKey and used an MD5/RC4 construction instead.

LSA secrets

With the LSA key, each secret under Policy\Secrets\<name>\CurrVal decrypts the same way (SHA-256 stretch → AES-CBC). A few names get special handling:

  • $MACHINE.ACC — the machine account password. Its NT hash is simply MD4(secret), which is what you pass-the-hash as DOMAIN\MACHINE$.
  • DPAPI_SYSTEM — the machine and user DPAPI master keys, used to unwrap DPAPI-protected blobs across the system.
  • _SC_<service> — a service's logon password, in cleartext UTF-16.

Cached domain logons (DCC2)

When a domain user logs into a machine that cannot reach a DC, Windows validates against a cached verifier under SECURITY\Cache\NL$<n>. The cache entry is encrypted with a key (NL$KM) that is itself an LSA secret:

NL$KM   = AES/RC4-decrypt(LSAKey, Policy\Secrets\NL$KM\CurrVal)
plain   = AES-CBC(NL$KM[16:32], entry.encrypted, entry.IV)
hash    = plain[:16]                    # the MS-Cache v2 verifier

The recovered verifier is the DCC2 (a.k.a. MS-Cache v2) value, formatted as:

$DCC2$10240#username#<16-byte-hex>

Crucially, DCC2 is not a reversible NT hash — it is PBKDF2(HMAC-SHA1, …) over the NT hash with the username as salt and a high iteration count (default 10240). You cannot pass-the-hash with it, only crack it. That salting is exactly why DCC2 cracking is slow, and why limiting CachedLogonsCount is a meaningful hardening step.

Defensive notes

LSA secrets are the quiet pivot in many intrusions: a single dumped $MACHINE.ACC or service password often unlocks lateral movement. Monitoring access to the SECURITY hive, rotating service accounts (gMSA), and minimising cached logons all reduce the blast radius.

Related articles

From the hashed boot key to a user's NT hash: the F and V structures, the RC4 vs AES storage formats, and the per-RID DES layer that wraps every Windows password hash.
The boot key is the root of all offline credential dumping. Here is where it lives, why it is scrambled across four registry keys, and how to reassemble it from the SYSTEM hive.
A domain controller stores every account hash in an ESE database. Here is how the datatable is laid out, how the Password Encryption Key is derived, and how each hash is unwrapped.