一、概述
前面几篇讨论的是加密存储:BitLocker 的 FVE metadata、EFS 的 $EFS 流、VeraCrypt 的卷头。它们有一个共同点——密钥或密钥材料留在系统的某个可利用位置上,取证是"找到它"的过程。
本篇处理的是完全不同的一类问题:当系统里没有留下任何可直接使用的密钥时,如何在合法授权下从哈希或密文中恢复口令。
在真实案件里,后一类远比前一类常见——用户自己设的口令、改过的文件密码、加密压缩包,主人都忘了或者不想说。
这个领域有一个特别容易让人走偏的特征:它在互联网上主要以"渗透测试"和"账号爆破"的面貌出现,几乎所有公开教程都默认目标是无授权的第三方系统。
而在取证语境下,操作顺序和合规约束与攻击场景有本质区别。
本篇最重要的一半内容是这些约束,而不是工具参数。
⚠️ 三条合规红线(写在这里,不是写在下文)
红线一:只能在有授权的检材上做。 授权范围必须覆盖三件事:检材来源合法、恢复目的明确、恢复结果的使用方式被授权书限定。模糊的"客户送来的机器"不构成授权;"送来的机器"也不自动授权你去做 GPU 集群爆破。把授权书和检材编号绑定归档,开工前先记录。哈希爆破本身在多数司法辖区不必然构成犯罪,但未经授权对他人系统实施的行为落在计算机系统入侵的射程内,而密码恢复是侵入行为的典型前置动作。
红线二:暴力破解是「最后的手段」,不是「第一反应」。 绝大多数案件中根本不需要爆破。真实的口令来源,按命中率排序是:
| 优先级 |
来源 |
说明 |
| ★★★★★ |
证据内的明文残留 |
配置文件、脚本、聊天记录、Excel 表格、.env、shell 历史 |
| ★★★★★ |
同机复用 |
同一用户换设备/换系统时复用了同一个口令 |
| ★★★★ |
其他账户的口令 |
同一管理员在其他服务上用过同一口令 |
| ★★★★ |
上下文候选 |
用户名、生日、车牌、项目名 + 用户习惯后缀 |
| ★★★ |
键盘模式 / 掩码 |
仅在已知格式特征时(如"6 位生日") |
| ★★ |
纯暴力 |
仅在长度极短(如 4 位 PIN)时才现实 |
| ★ |
彩虹表 |
对加盐现代格式几乎无用,见 2.4 |
先把上表走完,再考虑 hashcat。 报告里要写清楚"为什么走了爆破"——跳过了同机复用分析就直接跑字典,说明流程有缺陷。
红线三:破解得到的口令涉及第三人隐私时,报告里要做脱敏与最小化。 一条 NTLM 哈希背后可能是一个真实的人:他用于支付、邮箱、社保的同一个口令。写进鉴定报告的应该是——该哈希存在于哪个文件的哪个偏移、属于哪个账户(RID / 域名)、是否能与本案的某个关键文件相互印证。而不是"该账户口令为 P@ssw0rd2024"。只有当口令本身是案件核心事实时(例如它是受害者的胁迫来源、或是访问被删数据的唯一途径),才在受控附件中给出,且单独存放、加密、限定访问人。法庭上"我们拿到了口令"这句话,需要的是可复现的验证过程,不是口令本身。
本篇处理的证据形态(*2john 家族能处理的输入是理解本篇的第一步):
| 证据 |
提取物 |
前提 |
SAM hive |
NTLM 哈希 + RID |
hive 已离线提取 |
SECURITY hive |
缓存域凭据、DCC(Meterpreter 格式) |
hive 已离线提取 |
/etc/shadow |
crypt 格式串 |
需 root 读取权限记录 |
| Windows 凭据管理器 |
通用凭据 blob |
cmdkey /list + 内存分析配合 |
| 加密文件(7z / RAR / Office / PDF) |
经 *2john 转换后的"哈希" |
必须先判断是加密还是压缩 |
| 抓包 |
NetNTLMv2 / Kerberos / WPA 的 .hc22000 |
需 网络流量与 PCAP 取证 作为前置 |
先把文件类型判断清楚是本篇最容易被跳过、也最致命的一步。
7z 的加密头、Office 的 Agile 加密、PDF 的标准安全处理器,处理方式与算力需求差了几个数量级。
用错方式的开局,往往导致用几倍的算力去攻一个根本不该攻的目标。
在取证流程中的位置:本篇是分析环节的深水区,通常在明文路径全部走完之后才被启用。
上游依赖是镜像制作(所有提取都必须在已镜像的检材副本上做,原件不动)与注册表取证(SAM/SECURITY hive 的提取手法)。
浏览器密码库与 Token 解密与远程工具凭据解密产出的单向哈希字段,最终要按本篇的方法论决定是"固定存在性"还是"进入离线验证"。
下游支撑的是报告层。本篇的每一条产出都必须附带可复现的验证过程,方法论见取证流程与原则。
检材里有哪些可攻对象、每个对象的加密类型与算力可行性、非爆破路径是否已经穷尽、选定方式后能否恢复——以及,恢复结果是否经过"实际打开"级验证。
"打不开"不等于"打不开"——工具报 no key / unsupported / Invalid hash 在多数实现里语义并不统一,很可能只是"我没读懂这个格式"。
KDF 强度高的格式(密码管理器主密码)通常只能靠线索,不能靠算力。
以及最重要的一条:本篇不提供针对特定真实目标的口令字典、默认口令库或任何绕过技巧。方法论与纪律,不等于能解开任何东西。
读者前提:你需要先理解哈希与完整性校验在取证中的双重角色(既用来验证证据,也用来做口令验证,见哈希与完整性校验)、授权书与委托证明的基本要求(证据保管链与委托证明)、以及 GPU 算力的基本概念。
如果你还没有确定委托范围,先不要读下面的操作步骤。
二、核心原理
2.1 商业工具的定位:Passware Kit 的模块划分
Passware Kit Forensic 是这个领域最常见的商业方案("Passware"本身即源自 "Password Recovery Software")。
理解它的模块划分,等于理解了整个取证密码恢复的能力地图。
| 模块 |
作用 |
与开源工具的差异 |
| Find Encrypted Files |
全盘扫描并报告所有加密文件/容器及其加密类型与复杂度 |
开源工具通常需要逐个试错判断类型 |
| Full Disk Encryption |
解密 BitLocker / FileVault2 / LUKS(LUKS2) / TrueCrypt / VeraCrypt / APFS / PGP 等镜像 |
见 BitLocker 全卷加密取证 与 VeraCrypt 加密卷取证 |
| File Recovery |
Office / PDF / Zip / RAR / 7z 等 400+ 文件类型的口令恢复 |
覆盖的私有格式远多于 hashcat/JtR |
| Database Passwords |
从应用配置文件/注册表中提取并恢复数据库连接口令 |
见 数据库与配置文件加密 |
| Windows / Standalone System |
从外置注册表 hive 中提取系统账户口令 |
见 内存中的凭据与密钥 |
| Internet & Network |
浏览器、邮件客户端、网络连接的保存凭据 |
见 远程工具凭据解密 与 浏览器密码库与 Token |
| Memory Analysis |
分析内存镜像/休眠文件,提取其中的密钥与口令 |
见 内存中的凭据与密钥 |
| Password Managers |
KeePass / 1Password / LastPass 等主密码恢复 |
属于 KDF 高强度类型,通常只能靠线索 |
| Agents(分布式) |
把恢复任务分发到多台机器(Windows / Linux / 云) |
hashcat 也能做,但管理成本高 |
2.2 与开源工具的差异(必须写进报告的方法论说明)
| 维度 |
Passware Kit Forensic |
hashcat / John the Ripper |
| 覆盖格式 |
400+,含大量厂商私有格式(QuickBooks、FileMaker、Lotus Notes、财资软件) |
数百种哈希,但需能表达为"哈希"或可转换的文件格式 |
| 交互 |
图形化,可拖文件进去 |
纯命令行 |
| 批量 / 分布式 |
内置批量队列 + Agent 管理器 |
需自己脚本编排与搭建 |
| 复杂度评估 |
能报告"这个加密有多难" |
不评估 |
| 成本 |
闭源 + 按年订阅收费 |
免费开源 |
| 可复现性 |
闭源算法,外部无法独立验证,法庭上难辩护 |
开源、可审计、可复现 |
关键判断:商业工具的真正优势在于格式识别广和能给出复杂度评估,速度通常不是差距所在。
它的弱点是闭源——在需要为结论辩护的司法场景里,开源工具的可复现性往往比覆盖率更重要。
一个稳妥做法是:商业工具用于发现与初筛(找出哪些是加密的、哪些值得攻),开源工具用于确认与验证。
2.3 通用恢复流程的四个阶段
① 哈希提取 → ② 攻击方式选择 → ③ 工具执行 → ④ 实际验证
这四步的顺序不能颠倒。
跳过 ① 拿到不明格式的"哈希"直接喂给 hashcat,典型结果是 Invalid hash,或者更糟——格式猜错时 hashcat 可能"破解成功",但解出的明文是垃圾数据。
① 哈希提取的合法来源(全都必须是已镜像的检材或合法取得的配置):
| 来源 |
提取物 |
工具 |
| SAM hive |
NTLM 哈希 |
secretsdump.py / hashdump / RegRipper |
| SECURITY hive |
缓存域凭据、DCC |
secretsdump.py |
/etc/shadow |
crypt 格式 |
直接读取 |
| Windows 凭据管理器 |
通用凭据 blob |
cmdkey /list + 内存分析 |
| 应用配置文件 |
明文或弱编码口令 |
见 05、06、07 篇 |
| 网络抓包 |
NetNTLMv2 / Kerberos / WPA |
secretsdump.py / hcxpcapngtool |
| 加密文件 |
需 *2john 转换 |
见 2.5 |
② 攻击方式选择——这是决策而非穷举:
| 方式 |
何时选 |
关键前提 |
字典攻击 -a 0 |
口语化环境(个人机器、中文用户)、已知泄露口令 |
词表覆盖度;配合规则 |
规则攻击 -a 0 -r |
怀疑是"某词 + 变形" |
变形假设(首字母大写 + 数字后缀) |
掩码攻击 -a 3 |
已知格式特征(生日、手机号后 8 位、6 位 PIN) |
必须能说清每个 ? 对应什么 |
组合 / 混合 -a 1 / -a 6,7 |
怀疑是"词 + 数字后缀""两词拼接"这类企业口令模式 |
词表规模可控 |
PRINCE --prince |
强规则词典存在但机器上不方便维护 |
内存占用大 |
暴力 -a 3 ?a?a?a?a?a?a?a?a |
仅当长度 ≤ 7–8 且全字符集 |
算清 keyspace 再启动 |
| 彩虹表 |
仅 unsalted 旧格式 |
见 2.4 |
掩码的纪律要求:使用掩码前必须在报告中写清掩码的依据来源。?d?d?d?d?d?d?d?d 攻击 8 位生日数字,理由是"该用户在另一社交平台公开的生日为 1990-05-17"——这是可辩护的。"没有依据就用全字符集暴力"是不被接受的。
掩码语法(hashcat):
| 占位符 |
含义 |
占位符 |
含义 |
?l |
小写字母 |
?a |
?l?u?d?s 全组合 |
?u |
大写字母 |
?b |
0x00–0xff 全字节 |
?d |
数字 |
?1–?4 |
自定义字符集 1–4 |
?s |
符号 |
** |
拒绝当前规则候选 |
③ 工具定位:
- hashcat:GPU 优先。对快哈希(MD5/SHA1/SHA256/NTLM/NetNTLM)优势压倒性——这类算法计算量低,瓶颈在吞吐量,GPU 的并行规模正好碾压 CPU。
--example-hashes 可列出全部模式,-I 看设备。
- john the ripper:CPU 优先、支持格式更杂。对慢哈希(bcrypt/scrypt/PBKDF2)差别不大(都受限于算法本身而非算力),但它对畸形/非标准格式的容错更好,且
*2john 系列格式转换器更全。
④ 验证——本篇最容易被跳过、也最致命的一步。
hashcat 报 Cracked 只意味着"我算出了一个输入,它的哈希值等于目标"。
它不意味着这个输入真的是那个口令(碰撞极罕见但不是零),不意味着那个口令真能打开目标文件,也不意味着你提取的哈希确实来自这个文件。
合格的验证必须落到"实际打开":
# 验证 1:加密文件类——真正用解出的口令打开(7z 的 -p 只写一次)
7z l -p'<解出的口令>' 'evidence.zip' >/dev/null 2>&1 \
&& echo "VERIFIED: 可用该口令打开" || echo "NOT VERIFIED"
# 验证 2:数据库类——真正执行 SELECT
mysql -h <host> -u <user> -p'<解出的口令>' -e "SELECT VERSION();"
# 验证 3:算法自洽——用已知明文复算,确认你选的 -m 是对的
echo -n "test" | md5sum # 应等于你构造的测试哈希,否则说明选错了 -m
绝对不要把"hashcat 输出了 Status: Cracked"写进报告的验证环节。 那只是"候选已产生",不是"结论已成立"。
2.4 彩虹表为什么在本领域基本失效
彩虹表用空间换时间:预先算好 hash → 明文 的全量表,攻击时 O(1) 查表。
前提是哈希不加盐(否则每用户一个盐,表就废了)、迭代次数低、哈希空间足够小。
现实对照:bcrypt / scrypt / Argon2 / /etc/shadow 的 $y$(yescrypt)/ KeePass 主密码全部不可能;无盐 MD5/SHA1 早期口令理论可行;NTLM 无盐但按需计算已比查表快,表无优势。
结论:现代取证中彩虹表已基本退出。
2.5 哈希提取工具:*2john 家族
加密文件不是"哈希",但可以把它降维成一个"可用指定口令验证正确性"的对象。
这就是 *2john 工具的思路:解析文件格式,抽取验证参数,输出一个 hashcat/JtR 能接受的哈希行。
# *2john 随 John the Ripper 一起分发(进入其 run 目录)
cd /usr/share/john/run
ls *2john | head -30 # 形如 pdf2john.py、office2john.py、7z2john.py
# 典型用法:文件 → JtR 格式哈希
python3 pdf2john.py evidence.pdf > evidence_pdf.hash
python3 office2john.py evidence.xlsx > evidence_xlsx.hash
python3 7z2john.py evidence.7z > evidence_7z.hash
python3 keepass2john.py vault.kdbx > evidence_kdbx.hash
注意事项:
*2john 的输出是特定版本的实现。同一文件换 John 版本可能输出不同参数。
- 转换后必须先用已知口令自测(用一个自己加密的测试文件走通全流程),确认你的转换 → 攻击 → 打开链路是通的,再对检材动手。
**这条自测是发现"版本不匹配导致解错"的