【免费下载链接】Cybersecurity-Projects
Building 70 Projects ranging from beginner to advanced so anyone can — learn from, build upon, use as a reference, or even copy directly. Gamified Cybersecurity learning 👇
HashCracker 是 Cybersecurity-Projects 仓库中一个基于 C++23 实现的初学者级多线程哈希破解工具(位于 PROJECTS/beginner/hash-cracker),支持 MD5、SHA-1、SHA-256、SHA-512 四种哈希算法的字典攻击、暴力破解与规则变异攻击。本文将围绕该项目的演示文档 DEMO.md 展开,深入解析其两大核心攻击模式——内存映射字典攻击与规则驱动变异攻击的底层实现原理、CLI 操作方式与工程化细节,读完你既能照抄命令完成真实哈希破解演示,也能理解"10K 词表如何扩展成 20.1M 候选"这一规则引擎背后的数学与协程机制。
一、从 DEMO.md 出发:两大核心攻击模式一览
DEMO.md 用一句话概括了工具的用法:
./install.sh → hashcracker --hash <hash> --wordlist <list>并通过两个实战场景定义了文章的讨论范围:
| 演示场景 | 技术要点 | 运行效果 |
|---|---|---|
| Dictionary Attack(字典攻击) | 内存映射词表扫描、哈希类型自动检测、全核工作分区、实时进度条与 h/s 吞吐量 | 28 线程扫描 10.0K 词表,约 0.11 秒破解出 SHA-256 明文password,平均吞吐 46.9K h/s |
| Rule-Based Mutations(规则变异攻击) | 变异规则把 10K 词表扩展为 20.1M 候选,逐词应用首字母大写、leet 替换、数字追加、反转、大小写翻转等变换 | 28 线程处理 20.1M 候选,约 0.20 秒破解出 SHA-1 明文shadow,平均吞吐 5.5M h/s |
这两个截图(dictionary.png 与 rules.png)来自项目assets/目录,真实展示了两种攻击模式的终端输出。下面分别从实现原理层面拆解它们。
二、Dictionary Attack:内存映射词表 + 零竞争线程分区
2.1 零拷贝的内存映射文件读取
DEMO 强调"Memory-mapped wordlist scan"。对应实现位于 src/io/MappedFile.cpp 与 src/attack/DictionaryAttack.cpp。词表文件通过mmap直接映射进进程地址空间,扫描过程不经过用户态拷贝,这也是它能"zero-copy"处理超大词表的原因。
DictionaryAttack::create()的构建流程(DictionaryAttack.cpp):
- 通过
MappedFile::open(path)打开词表并获取data()指针与size(); - 在映射缓冲上逐字节统计
\n得到总行数(文件末尾无换行时补 1 行); - 按线程数将行数均分,余数行分配给编号靠前的线程(
my_line_count = lines_per_thread + (thread_index < remainder ? 1 : 0)); - 用
find_next_newline定位出每个线程的start_offset与end_offset字节区间。
next()负责逐行产出候选词(DictionaryAttack.cpp):从current_offset_扫描到下一个换行符,剥离行尾的\r以兼容 Windows 格式词表,跳过空行;分区耗尽时返回AttackComplete信号。这种设计让每个线程只遍历自己专属的字节区间,彼此零竞争,正对应 DEMO 中"work-partitioned across all cores"的描述。
2.2 哈希类型自动检测
DEMO 提到"auto-detected hash type"。实现位于 src/hash/HashDetector.cpp:先校验输入全部为十六进制字符,再按十六进制串长度匹配算法——32 位判定 MD5、40 位判定 SHA-1、64 位判定 SHA-256、128 位判定 SHA-512(长度常量定义在 src/config/Config.hpp)。非十六进制或长度不在枚举内则返回CrackError::InvalidHash。
因此 DEMO 中的 64 位哈希
5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8会被自动识别为 SHA-256;32 位哈希被识别为 MD5;40 位被识别为 SHA-1。
2.3 引擎如何调度多线程与进度显示
src/core/Engine.hpp 中的Engine::crack<H, A>模板函数驱动整个破解会话:
- 线程数取
cfg.thread_count,为 0 时回落到std::thread::hardware_concurrency()(DEMO 截图中显示 28 线程即由此得出); - 用
ThreadPool为每个线程创建独立的DictionaryAttack实例,各自消费不重叠的分区; - 每个 worker 将候选词交给模板
Hasher H(如SHA256Hasher)计算摘要,与目标哈希比对;首个命中线程通过SharedState::found原子标志通知其余线程停止; - 候选计数采用线程本地累加、每 1024 次迭代批量冲刷到原子计数器的策略,降低原子操作竞争(
(local_count & 0x3FF) == 0即 1024 的倍数检查); - 后台
std::jthread每 100ms(config::PROGRESS_UPDATE_MS)刷新一次进度条,实时显示候选进度、h/s 与 ETA,这就是 DEMO 截图中的"live progress bar and h/s throughput"。
2.4 字典攻击演示与验证
./install.sh hashcracker --hash 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8 \ --wordlist wordlists/10k-most-common.txt # ✔ CRACKED: password运行后界面(见 dictionary.png)显示:SHA-256 / Dictionary / 28 threads,候选总量 10.0K,进度条实时推进,最终输出CRACKED: password,耗时 00:00.11,平均 46.9K h/s。
三、Rule-Based Mutations:把 10K 词表扩展成 20.1M 候选
3.1 七类变异规则与"2005 倍"扩展的计算
DEMO 的核心卖点是:10K 词表经规则扩展后产生20.1M 候选。这一数字的底层逻辑来自 src/rules/RuleSet.cpp 中RuleSet::apply_all链式拼接的七类生成器:
| 规则 | 函数 | 行为 | 每个词产出数 |
|---|---|---|---|
| 首字母大写 | capitalize_first | password→Password | 1 |
| 全大写 | uppercase_all | password→PASSWORD | 1 |
| Leet 替换 | leet_speak | password→p@$$w0rd | 1 |
| 追加数字 | append_digits | pass→pass0…pass999 | 1000 |
| 前置数字 | prepend_digits | pass→0pass…999pass | 1000 |
| 反转 | reverse | password→drowssap | 1 |
| 大小写翻转 | toggle_case | 大写变小写、小写变大写 | 1 |
合计1+1+1+1000+1000+1+1 = 2005个变异候选/词。10K 词表 × 2005 ≈ 20.05M,与 DEMO 截图中显示的 20.1M 总量吻合(引擎的total_estimate也是按probe->total() * 2005预估,见 Engine.hpp)。
其中 Leet 替换映射表固定为a→@、e→3、i→1、o→0、s→$、t→7(定义于 RuleSet.cpp);数字追加/前置的上限由 Config.hpp 中的MAX_APPEND_DIGIT与MAX_PREPEND_DIGIT(默认 999)控制,即每词各生成0..999共 1000 个变体。
3.2 用 C++23 协程生成候选流
一个值得注意的实现细节是:RuleSet的所有规则方法都是C++23std::generator协程,通过co_yield逐个产出变异候选(见 RuleSet.hpp)。apply_all则用co_yield std::ranges::elements_of(...)把七个生成器串联成单一惰性候选流(RuleSet.cpp),避免为每个词一次性物化全部 2005 个字符串,内存占用与扫描速度因此显著优化。
3.3 RuleAttack:包装字典攻击的变异执行器
规则模式并不是独立的扫描逻辑,而是在 DictionaryAttack 之上叠加一层变异。见 src/attack/RuleAttack.cpp:
RuleAttack::create()内部先构造一个DictionaryAttack实例(同样按线程分区);load_next_word()对每个基础词调用RuleSet::apply_all生成全部变异存入mutations_缓冲,并把原词本身作为第一个候选(RuleAttack.cpp);next()依次弹出缓冲中的变异候选,缓冲耗尽后拉取下一个字典词;- 若开启
chain_rules,还会把首轮变异再次套用apply_all,产生"变异的变异",进一步扩大候选空间(以吞吐换覆盖率)。
哈希比对与盐处理(--salt支持前置/后置拼接)复用 Engine.hpp 的统一 worker 循环。
3.4 规则攻击演示与验证
hashcracker --hash ed9d3d832af899035363a69fd53cd3be8f71501c \ --wordlist wordlists/10k-most-common.txt --rules # ✔ CRACKED: shadow运行界面(见 rules.png)显示:SHA-1 / Rules / 28 threads,候选总量 20.1M,实时吞吐一度达到 8.4M h/s,最终约 0.20 秒破解出明文shadow。直观对比字典模式:同样的 28 线程,规则模式把候选规模放大了约 2000 倍,却以更高的 h/s 覆盖了远超纯词表的密码形态。
规则引擎的正确性由 tests/test_rules.cpp 验证:断言capitalize_first("password") == "Password"、leet_speak("password") == "p@$$w0rd"、append_digits("pass")恰好产出 1000 项(pass0..pass999)、apply_all("password")候选数大于 2000,并验证RuleAttack会把规则应用到每个字典词、chain_rules模式产出更多候选。
四、完整 CLI 参考与安装
4.1 安装
./install.sh(install.sh)按发行版自动安装依赖(g++/gcc-c++、CMake、ninja、libssl/openssl、libboost-program-options),以 release preset 构建并把二进制软链接到~/.local/bin/hashcracker。依赖 C++23 编译器与 Boost.Program_options。
4.2 命令行参数
main.cpp 通过boost::program_options解析以下参数:
| 参数 | 说明 | 默认值 |
|---|---|---|
--hash <hash> | 目标哈希(必填) | — |
--type <md5\|sha1\|sha256\|sha512\|auto> | 哈希算法,auto按十六进制串长度自动识别 | auto |
--wordlist, -w <path> | 词表路径(字典/规则模式必填) | — |
--bruteforce, -b | 启用暴力破解模式 | 关闭 |
--charset <lower,upper,digits,special> | 暴力破解字符集,可逗号组合 | lower,digits |
--max-length <N> | 暴力破解最大长度 | 6 |
--rules, -r | 对字典词应用变异规则 | 关闭 |
--chain-rules | 规则组合叠加(变异再变异) | 关闭 |
--salt <value>/--salt-position <prepend\|append> | 盐值及其拼接位置 | 无盐 /prepend |
--threads, -t <N> | 线程数,0表示自动取 CPU 核数 | 0(自动) |
--output, -o <path> | 将破解结果写入 JSON 文件 | — |
其中字符集由build_charset按 token 组装(main.cpp),对应常量CHARSET_LOWER/UPPER/DIGITS/SPECIAL定义于 Config.hpp。
4.3 自带演示哈希
README.md 提供了三个可立即复现的哈希:
| Hash | 类型 | 明文 |
|---|---|---|
5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8 | SHA-256 | password |
8621ffdbc5698829397d97767ac13db3 | MD5 | dragon |
ed9d3d832af899035363a69fd53cd3be8f71501c | SHA-1 | shadow |
# 纯字典攻击 hashcracker --hash 8621ffdbc5698829397d97767ac13db3 --wordlist wordlists/10k-most-common.txt # 规则变异攻击 hashcracker --hash ed9d3d832af899035363a69fd53cd3be8f71501c --wordlist wordlists/10k-most-common.txt --rules # 暴力破解(无词表) hashcracker --hash 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8 --bruteforce --charset lower --max-length 8仓库自带三份词表可直接使用:wordlists/10k-most-common.txt、wordlists/john-the-ripper.txt与wordlists/mixed_it.txt。
五、攻击模式的内部调用链小结
从 main.cpp 的dispatch_attack可以看出三种模式的选择逻辑与底层绑定:
--bruteforce → Engine::crack<H, BruteForceAttack> --rules → Engine::crack<H, RuleAttack> 默认 → Engine::crack<H, DictionaryAttack>而RuleAttack内部又包裹一个DictionaryAttack,因此规则攻击天然继承字典攻击的内存映射词表读取与线程分区能力,只是在上层多了一道RuleSet::apply_all变异流水线。哈希侧则由dispatch_hasher在MD5Hasher / SHA1Hasher / SHA256Hasher / SHA512Hasher四个具体EVPHasher之间运行时切换(main.cpp),与auto检测结果一一对应。
六、局限与使用边界
从实现看,本工具是教学与演示导向的破解器,使用时需注意:
- 验证目标合规:只应对自己拥有或明确授权测试的哈希进行破解,AGPL-3.0 许可下用于安全研究与学习;
- 检测能力有限:哈希类型按长度判定,无法区分同一长度家族内的变体;
--type可显式指定规避歧义; - 规则深度受限于
chain_rules:默认单轮规则约 2005 倍扩展,叠加--chain-rules可进一步放大候选空间,但以吞吐下降为代价; - 暴力破解空间:字符集与
--max-length组合是指数级增长,过大的参数会显著拉长耗时,适合小规模可枚举空间。
如需进一步了解背后的密码学概念、架构设计与扩展练习,可继续阅读该项目的 learn 系列文档;词表、单元测试与 CMake 构建配置均可在 PROJECTS/beginner/hash-cracker 目录下直接查阅与复现。
【免费下载链接】Cybersecurity-Projects
Building 70 Projects ranging from beginner to advanced so anyone can — learn from, build upon, use as a reference, or even copy directly. Gamified Cybersecurity learning 👇
相关推荐
hashcracker 实战指南:基于 C++23 策略模板架构的多线程哈希破解工具
hashcracker 实战指南:基于 C++23 策略模板架构的多线程哈希破解工具 hashcracker 是 Cybersecurity Projects
hash_extender:实现哈希长度扩展攻击的工具
hash_extender:实现哈希长度扩展攻击的工具 在网络安全领域,哈希长度扩展攻击是一种利用哈希算法弱点的高效攻击手段。今天,我要向大家推荐一个开源项目—
网络安全python-mini-projects 之 Zip_Bruter:基于多线程字典攻击的 ZIP 加密压缩包爆破工具解析
python mini projects 之 Zip_Bruter:基于多线程字典攻击的 ZIP 加密压缩包爆破工具解析 本篇文章围绕开源仓库 python m
示例工程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考