在授权渗透测试、CTF 解题和安全研究场景里,经常需要面对一批待验证的密码哈希。市面上的破解工具虽然不少,但有的依赖 GPU 环境,有的参数体系复杂,对于以 C# 为主要技术栈的团队来说,想在里面做二次扩展并不轻松。GitHub 上 JuliusBrussee 开源的 caveman 项目给出了另一个思路:整个工具用 C# 编写,跨平台运行,核心逻辑可以复用,还支持用 C# 自定义密码生成器。这篇文章就围绕 caveman 的定位、构建方式、基本用法、扩展思路和常见问题进行完整梳理,适合安全测试入门者、CTF 玩家以及想在 .NET 生态里集成密码强度校验工具的开发者阅读。
1. caveman 项目概览
1.1 项目定位
caveman 是 JuliusBrussee 在 GitHub 上开源的一个密码暴力破解(Brute-Force)工具,仓库地址为 https://github.com/JuliusBrussee/caveman。它使用 C# 编写,基于 .NET 构建,能够在 Windows、Linux、macOS 上运行。
项目对自己的定位是“fast, flexible, and simple”,即快速、灵活、简单。它不像 Hashcat 那样追求大规模 GPU 集群的极致性能,而是把核心逻辑放在 CPU 多线程执行上,同时提供清晰的扩展机制。换句话说,caveman 更适合以下场景:
- 希望在一个中小型工具链中快速加入哈希破解能力。
- 希望用 C# 直接编写自定义密码生成规则。
- 希望了解暴力破解工具内部工作原理,并在此基础上做研究。
- 团队技术栈以 .NET 为主,不想引入异构语言的破解工具。
1.2 它能做什么
从功能角度看,caveman 主要提供以下几类能力:
| 能力 | 说明 |
|---|---|
| 哈希暴力破解 | 对给定哈希值执行批量候选密码尝试 |
| 字典攻击 | 从 wordlist 文件中逐行读取候选密码 |
| 多种哈希算法 | 支持常见摘要算法的哈希计算与比对 |
| 自定义生成器 | 通过编写 C# 类控制候选密码的产生逻辑 |
| 神经网络密码猜测 | 利用训练模型优先尝试高概率密码 |
其中“自定义生成器”和“神经网络密码猜测”是它区别于普通小工具的特色功能。
1.3 典型应用场景
严格来说,caveman 适合在以下环境中使用:
- 授权渗透测试:企业安全团队在获得授权后,对自有系统的弱口令进行批量检测。
- CTF 竞赛:比赛题目给出哈希,要求参赛者还原明文密码。
- 密码恢复:你自己或所在组织拥有数据合法处置权,需要恢复遗忘的密码哈希。
- 安全研究:研究不同哈希算法的破解成本、字典生成策略、密码模型训练等。
1.4 合规声明
这一点必须放在最前面:caveman 是安全测试工具,不是用来攻击他人系统的工具。在使用前,请务必确认你拥有目标系统的合法授权。未授权对他人系统进行破解,在多数国家和地区都属于违法行为。本文所有示例均基于本机测试环境或 CTF 题目中的演示数据,请勿将文中方法用于任何未授权目标。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与项目获取
2.1 软件要求
在开始之前,需要准备好以下软件:
- Git:用于从 GitHub 拉取源码。
- .NET SDK:用于编译和运行 C# 项目。
- 命令行工具:Windows 可使用 PowerShell 或 CMD,Linux/macOS 使用 Terminal。
- 可选 IDE:Visual Studio、JetBrains Rider 或 VS Code 都可以,不强制。
关于 .NET SDK 版本,这里需要特别说明:caveman 项目开发时间较早,不同提交对应的目标框架可能不同,可能是 .NET Core 3.1,也可能是 .NET 5/6/8。请不要照抄任何教程里的版本号,而是以仓库中的 README.md、global.json 和各个 .csproj 文件为准。如果你安装的 SDK 与项目目标框架不匹配,编译时会得到明确的错误提示,再根据提示安装对应 SDK 即可。
2.2 拉取源码
打开终端,执行以下命令:
bash复制git clone https://github.com/JuliusBrussee/caveman.git
cd caveman
如果网络较慢,也可以先下载 ZIP 压缩包再解压。拉取完成后,先查看项目根目录的 README:
bash复制ls
cat README.md
README 中通常会写明项目结构、构建方式和基本用法,这是最权威的第一手资料。
2.3 项目结构说明
根据仓库的常见组织方式,caveman 大致包含以下模块:
code复制caveman/
├── src/
│ ├── Caveman/ # 命令行入口程序
│ ├── Caveman.Lib/ # 核心破解库
│ └── Caveman.Neural/ # 神经网络密码生成相关代码
├── README.md
└── caveman.sln # 解决方案文件
不同的仓库历史提交,目录结构可能会有调整。如果你看到的目录与上面不同,不要慌张,以实际仓库为准。关键是先找到解决方案文件(.sln)和命令行入口项目,这是我们接下来构建和运行的基础。
3. 核心原理拆解
3.1 暴力破解的基本流程
不论工具外表多复杂,暴力破解的核心逻辑其实只有四步:
- 接收一个或多个目标哈希值。
- 生成一个候选密码。
- 使用指定算法计算候选密码的哈希值。
- 将计算结果与目标哈希进行比较。
如果匹配,说明找到了明文密码;如果不匹配,则回到第 2 步继续生成下一个候选密码。用流程表示就是:
code复制生成候选密码 -> 计算哈希 -> 与目标哈希比对
^ |
+--------- 不匹配 --------+
从这个流程可以看出,破解速度主要取决于两个因素:
- 单位时间内能生成并计算多少候选密码,这由 CPU 性能、线程数和算法实现决定。
- 候选密码集合的质量,这由字典质量和生成规则决定。
caveman 在第一个因素上采用多线程并行计算,在第二个因素上通过字典、生成器和神经网络模型来提升命中率。
3.2 哈希算法的特点
caveman 支持多种常见哈希算法,例如 MD5、SHA1、SHA256、SHA512 等。具体支持列表请以项目 README 或运行时的 --help 输出为准。
这些算法的共同特点是“单向性”:你可以很容易地从密码 Password123 计算出它的 MD5 值,但很难从 MD5 值反推出明文。因此破解只能采用“猜一个、算一个、比一个”的方式。也正因为如此,暴力破解工具的正确优化方向并不是“逆向算法”,而是“更快地生成候选密码”和“更快地计算哈希”。
这里要提醒一点:MD5 和 SHA1 在现代安全实践中已经不适合作为密码存储算法,但在很多旧系统、CTF 题目和哈希校验场景中仍然大量存在。caveman 支持它们,主要是为了覆盖这些真实存在的场景。
3.3 破解模式
caveman 的候选密码来源可以归纳为三种模式:
- 字典模式:从 wordlist 文件中逐行读取候选密码。这是最基础也最常用的模式,适合针对常见弱口令进行批量验证。
- 生成器模式:使用内置规则或自定义 C# 生成器,按照程序逻辑动态生成候选密码。例如生成所有长度为 4 的纯数字组合。
- 神经网络模式:利用训练好的密码模型,预测更可能被人类使用的密码,并优先尝试这些高概率项。
三种模式各有适用场景。字典模式适合快速验证已知弱口令;生成器模式适合按规则穷举;神经网络模式适合目标哈希来自真实用户密码、且字典覆盖不足的情况。
3.4 为什么选择 C# 实现
你可能会问,破解工具不是用 C 或 Rust 写性能才高吗?为什么有项目选择 C#?这里有几个实际原因:
- 跨平台能力:.NET Core 之后,C# 可以稳定运行在 Windows、Linux、macOS 上,部署简单。
- 开发效率:C# 语法清晰,配合 .NET 的并发库,可以较快实现多线程任务。
- 生态集成:直接引用 NuGet 包,可以方便地接入机器学习、日志、报告等组件。
- 可维护性:如果一个团队本身就是 .NET 团队,用 C# 写安全工具意味着内部 review、二次开发和长期维护的成本更低。
因此,caveman 并不仅仅是“能跑”的玩具,它更是一个展示“如何用 C# 体系化地实现密码破解框架”的参考项目。
4. 完整实战:从编译到运行
下面我们以本机测试环境为例,走一遍完整的构建和运行流程。请记住:所有命令都要在你有权测试的设备上执行。
4.1 编译项目
进入 caveman 仓库根目录,执行:
bash复制dotnet build
如果你只想构建命令行入口项目,可以指定项目路径:
bash复制dotnet build src/Caveman
编译成功后,终端会显示生成的可执行文件路径,一般位于:
code复制src/Caveman/bin/Debug/<目标框架>/Caveman
在 Windows 上是 Caveman.exe,在 Linux/macOS 上是 Caveman。
如果编译过程中提示找不到某个 NuGet 包,可以检查 NuGet 源配置,必要时切换为可用的镜像源后重新执行 dotnet restore。
4.2 查看命令帮助
第一次运行,强烈建议先查看帮助信息:
bash复制dotnet run --project src/Caveman -- --help
或者直接运行编译产物:
bash复制./src/Caveman/bin/Debug/net6.0/Caveman --help
注意:这里 net6.0 只是示例路径,你需要根据实际编译输出的目录名调整。--help 会列出所有支持的子命令、参数及其说明。不同版本可能使用“全局参数”风格或“子命令”风格,因此下文示例中的参数名如果与你的版本不一致,请一律以 --help 输出为准。
4.3 准备测试哈希
为了验证工具是否正常工作,我们需要构造一个已知密码的哈希。假设密码是 Password123,计算它的 MD5 值。
在 Linux/macOS 上:
bash复制echo -n "Password123" | md5sum
在 Windows PowerShell 上:
powershell复制[System.BitConverter]::ToString(
[System.Security.Cryptography.MD5]::Create().ComputeHash(
[System.Text.Encoding]::UTF8.GetBytes("Password123")
)
).Replace("-", "").ToLower()
如果本机有 Python,也可以直接用 Python 计算:
bash复制python3 -c "import hashlib; print(hashlib.md5(b'Password123').hexdigest())"
把输出结果保存为 hash.txt 文件,备用。例如:
code复制5ebe2294ecd0e0f08eab7690d2a6ee69
请确认这个 MD5 值确实是 Password123 的,而不是其他字符串的。可以多次计算验证。
4.4 准备字典文件
创建一个简单的字典文件 wordlist.txt,内容包含几个候选密码:
code复制123456
password
admin
Password123
qwerty
保存后,确认文件编码是 UTF-8 无 BOM。如果你在 Windows 记事本中保存,建议选择“UTF-8”编码,避免 BOM 导致第一行读取异常。
4.5 执行破解
接下来运行破解命令。caveman 的用法在不同版本中可能有差异,下面是两种典型的命令行风格。
风格一:全局参数风格
bash复制dotnet run --project src/Caveman -- --wordlist wordlist.txt --algorithm md5 hash.txt
风格二:子命令风格
bash复制dotnet run --project src/Caveman -- crack --hashes hash.txt --wordlist wordlist.txt --algorithm md5
如果当前版本还支持直接传哈希值,也可以尝试:
bash复制dotnet run --project src/Caveman -- --hash 5ebe2294ecd0e0f08eab7690d2a6ee69 --wordlist wordlist.txt --algorithm md5
无论哪种风格,都请先看一下 --help,确认参数名后执行。
4.6 预期结果
如果一切正常,程序会在命中 Password123 时输出类似下面的信息:
code复制[+] 5ebe2294ecd0e0f08eab7690d2a6ee69 = Password123 (MD5)
不同版本的输出格式可能不同,但只要能看到 5ebe2294ecd0e0f08eab7690d2a6ee69 与 Password123 的对应关系,就说明破解成功。
如果没有输出,可能的原因包括:
- 字典中没有该密码对应的行。
- 哈希算法选择错误。
- 文件路径不对,工具没有读到哈希文件。
- 参数名不匹配,命令实际没有执行破解。
此时不要急着下结论,先结合 --help 检查参数,再逐步排查。
5. 自定义密码生成器
5.1 为什么要自定义生成器
字典模式的问题在于:它只能尝试“已经存在于文件中”的密码。如果目标密码是一个规则性很强的字符串(例如 abc001、abc002、abc003 这样的递增序列),你不可能把所有可能性都写进字典。
生成器模式就是为了解决这个问题。它允许你用程序逻辑动态产生候选密码,从而覆盖字典中没有的规则组合。
5.2 设计思路
caveman 的生成器扩展点本质上是一个“能够产出候选密码序列”的组件。你在 C# 中实现相应接口后,工具会在破解循环中不断从你的生成器里获取下一个候选密码。
下面是一个表达设计思路的示例,接口名称和命名空间请以实际版本为准:
csharp复制// 文件路径:src/MyGenerator/MyGenerator.cs
public class MyGenerator : IPasswordGenerator
{
public IEnumerable<string> Generate()
{
// 按规则生成候选密码:prefix + 三位数字
for (int i = 0; i < 1000; i++)
{
yield return $"prefix{i:000}";
}
}
}
这段代码的意思是:生成从 prefix000 到 prefix999 共 1000 个候选密码。yield return 是 C# 的迭代器语法,可以让生成器“惰性”产生密码,不需要一次性把所有候选密码放到内存中。
实现生成器后,需要将对应类编译进 caveman 的加载路径。具体如何注册和启用,请阅读仓库 README 中关于 custom generator 的说明。
5.3 实际项目中的注意事项
编写自定义生成器时,有几个容易被忽略的问题:
- 生成顺序会影响破解速度。如果目标密码大概率以
abc开头,就把这类规则放在前面。 - 生成器要尽量“轻”。不要在生成器里做复杂 IO 或网络请求,否则会拖慢整个破解循环。
- 候选密码集合要可控。无上限的穷举会让任务永远跑不完,建议给生成器加上数量上限或终止条件。
- 注意去重。如果字典和生成器产生了重复密码,会造成无意义的重复计算。
6. 神经网络密码猜测模块
6.1 模块定位
caveman 仓库中的 Caveman.Neural 相关代码,展示了如何用神经网络模型来改进密码猜测顺序。它的核心思想是:真实世界中用户的密码并不是均匀分布的随机字符串,而是有规律可循的,比如包含姓名、生日、常见单词、键盘相邻键组合等。
如果能够训练一个模型,让它学习大量已泄露密码中的模式,那么模型就可以对“下一个候选密码是什么”给出概率排序。破解工具优先尝试概率高的密码,命中率会显著提升。
6.2 训练数据与模型
这类神经网络模型通常使用公开的密码泄露数据集进行训练,例如 RockYou 等历史上已经公开的研究数据集。这里必须强调两点:
- 只使用公开、合法的研究数据集。
- 不要将未授权获取的真实用户密码用于训练,这既涉及法律风险,也涉及严重的隐私问题。
模型的训练流程大致是:
- 将明文密码切分为字符序列。
- 将字符映射为向量。
- 使用循环神经网络或 Transformer 类模型学习下一个字符的概率分布。
- 在生成阶段,按概率采样或贪心生成候选密码。
6.3 与暴力破解的配合
在实际使用中,神经网络模块并不是取代字典和生成器,而是调整候选密码的优先级。你可以先让模型生成一批高概率密码,再把这批密码导入字典,或者直接让破解引擎按模型给出的概率顺序进行尝试。
这种方式的好处是:能覆盖字典中没有、但人类很可能使用的密码模式;坏处是:模型体积和推理时间会带来额外开销,需要根据测试环境权衡。
7. 常见问题与排查思路
在使用 caveman 的过程中,最容易遇到的还是环境、参数和文件路径三类问题。这里整理成一张排查表:
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
dotnet build 编译失败 |
SDK 版本与项目目标框架不匹配 | 查看 global.json 和 .csproj,安装对应 SDK |
| 恢复 NuGet 包失败 | 网络问题或源不可用 | 配置 NuGet 源或镜像,重新 dotnet restore |
| 可执行文件找不到 | 目标框架路径与预期不一致 | 使用 pwd、ls 查看实际输出目录 |
| 运行后没有破解结果 | 字典不含目标密码或算法错误 | 先在字典中加入已知密码验证流程 |
| 中文密码读取乱码 | 字典文件编码不是 UTF-8 | 使用 UTF-8 无 BOM 重新保存 |
| 小字典很快跑完 | 候选密码集合太小 | 换更大字典,或使用生成器扩展候选空间 |
| 想用 GPU 加速 | caveman 主要走 CPU 计算 | 确认项目是否支持 GPU,否则考虑 Hashcat 等工具 |
| 自定义生成器不生效 | 接口签名或注册方式不对 | 仔细阅读 README 中扩展说明,对照示例代码 |
排查问题的通用思路,可以按下面顺序进行:
- 先看报错信息本身,确认是编译错误、运行时错误还是业务逻辑问题。
- 用最小化案例复现,比如只破解一个已知哈希。
- 检查文件路径、文件编码、参数大小写。
- 查看
--help,确认当前版本支持的参数名。 - 对照 README 中的示例命令,逐项匹配。
8. 最佳实践与工程建议
8.1 安全边界优先
使用 caveman 这类工具,最重要的工程实践不是性能调优,而是边界控制:
- 只在你有授权的目标上运行。
- 优先在隔离的虚拟机或容器中测试。
- 不把真实用户哈希随意复制到共享环境。
- 破解得到的明文密码,应在验证后立即销毁,不要留存。
8.2 数据准备与字典管理
字典质量直接决定字典攻击的命中率。建议维护一套分层字典:
- 基础弱口令字典:
123456、password、admin等。 - 行业定制字典:根据目标系统属性添加自定义词条。
- 规则变体字典:在基础字典基础上生成大小写、数字、符号组合。
注意,字典文件要统一使用 UTF-8 编码,每行一个密码,避免多余空格和 BOM。
8.3 性能调优方向
caveman 主要使用 CPU 多线程,因此:
- 调整线程数或池大小前,先确认 CPU 核心数。
- 在测试机上跑基准用例,观察 CPU 占用和破解速度。
- 哈希算法不同,计算开销差异很大,不要拿 MD5 的速度预期去套 SHA512。
如果后续需要大规模 GPU 破解,建议评估 Hashcat 等 GPU 工具,caveman 更适合 CPU 环境下的 .NET 集成场景。
8.4 日志与结果记录
安全测试中,可复现性很重要。建议运行破解任务时记录以下信息:
- 目标哈希来源和授权范围。
- 使用的字典路径和版本。
- 使用的算法和参数。
- 开始时间、结束时间、尝试次数。
- 最终命中的密码列表。
这样生成的结果报告,既便于内部审核,也能满足合规要求。
8.5 与团队工具链集成
对于 .NET 团队,可以将 caveman 的核心库封装为内部安全测试服务,提供给 QA 或安全团队使用,而不是让每个人直接操作命令行。封装时要注意:
- 不要把明文密码写入日志。
- 统一封装授权校验逻辑。
- 提供清晰的 API 文档和返回值结构。
9. 总结
caveman 是一个适合 .NET 开发者学习和二次开发的密码暴力破解框架。它没有复杂的 GPU 集群要求,核心逻辑清晰,支持字典、自定义生成器和神经网络密码猜测,能够覆盖从基础弱口令检测到规则穷举的多种测试场景。
通过本文,你了解了它的项目定位、核心破解流程、构建方式和基本用法,也看到了自定义生成器的扩展思路以及神经网络模块的工作方式。实际使用中要特别注意两点:一是严格遵守授权边界,二是先使用已知哈希验证工具流程,再处理真实测试数据。
如果接下来想深入研究,可以往这几个方向继续学习:密码学中哈希算法的特性与区别;.NET 多线程并行计算的优化方式;公开密码数据集的模式分析与神经网络建模;以及 Hashcat、John the Ripper 等主流工具与 caveman 的横向对比。
安全测试工具本身是中立的,代码能做什么和代码被允许做什么,是两件完全不同的事。希望这篇文章能帮助你规范、高效地完成授权的安全测试工作,也能让你对暴力破解工具的内部原理有更清晰的理解。
