Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

KeyTheft

SAM dump via RemoteRegistry handle theft, outputs XOR-encrypted PNG files with zero regf signature on disk.

What is this?

KeyTheft dumps the Windows SAM database by stealing a registry KEY handle from the RemoteRegistry service's svchost.exe process. The attacking process never opens any SAM registry key. Output files are disguised as PNG images XOR-encrypted with a CSPRNG-generated key, prepended with a valid PNG header. No regf magic bytes ever touch disk.

This technique is distinct from every published SAM dump method:

Technique Primitive Touches lsass? Opens SAM key? regf on disk?
reg save HKLM\SAM NtOpenKey → NtSaveKey No Yes Yes
secretsdump (SAMR) SamrConnect RPC No Yes (via RPC) Yes
Volume Shadow Copy IVssBackupComponents No Yes (file read) Yes
Raw NTFS (\\.\C:) MFT parse No No (but raw volume) Yes
Mimikatz (lsass dump) MiniDumpWriteDump Yes No N/A
KeyTheft NtDuplicateObject → NtSaveKey No No No

How it works

                    ┌─────────────────────┐
                    │   RemoteRegistry    │
                    │   svchost.exe       │
                    │   (SYSTEM, non-PPL) │
                    │                     │
                    │  Handle 0x238 ──────┼──► \REGISTRY\MACHINE\SAM
                    └──────▲──────────────┘       (KEY object)
                           │
              NtDuplicateObject
              (PROCESS_DUP_HANDLE)
                           │
                    ┌──────┴──────────────┐
                    │   KeyTheft.exe      │
                    │   (attacker, admin) │
                    └──────┬──────────────┘
                           │
                      NtSaveKey
                           │
                    ┌──────▼──────────────┐
                    │  .tmp (plaintext)   │──► XOR encrypt ──► sam.png
                    │  (deleted on disk)  │                    (PNG header + ciphertext)
                    └─────────────────────┘

Chain

  1. Start RemoteRegistry a non-PPL service running as SYSTEM inside svchost.exe
  2. RegConnectRegistryW("\\\\localhost", HKLM) loopback RPC connection
  3. RegOpenKeyExW(hRemote, "SAM", KEY_READ) forces the svchost process to call NtOpenKey(\REGISTRY\MACHINE\SAM) internally, creating a KEY handle in its handle table
  4. Enumerate system handles NtQuerySystemInformation(SystemExtendedHandleInformation), filter for Key objects in the svchost PID
  5. NtDuplicateObject steal the SAM KEY handle from svchost into our process (svchost is not PPL, so OpenProcess(PROCESS_DUP_HANDLE) succeeds)
  6. NtSaveKey(stolen_handle, temp_file) dump the entire SAM hive subtree to a .tmp file
  7. DisguiseAsImage read the plaintext hive, XOR encrypt with a 16-byte CSPRNG key (RtlGenRandom), prepend a valid PNG header (8-byte signature + 25-byte IHDR), write as .png, delete the .tmp

Why NtSaveKey works with a stolen handle

NtSaveKey operates in kernel mode. It checks:

  • The handle type is Key ✓
  • The caller has SeBackupPrivilege ✓ (we enable it)

It then walks the entire key subtree in kernel mode, bypassing individual subkey DACLs. The subkeys under SAM\SAM\Domains\Account are SYSTEM-only, but NtSaveKey ignores this, it reads from the Configuration Manager's in-memory hive data, not through the access-check path.

PNG output format

Output files pass file/YARA/EDR signature checks as PNG images:

Offset  Content
──────  ─────────────────────────────────────
0x00    89 50 4E 47 0D 0A 1A 0A          PNG signature (8 bytes)
0x08    00 00 00 0D 49 48 44 52 ...      IHDR chunk — 1×1 RGBA (25 bytes)
0x21    XX XX XX XX XX XX XX XX ...      XOR-encrypted hive data (N bytes)

Properties:

  • Valid PNG magic (89 50 4E 47) file command reports "PNG image data"
  • Valid IHDR chunk with correct CRC passes structural validation
  • No regf bytes anywhere in the file, YARA rules for registry hives won't match
  • XOR key generated by RtlGenRandom (CSPRNG) not stored in the file, only printed to console
  • Without the key, encrypted payload is indistinguishable from random data

Build

# MSVC
cl /W4 /O2 KeyTheft.c advapi32.lib

# MinGW (MSYS2)
gcc -O2 -municode -o KeyTheft.exe KeyTheft.c -ladvapi32

Usage

KeyTheft.exe [sam_output.png] [system_output.png]
SAMVALID

Decoding

Use decode.py to strip the PNG header and XOR decrypt back to standard .hiv format:

python3 decode.py <xor_key_hex> sam.png system.png
KeyTheft Decoder, restore PNG-disguised hive files

[+] sam.png: valid registry hive (regf magic confirmed)
    -> sam.hiv (49,152 bytes)
[+] system.png: valid registry hive (regf magic confirmed)
    -> system.hiv (16,732,160 bytes)

  secretsdump.py -sam sam.hiv -system system.hiv LOCAL

Hash extraction

Extract NTLM hashes with impacket:

secretsdump.py -sam sam.hiv -system system.hiv LOCAL

Or use the included sam_extract.py (standalone, no dependencies):

python3 sam_extract.py system.hiv sam.hiv

Files

File Description
KeyTheft.c Main PoC, handle theft + XOR/PNG output
decode.py Decoder: PNG → .hiv (strips header, XOR decrypts, verifies regf)
sam_extract.py Standalone SAM hash extractor (pure Python, no impacket needed)

Detection

What it generates

Observable Source
RemoteRegistry service started Event Log: System 7036
OpenProcess(svchost, 0x40) Sysmon Event 10 (TargetImage: svchost.exe)
Handle duplication from svchost ETW: Microsoft-Windows-Kernel-Audit-API-Calls
.png file created (benign-looking) Sysmon Event 11 (FileCreate) blends with normal activity
NtSaveKey call ETW: Microsoft-Windows-Kernel-Registry

Why PNG disguise defeats file-based detection

Most EDR and YARA rules for SAM dump artifacts rely on:

  1. File extension (.hiv, .save, .dat) output is .png
  2. regf magic bytes at offset 0, output starts with 89 50 4E 47 (PNG signature)
  3. Registry hive structure patterns, payload is XOR-encrypted, no recognizable structure

The .tmp intermediate file (plaintext hive) exists only in memory-mapped I/O between NtSaveKey and DisguiseAsImage, and is deleted immediately after encryption. Race window is minimal.

Requirements

  • Windows 10 / 11 (tested on Win11 26200)
  • Administrator privileges (for SeDebugPrivilege + SeBackupPrivilege)
  • RemoteRegistry service must be available (installed by default, usually set to Manual start)

Limitations

  • If RemoteRegistry service is disabled (not just stopped), it cannot be started. Some hardened environments disable it via GPO.
  • SeBackupPrivilege is required regardless of handle source, this is checked by NtSaveKey in kernel mode.
  • The technique generates a service start event for RemoteRegistry, which is unusual in environments where this service is normally stopped.

About

No description, website, or topics provided.

Resources

Stars

47 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages