1. 项目概述:为什么需要双工具破解NTLM?
在渗透测试或安全评估的授权范围内,获取到Windows系统的密码哈希(Hash)是常有的事。其中,NTLM(NT LAN Manager)哈希是Windows网络认证的核心,从古老的Windows NT到现在的Active Directory域环境,它无处不在。当你拿到一串像aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0这样的字符时,背后可能就是一台服务器或一个用户账户的访问权限。单纯知道原理不够,你得能把它转化成实际的突破口,这就是实战的价值。
为什么是John the Ripper和Hashcat这对“黄金组合”?因为它们代表了两种互补的破解哲学。John the Ripper(简称John)更像是一位经验丰富的“策略大师”,它灵活、可定制性强,尤其擅长基于规则的智能攻击和复杂的密码策略分析,在CPU上运行,适合精细化的密码研究。而Hashcat则是纯粹的“力量型选手”,它被设计为榨干GPU每一分算力的“破解引擎”,在暴力破解和大型字典攻击的速度上无人能及。单独使用任何一个,你都可能在某些场景下遇到瓶颈:用John跑大型字典或暴力破解太慢;用Hashcat做复杂的规则变换可能不如John方便。将两者结合,先用Hashcat的蛮力进行第一轮高速冲刷,再用John的规则进行第二轮深度挖掘,往往能起到1+1>2的效果。
这篇文章,我就从一个老手的角度,带你从NTLM哈希的原理开始,一步步拆解如何用这两个工具搭建高效的破解流程。无论你是安全研究员、渗透测试人员,还是对系统安全感兴趣的技术爱好者,这套方法都能让你在面对一串NTLM哈希时,心里有谱,手上有术。
2. 核心原理:NTLM哈希的生成与脆弱性
要破解,先得懂它是怎么来的。NTLM哈希不是直接存储你的密码明文,而是经过一个不可逆的数学变换(哈希函数)的结果。但正是这个过程中的一些历史设计,成为了它的安全短板。
2.1 NTLM哈希的计算过程
当你输入密码,比如“P@ssw0rd2024”,Windows系统会首先将其转换为Unicode编码。然后,对这个Unicode字符串应用MD4哈希算法。MD4是一个很老的哈希函数,现在已知存在严重密码学弱点,但微软为了向后兼容,一直在NTLM中沿用。计算出的这个128位(16字节)的MD4哈希值,就是所谓的“NTLM哈希”。它通常以32个十六进制字符的形式呈现,例如8846F7EAEE8FB117AD06BDD830B7586C。
这里有个关键点:NTLM哈希是静态的。只要密码不变,无论你在哪台电脑、哪个时间登录,计算出的这个哈希值都是一样的。这与一些现代系统使用的加盐(Salt)哈希有本质区别。加盐哈希会为每个密码随机生成一个“盐值”,并与密码组合后再哈希,使得即使两个用户密码相同,其哈希值也完全不同,极大增加了破解难度。而NTLM没有盐,这意味着攻击者可以预先计算海量密码的哈希值(即彩虹表),进行快速的比对破解。虽然现代Windows默认已禁用LM哈希并推荐使用NTLMv2等更安全的会话机制,但NTLM哈希本身在系统内仍广泛存在。
2.2 为什么NTLM易于破解?
除了没有加盐,还有几个因素让NTLM成为脆弱的目标:
- 算法强度不足:MD4算法已被证明存在碰撞漏洞,且计算速度极快。这对验证方是优点,对攻击方更是“优点”——意味着他们可以每秒尝试数十亿甚至上百亿个密码组合(尤其是在GPU上)。
- 密码复杂性策略的局限性:尽管企业策略要求密码包含大小写、数字、符号,但人类的思维有模式。例如,“P@ssw0rd2024”其实就是“Password2024”的常见变体(‘a’变‘@’, ‘o’变‘0’)。这种变换规则是可预测的。
- 哈希的暴露风险:在Active Directory中,域控上存储着所有用户的NTLM哈希(在NTDS.dit文件中)。一旦攻击者通过某种手段(如域内提权、DCSync攻击)获取了该文件,就等于拿到了整个域用户密码的“指纹库”。本地SAM文件中则存储着本地用户的哈希。
理解这些原理,你就会明白,我们的破解攻击主要针对的是密码本身的脆弱性,而非MD4算法本身(虽然算法旧,但直接反转哈希在计算上仍不可行)。我们的所有策略,无论是字典、规则还是暴力破解,都是在模拟生成海量的候选密码,计算其NTLM哈希,然后与目标哈希进行比对。这个过程就是“猜”,但要用聪明且高效的方法去“猜”。
3. 环境准备与工具安装
工欲善其事,必先利其器。下面分别介绍在Kali Linux(渗透测试常用系统)和Windows系统上安装配置John和Hashcat的详细步骤。我强烈建议使用Linux环境,尤其是对于Hashcat的GPU支持,Linux的驱动和兼容性通常更好。
3.1 John the Ripper 安装与配置
John是一个开源项目,安装相对简单。
在Kali Linux上:Kali已经预装了John,但可能是精简版(john)。建议安装功能完整的“John the Ripper jumbo”版本,它支持更多的哈希类型和特性。
sudo apt update sudo apt install john -y安装后,可以通过john --list=formats | grep -i ntlm来检查是否支持NTLM。你应该能看到netntlm, netntlmv2, nt等。其中nt就是传统的NTLM哈希格式。
在Windows上:
- 访问OpenWall的官方GitHub仓库,下载适用于Windows的预编译Jumbo版本压缩包。
- 解压到一个路径简单的目录,比如
C:\john。 - 将
C:\john\run目录添加到系统的PATH环境变量中。 - 打开命令提示符或PowerShell,输入
john,应该能看到帮助信息。
注意:Windows下John的性能通常不如Linux,且对于GPU加速的支持也较弱。它主要依赖CPU进行破解。
John的核心文件:
john:主程序。password.lst:一个简单的内置字典文件。john.conf:John的配置文件,位于/etc/john/john.conf(Linux)或解压目录的run文件夹下。这个文件定义了密码破解的规则(rules),是John智能攻击的灵魂,我们后面会详细修改它。
3.2 Hashcat 安装与配置
Hashcat的安装重点在于GPU驱动的正确安装。
在Kali Linux上:
sudo apt update sudo apt install hashcat hashcat-nvidia -y # 如果使用NVIDIA GPU # 对于AMD GPU,可以尝试安装 `hashcat-amdgpu` 或从源码编译安装后,运行hashcat --version查看版本,运行hashcat -I(大写i)来查看Hashcat检测到的计算设备(OpenCL平台)。如果你看到你的GPU型号,并且性能指标正常,说明驱动基本就绪。
在Windows上:
- 安装显卡驱动:确保安装了最新的NVIDIA Game Ready驱动或AMD Adrenalin驱动。这是最关键的一步。
- 安装OpenCL运行时:对于NVIDIA,驱动通常已包含。对于AMD,可能需要从AMD官网额外下载并安装“AMD APP SDK”或“ROCm”运行时(取决于显卡和Hashcat版本)。
- 下载Hashcat:从Hashcat官网下载最新的二进制压缩包。
- 解压并测试:解压后,在命令行中进入该目录,运行
hashcat.exe -b进行性能基准测试。这个测试会输出你的GPU对各种哈希算法的破解速度,是衡量你设备破解能力的直接指标。
首次运行验证:在Linux或Windows上,都可以用一个简单的命令测试Hashcat是否工作正常:
hashcat -m 1000 -a 0 '8846f7eaee8fb117ad06bdd830b7586c' rockyou.txt这个命令尝试用rockyou.txt字典破解一个示例NTLM哈希(-m 1000指定NTLM类型)。你需要先下载rockyou.txt字典(在Kali中位于/usr/share/wordlists/rockyou.txt.gz,需解压)。如果一切正常,你会看到Hashcat开始工作并显示状态。
实操心得:安装后务必运行
hashcat -b。这个基准测试不仅能验证环境,其输出的“速度”值(如H/s,每秒哈希数)是你后续估算破解时间的重要依据。一张好的RTX 4090显卡破解NTLM的速度可以达到数百GH/s(每秒千亿次哈希计算),而CPU可能只有几MH/s,相差数万倍。
4. 实战演练:双工具协同破解流程
假设我们通过授权渗透测试,从一台Windows Server 2019的SAM文件中提取到了以下两个用户的NTLM哈希:
Administrator:1001:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: Guest:1002:aad3b435b51404eeaad3b435b51404ee:8846f7eaee8fb117ad06bdd830b7586c:::格式是用户名:RID:LM哈希:NTLM哈希:::...。我们关注的是冒号分隔的第四段,即NTLM哈希。注意,Administrator的哈希31d6cfe0d16ae931b73c59d7e0c089c0是空密码的哈希,这是一个特殊值。我们真正要破解的是Guest用户的哈希8846f7eaee8fb117ad06bdd830b7586c。
4.1 第一步:数据准备与格式化
工具需要干净的输入。首先,我们创建一个只包含目标哈希的文件。对于Hashcat,我们只需要哈希值本身(或用户名:哈希的格式)。对于John,我们需要特定的格式。
为Hashcat准备文件target_hashes.txt:
8846f7eaee8fb117ad06bdd830b7586c或者,如果你想保留用户名信息便于识别,可以用:
Guest:8846f7eaee8fb117ad06bdd830b7586c为John准备文件target_hashes_john.txt:John需要一种特定的格式,通常是用户名:哈希,或者对于从SAM提取的,可以直接使用pwdump格式。我们可以手动构造:
Guest:1002:8846F7EAEE8FB117AD06BDD830B7586C:::但更简单的方法是,将原始的SAM提取行保存到一个文件,John通常能自动识别。我们创建一个ntlm_hash.txt,内容就是最初的两行。
字典准备:字典是破解的弹药库。除了Kali自带的rockyou.txt,一个好的做法是组合使用多个字典。
- 基础字典:
rockyou.txt(约1400万密码)。 - 定制字典:根据目标信息生成。如果知道公司名是“TechCorp2024”,可以创建一个包含其变体的字典,如
techcorp, TechCorp, techcorp2024, TechCorp2024, Techcorp123等。 - 规则字典:利用John的规则,对基础字典进行动态变换,这比存储所有变体更高效。
我们创建一个简单的自定义字典文件custom_words.txt备用。
4.2 第二步:第一轮攻击——Hashcat GPU高速字典攻击
Hashcat擅长打“闪电战”。我们用最快的GPU模式,先进行一轮广泛的字典攻击。
命令解析:
hashcat -m 1000 -a 0 -o cracked.txt target_hashes.txt /usr/share/wordlists/rockyou.txt-m 1000:指定哈希类型为NTLM。-a 0:指定攻击模式为字典攻击(straight)。-o cracked.txt:将破解成功的密码输出到cracked.txt文件。target_hashes.txt:包含目标哈希的文件。/usr/share/wordlists/rockyou.txt:使用的字典文件路径。
执行与监控:运行命令后,Hashcat会启动。你会看到一个动态更新的状态界面,显示:
- Speed:当前破解速度(如 350.1 GH/s)。
- Progress:进度百分比和预计剩余时间。
- Recovered:已破解的哈希数量。
- Status:当前状态(如 Running, Paused, Cracked)。
如果rockyou.txt里恰好有密码“password123”的哈希是8846...c,那么几秒内就会破解成功,状态变为Cracked,密码会保存在cracked.txt中,格式如8846f7eaee8fb117ad06bdd830b7586c:password123。
注意事项:如果第一轮字典攻击没有结果,非常正常。
rockyou.txt虽然大,但毕竟只是常见密码。这时不要气馁,我们进入下一轮更智能的攻击。
4.3 第三步:第二轮攻击——John the Ripper 规则攻击
当蛮力字典无效时,就需要“智取”。John的规则攻击(-a 0 with rules)是其精髓。它通过预定义的规则集,对字典中的每个单词进行一系列变换,如大小写切换、添加后缀/前缀、字符替换(‘o’->‘0’, ‘a’->‘@’)等。
启用强大的规则:John的配置文件里定义了许多规则集,如Wordlist规则套件。我们使用一个强大的规则模式:
john --wordlist=/usr/share/wordlists/rockyou.txt --rules=Wordlist --format=NT target_hashes_john.txt--wordlist:指定字典文件。--rules=Wordlist:应用名为“Wordlist”的规则集。这是John预定义的一个非常全面的规则集合。--format=NT:明确指定哈希格式为NT(即NTLM)。target_hashes_john.txt:目标哈希文件。
规则在做什么?假设字典里有单词“password”。规则可能会依次生成:
Password(首字母大写)PASSWORD(全大写)p@ssword(a->@)p@ssw0rd(a->@, o->0)password123(添加数字后缀)Password2024!(首字母大写+年份+符号) ... 一个单词经过规则扩展,可以变成几十甚至上百个候选密码,极大地提高了命中复杂密码的概率。
查看结果:破解成功后,使用john --show target_hashes_john.txt来显示破解出的用户名和密码。
4.4 第四轮攻击:Hashcat 混合攻击与暴力破解
如果规则攻击也失败了,说明密码可能不在常见字典及其常见变体中。此时,我们需要扩大搜索范围。
混合攻击(Hybrid Attack): 混合攻击(-a 6或-a 7)结合了字典和掩码。例如,我们猜测用户可能在某个基础词后添加了固定格式的后缀(如年份、数字)。
hashcat -m 1000 -a 6 target_hashes.txt custom_words.txt ?d?d?d?d这个命令尝试用custom_words.txt里的每个单词,拼接上任意4位数字(?d代表一个数字)。这可以用来破解像“Company2023”这样的密码。
掩码攻击(Mask Attack): 当我们对密码结构有一定假设时,掩码攻击(-a 3)效率极高。它直接定义每个字符位置的可能字符集。
hashcat -m 1000 -a 3 target_hashes.txt ?u?l?l?l?l?d?d?d?d这个掩码表示:1位大写字母(?u) + 4位小写字母(?l) + 4位数字(?d),例如“Hello1234”。掩码可以非常灵活,例如?u?l?l?l?s?d?d?d?d表示在中间可能有一个特殊字符(?s)。
暴力破解(Brute-Force): 这是最后的手段,尝试所有可能的组合。务必谨慎使用,因为随着密码长度增加,可能性呈指数级增长。
hashcat -m 1000 -a 3 target_hashes.txt ?a?a?a?a?a?a?a?a这个命令尝试所有8位可打印字符(?a)的组合。对于一个8位复杂密码,即使以100 GH/s的速度,也需要数年时间。因此,暴力破解通常需要结合强大的硬件和合理的掩码限制(例如,知道密码是8-10位,且以大写字母开头)。
实操心得:在实际测试中,攻击顺序应该是字典 -> 规则 -> 混合/掩码 -> 有限暴力。并且,要充分利用Hashcat的“恢复”(--restore)功能。你可以用
--session参数给任务命名,中断后可以随时恢复。例如:hashcat -m 1000 -a 3 --session=mycrack target_hashes.txt ?u?l?l?l?l?d?d?d?d,中断后使用hashcat --restore --session=mycrack继续。
5. 高级技巧与性能优化
掌握了基本流程,下面这些技巧能让你效率倍增。
5.1 字典工程与规则定制
生成定制字典:使用crunch、cewl或hashcat-utils中的工具。
cewl可以爬取目标公司网站,生成基于其内容的独特字典。hashcat --force test.hash -r rules/best64.rule --stdout > mutated_wordlist.txt可以先用规则处理字典并保存为新字典,供其他工具使用。
编写自定义John规则:编辑john.conf,在[List.Rules:Custom]段落添加自己的规则。例如:
[List.Rules:MyRules] c $1$2$3$4 # 在单词后添加1234 sao@ # 将所有的 'a' 替换为 '@' so0O # 将所有的 'o' 替换为 '0' 或 'O'然后在John中使用--rules=MyRules。
5.2 Hashcat 性能调优
- 工作负载优化:
-w参数调整工作负载。-w 3或-w 4可以提高性能,但可能使系统交互卡顿。在专用破解机器上可以设为-w 4。 - GPU调优:
--force:忽略警告强制运行(慎用)。--optimized-kernel-enable:启用优化内核。- 对于NVIDIA GPU,可以尝试
--backend-options=--unroll-loops等。
- 使用Potfile:Hashcat默认将破解结果保存在
~/.hashcat/hashcat.potfile中。再次破解相同哈希时,Hashcat会直接跳过,节省时间。--potfile-disable可以禁用此功能。 - 分布式破解:如果有多台机器,可以使用
--outfile-format=3输出为HCCAPX格式,然后合并结果,或者使用中间文件手动分割任务。
5.3 双工具联动策略
真正的协同不是依次使用,而是管道化协作。
- John生成字典,Hashcat破解:利用John的规则引擎生成高质量的变异字典,然后用Hashcat高速跑。
这里John的john --wordlist=base.txt --rules=Wordlist --stdout | hashcat -m 1000 -a 0 target_hashes.txt--stdout将规则变换后的密码列表输出到标准输出,通过管道|直接传给Hashcat。这结合了John的智能和Hashcat的速度。 - Hashcat掩码结果作为John的输入:先用Hashcat跑一个宽泛的掩码,将未破解的哈希(用
--left参数导出)再用John的深度规则进行攻击。
6. 常见问题、排查与防御建议
6.1 破解过程中的常见问题
问题1:Hashcat报错 “No devices found/left” 或 “CL_OUT_OF_RESOURCES”。
- 原因:GPU驱动未正确安装,或GPU内存不足。
- 排查:
- 运行
hashcat -I确认设备被识别。 - 对于内存不足,尝试减小掩码复杂度或使用
--optimized-kernel-enable。 - 在Windows上,确保使用的是最新稳定版驱动,而非Studio驱动(Game Ready驱动对计算支持更好)。
- 运行
问题2:John运行缓慢,几乎没有进度。
- 原因:John默认使用CPU单核。规则过于复杂或字典太大。
- 排查:
- 使用
--fork=N参数启用多进程(N为CPU核心数),如john --fork=4 ...。 - 检查规则,可以先用一个简单的规则集(如
--rules=Single)测试。 - 考虑将任务转移到Hashcat进行GPU加速。
- 使用
问题3:破解成功,但密码显示为乱码或非预期字符。
- 原因:密码中可能包含非ASCII字符或终端显示问题。
- 排查:
- 使用
john --show --encoding=UTF-8指定编码查看。 - 对于Hashcat,查看
cracked.txt文件本身的内容,用文本编辑器打开。
- 使用
问题4:如何判断一个NTLM哈希是否无法破解?
- 如果经过大型字典、深度规则、合理掩码攻击后仍未破解,且暴力破解在可行时间内(根据你的算力和密码长度估算)也无望,那么可以暂时视为“强密码”。但永远不要绝对化,新的字典、新的社会工程学信息可能会改变局面。
6.2 从防御者视角看NTLM安全
了解了攻击,才能更好地防御。作为系统管理员或安全工程师,你应该:
- 强制使用强密码策略:长度大于12位,强制要求大小写字母、数字、特殊字符混合。避免使用可预测的替换(P@ssw0rd)或常见模式。
- 启用并优先使用Kerberos认证:在域环境中,确保客户端和服务器都支持并优先使用Kerberos,它比NTLM安全得多。
- 限制NTLM使用:通过组策略禁用NTLMv1,并尽可能限制NTLMv2的使用范围。可以设置“网络安全:限制NTLM”策略。
- 实施NTLM审计与监控:在关键服务器上启用NTLM审计日志,监控异常或大量的NTLM认证请求。
- 使用LAPS(本地管理员密码解决方案):对于本地管理员账户,使用LAPS定期随机化密码,并确保密码长度和复杂性,使得提取的哈希短时间内失效。
- 防范哈希传递(Pass-the-Hash)攻击:即使密码无法破解,攻击者也可能直接使用窃取的NTLM哈希进行横向移动。启用Credential Guard(Windows 10/11, Server 2016+)可以隔离和保护哈希。
- 定期进行密码哈希审计:在授权下,定期对自己的系统进行哈希提取和破解测试,主动发现弱密码。
密码安全是一场攻防的持久战。攻击工具如John和Hashcat的日益强大,不断提醒我们,依赖密码本身复杂度是脆弱的。因此,在强化密码策略的同时,务必部署多因素认证(MFA),这是当前防止凭证泄露导致入侵的最有效手段之一。对于关键系统,考虑采用证书、生物识别等更强大的认证方式,逐步降低对静态密码的依赖。