heeeyaaaa/vmem-decrypt
GitHub: heeeyaaaa/vmem-decrypt
该工具通过逆向 VMware 的 encobj 加密结构,仅需虚拟机密码即可离线解密 vTPM 加密的内存与快照文件,并将其转换为 Volatility 可直接分析的取证镜像。
Stars: 0 | Forks: 0
# vmem-decrypt
解密 **VMware Workstation / Fusion** 虚拟机的加密数据文件 -
`.vmem`(保存的内存)、`.vmsn` / `.vmss`(快照 / 挂起状态)以及 `.nvram` - 仅需使用虚拟机的 **密码**。
VMware 会强制对配置了 **vTPM** 的 **Windows 11** 客户机进行“部分”虚拟机加密,这
同时也会加密内存/快照文件。这使得这些文件在解密之前无法用于内存取证(如
Volatility 等)。该工具使用纯 Python 复现了 VMware 的 `encobj`
解密过程,因此你无需依赖 ESXi 或 VMware 的内部工具即可完成
解密步骤。
**测试环境:** VMware® Workstation Pro **26H1**,客户机 Windows 11 **25H2** (build 26100),
使用 Volatility 3 (2.28) 进行分析。其中的 encobj 解密以及 block/LZ 容器结构是针对该版本的 `vmware-vmx` 进行逆向工程的;差异较大的 VMware 版本 *可能*
会使用不同的 checkpoint 格式(如果遇到不支持的情况,工具会明显报错,而不会静默输出乱码,因此你可以放心使用)。
## VMware 如何加密这些文件
```
STAGE 1 (password recovery) STAGE 2 (this tool)
.vmx ──VM-Password-Extractor──▶ $vmx$ hash ──hashcat──▶ password ─┐
▼
password ─PBKDF2-HMAC-SHA1(salt,10000)─▶ KEK
KEK[:32] ─AES-256-CBC─▶ keySafe dict ─▶ config_key (64 B)
config_key[:32] ─AES-256-CBC─▶ encryption.data ─▶ dataFileKey (64 B)
dataFileKey[:32] = AES-256-CBC key for .vmem/.vmsn/.vmss/.nvram
```
VMware 将每个密钥都标记为 `XTS-AES-256`,但实际上它仅将 **前 256 位用作
AES-256-CBC 密钥** - 这 **并不是** 真正的 XTS。(真正的 XTS 无法解密这些文件;这坑了绝大多数尝试解密的人。)
### encobj 数据文件布局(`magic 0x8943dd9e`,小端序)
```
[0x000 .. 0x1000) 4096-byte plaintext header
u32 magic @0x00 = 0x8943dd9e
u32 version @0x04 (1 = vmsn, 2 = vmem)
u32 data_per_page @0x08 = 4064
u32 iv_size @0x0c = 16
u32 mac_size @0x10 = 16
u64 logical_size @0x18 (trim the decrypted output to this)
[0x1000 .. EOF) 4096-byte on-disk pages, each:
[ ciphertext : 4064 ][ IV : 16 ][ MAC : 16 ]
plaintext = AES-256-CBC( ciphertext, key = dataFileKey[:32], iv = the page's IV )
```
## 安装
```
git clone https://github.com/heeeyaaaa/vmem-decrypt
cd vmem-decrypt
pip install -r requirements.txt # just: cryptography
```
## 使用说明
### 阶段 1 - 恢复密码(使用独立工具)
`.vmx` 文件中保存的是 PBKDF2 验证器,而不是密钥。将其提取为可破解的哈希值,然后进行暴力破解或字典破解:
```
# 从 .vmx 中提取 hash (https://github.com/archidote/VM-Password-Extractor)
python3 VM-Password-Extractor.py --vmx VM.vmx --vmx-password-hash-to-hashcat
# -> $vmx$0$10000$$
# 使用 hashcat 进行破解 (VMware VMX = mode 27400)
hashcat -m 27400 hash.txt /usr/share/wordlists/rockyou.txt
```
(John the Ripper 同样适用;它使用了相同的 `$vmx$…` 哈希作为其 VMware 格式。)
### 阶段 2 - 解密(使用本工具)
```
# 直接从 .vmx 和恢复的密码进行解密
python3 vmem_decrypt.py VM-Snapshot1.vmsn VM-Snapshot1.dec.vmsn --vmx VM.vmx --password 'P@ssw0rd'
python3 vmem_decrypt.py VM-Snapshot1.vmem VM-Snapshot1.dec.vmem --vmx VM.vmx --password 'P@ssw0rd'
# 或者恢复一次 key 并重复使用
python3 vmem_decrypt.py --vmx VM.vmx --password 'P@ssw0rd' --print-key
python3 vmem_decrypt.py VM.vmem VM.dec.vmem --key 151bcbc1...981f85
# 在未解密的情况下检查文件结构
python3 vmem_inspect.py VM-Snapshot1.vmem
```
**验证是否成功:** 成功解密的 `.vmsn`/`.vmss` 会以 VMware 快照的
magic 值开头(`0xbed2bed2`,或者是 `0xbed2bed0` / `0xbad1bad1` / `0xbed3bed3`),随后是 `u32`
组数以及 ASCII 组名(`Checkpoint`、`ConfigParams`、`memory`、`cpu` 等)。
## 获取适配 Volatility 的镜像
对于 `.vmsn` / `.vmss` / `.nvram`:解密后的文件已经是 VMware 的原生格式,
可以直接使用。
对于 `.vmem`:VMware **先压缩后加密**,因此解密后的 `.vmem` 仍然是 VMware 的
压缩 checkpoint 格式。使用 `vmem_flatten.py` 对其进行解压展开,然后将结果
连同 **解密后的 `.vmsn`** 一起传给 Volatility:
```
# expand -- 重要:将输出命名为 .vmem(不要命名为 .raw)
python3 vmem_flatten.py VM-Snapshot1.dec.vmem out.vmem
# 将解密后的 .vmsn 放在它旁边并使用相同的基本名称,然后在 .vmem 上运行 vol:
cp VM-Snapshot1.dec.vmsn out.vmsn
vol -f out.vmem windows.info # vol3 auto-detects its vmware layer from the .vmem/.vmsn pair
vol -f out.vmem windows.pslist
```
展开后的镜像是多个 4 MiB 物理块的拼接。其编解码器是一种自定义的
面向字节的 LZ77,是通过逆向 `vmware-vmx` 的 checkpoint 解压器得到的 - 有关完整的容器结构及 LZ 语法,请参阅 [`docs/FORMAT.md`](docs/FORMAT.md)。
(如果你有权限访问 ESXi,其内置的 `crypto-util encobj decrypt` 命令可以一步完成解密 **和** 解压缩。)
## 状态
| 文件 | 解密 | 适配 Volatility |
|------|:------:|:----------------:|
| `.vmsn` / `.vmss` | ✅ | ✅(原生格式) |
| `.nvram` | ✅ | 不适用 |
| `.vmem` | ✅ | ⚠️ 需要解压缩(通过 ESXi `crypto-util`,或尚不支持的离线方式 TODO) |
## 致谢
- Key-chain 参考:[RF3/VMwareVMX](https://github.com/RF3/VMwareVMX),
[axcheron/pyvmx-cracker](https://github.com/axcheron/pyvmx-cracker)
- Hash 提取参考:[archidote/VM-Password-Extractor](https://github.com/archidote/VM-Password-Extractor)
- `encobj` 容器结构及逐页(per-page)AES-256-CBC 布局由本工具完成逆向工程。
## 许可证
基于 [MIT License](LICENSE) 授权。
标签:JARM, Python, 内存分析, 数字取证, 无后门, 自动化脚本, 虚拟化技术, 解密工具, 逆向工具