ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Proxmark3 HiTag2 破解实战:ht2crack2 预计算表攻击——从构建 1.2TB 时间换空间表到恢复 48 位密钥

2026/9/17 14:04:19 拓冰建站 浏览量
Proxmark3 HiTag2 破解实战:ht2crack2 预计算表攻击——从构建 1.2TB 时间换空间表到恢复 48 位密钥 Proxmark3 HiTag2 破解实战ht2crack2 预计算表攻击——从构建 1.2TB 时间换空间表到恢复 48 位密钥【免费下载链接】proxmark3Iceman Fork - Proxmark3项目地址: https://gitcode.com/GitHub_Trending/pr/proxmark3本篇围绕 Proxmark3Iceman Fork仓库中 ht2crack2 套件 展开讲解 HiTag2 攻击 2时间/空间换钥的完整工程流程如何调参编译、如何在一块 1.5TB 磁盘上构建并排序 2^37 条 PRNG 状态的预计算表、如何用生成的测试向量验证表、以及最终如何用真实采集的 2048 位密钥流搜索出 PRNG 状态并回滚恢复 48 位密钥。读完本文你可以掌握这套时间换空间攻击从表构建到密钥恢复的每一步命令、参数含义并理解表分桶、跳跃表和状态回滚背后的源码级原理。一、ht2crack2 在 HiTag2 破解体系中的定位HiTag2 是汽车无钥匙进入RWDremote keyless entry领域常见的 125kHz LF 加密标签。仓库 tools/hitag2crack/README.md 将该目录下的工具集称为 HiTag2 Cracking Suite它实现了多篇安全研究论文中描述的多种攻击作者为 Kevin Sheldrake 等人攻击 1nonce 重放 长度扩展攻击Proxmark3 充当 RWD 重放同一组加密 nonce 与挑战响应在设备侧恢复密钥流攻击 2时间/空间换钥攻击使用一张预计算的 2^37 条 PRNG 状态表由 Proxmark3 恢复 2048 位密钥流后在表中查找匹配——这正是 crack2 子目录ht2crack2实现的攻击攻击 3 / 4 / 5 系列分别基于 PRNG 输出偏置的密码分析攻击、快速相关攻击以及基于 HiTag2 Hell 的实现与 OpenCL GPU 版本。ht2crack2 的官方定位在 tools/hitag2crack/README.md 中有明确说明这些攻击没有 Proxmark3 客户端命令实现只有一套独立的可执行程序需要在你自己的系统上编译运行从活动系统提取所需数据也没有现成的便捷手段官方建议使用 RFIDler 设备并直言 Proxmark3 的lf hitag sniff命令还不够成熟到能采集所需数据。因此 ht2crack2 的输入是离线数据一段已知 UID 与加密 noncenR对应的 2048 位密钥流文件。crack2 目录包含四个可执行程序的源码与两个测试脚本其 Makefile 定义了完整的构建目标BINS ht2crack2buildtable ht2crack2search ht2crack2gentest ht2crack2search_multi INSTALLTOOLS $(BINS) include ../../../Makefile.host四个可执行文件分别是程序作用源码ht2crack2buildtable构建并排序 2^37 条 PRNG 状态表约 1.2TBht2crack2buildtable.cht2crack2gentest用已知的 key/UID/nR 生成测试用密钥流文件ht2crack2gentest.cht2crack2search在排序后的表中搜索匹配的 PRNG 状态并恢复密钥ht2crack2search.cht2crack2search_multi多线程版本的搜索程序Iceman 2024 年加入README 未提及ht2crack2search_multi.cMakefile 通过 Makefile.host 统一平台处理对 MinGW 额外加-D_ISOC99_SOURCE以获得 GNU printf 支持例如%z格式并链接-lpthread多线程构建/排序所必需。README 中Makefile 面向 Linux在 Mac 上编译需交换 LIBS 行的说法属于较早版本的构建方式从当前源码结构看平台差异已由Makefile.host集中处理。二、编译与三个关键参数构建入口是修改 ht2crack2buildtable.c 头部的三个宏然后执行make clean make1. DATAMAX每桶内存大小决定总内存占用// DATAMAX is the size of each bucket (bytes). There are 65536 buckets so choose a value such that // DATAMAX * 65536 RAM available. #define DATAMAX 196600 // around 192K rounded down to a power of 10表在构建时按密钥流前两个字节分成65536 个桶bucket每个桶在内存中占DATAMAX字节因此总内存需求为DATAMAX × 65536。README 给出的经验公式是Calculate DATAMAX free RAM available / 65536, and then round down to a power of 10.例如 16GB 内存的机器想留 12GB 给表12GB / 65536 196608向下取整到 10 的幂次得DATAMAX 196600即源码中的默认值。2. NUM_BUILD_THREADS构建线程数// NUM_BUILD_THREADS and NUM_SORT_THREADS are the number of threads to run concurrently. These should // ideally be equal to the number of virtual cores you have available. // // If sorting fails with a bus error then that is likely because your disk I/O cant keep up with // the read/write demands of the multi-threaded sorting. ... // // These MUST be a power of 2 for the maths to work - you have been warned! // Also, sort threads MUST be build threads or a horrible buffer overflow will happen! #define NUM_BUILD_THREADS 8 #define NUM_SORT_THREADS 8README 强调这两个值必须都是 2 的幂且NUM_BUILD_THREADS ≥ NUM_SORT_THREADS否则会可怕的缓冲区溢出。为什么必须是 2 的幂从 ht2crack2buildtable.c 可以看到原因总表规模 2^37 条要均分给 N 个线程代码用循环右移来实现除法maxentries maxentries 37; while (!(tnum 0x1)) { maxentries maxentries 1; tnum tnum 1; }即 1 线程 2^37 条、2 线程 2^36 条、4 线程 2^35 条、8 线程 2^34 条以此类推。排序阶段同理每个排序线程负责0x100 / NUM_SORT_THREADS个首字节区间见 sorttable若线程数不是 2 的幂整除分配就会错乱。README 还提醒如果排序阶段报 bus error多半是磁盘 I/O 跟不上多线程读写的速度网络磁盘尤其如此SATA/USB2/3 通常没问题此时应减少NUM_SORT_THREADS。三、运行 ht2crack2buildtable构建并排序 1.2TB 表运行条件与命令# 确保所在磁盘至少 1.5TB 空间 ./ht2crack2buildtable然后就是等很久可能要几天。运行期间会发生三件事程序创建table/目录树65536 个桶对应table/xx/yy.bin两级十六进制目录下的 65536 个文件边构建边追加写入每个文件逐渐长到约 20MB2^37 条 × 10 字节 / 65536 个桶 ≈ 20MB与源码注释的 1.2TB 总量吻合2^37 × 10 ≈ 1.37TB构建完成后排序线程逐个读取table/中的文件用qsort按条目内容排序后写入平行的sorted/目录树sorted/xx/yy.bin并删除原始未排序文件全部完成后程序退出你就得到了用于搜索的排序表。表条目结构与分桶原理源码级每条记录逻辑上由 12 个字节组成write_ks_s 生成其中 10 字节有效数据// writebuf(buf, ks1, 3); 前 24 位输出流 ks1 的低 3 字节 // writebuf(buf 3, ks2, 3); 后 24 位输出流 ks2 的 3 字节 // writebuf(buf 6, shiftreg, 6); 48 位 PRNG 状态6 字节 // store(buf);而 store() 会把整条记录前 2 字节取出作为桶索引d_1 data[0]; d_2 data[1]桶号 d_1*0x100 d_2只把剩余10 字节DATASIZE 104 字节流 6 字节状态写入内存桶桶满DATAMAX字节就O_APPEND追加到table/%02x/%02x.bin。这个设计使索引信息天然编码在文件路径里——搜索时只需根据密钥流的前两个字节直接定位到唯一文件文件内再用bsearch二分查找这正是表能分桶后逐文件排序的关键。桶内写入用每桶一把pthread_mutex_t保护多线程构建时不同线程写同一桶会串行化避免交错写坏数据。跳跃表快进 2^37 步不逐位模拟直接对每个候选状态模拟 LFSR 太慢源码用两张跳跃表实现 O(48) 的快进。builddi() 预先算出 48 个基状态每一位独立置 1各自快进steps步后的状态jumpnsteps() 利用 LFSR 的线性性把当前状态的每一位与对应基状态做条件异或等价于一步快进steps步bitmask 1; for (i 0; i 48; i) { if (hstate-shiftreg bitmask) { output output ^ thisd[i]; } bitmask bitmask 1; }两张表分工不同见 main表 22048 步用于各线程定位自己的起始偏移——线程i从公共初始状态快进i × 2048步表 12048 × NUM_BUILD_THREADS 步用于循环中快进——N个线程从相隔 2048 步的不同偏移并发推进每轮各产出 1 条记录后前进2048 × N步互不重叠地覆盖整个 2^37 状态空间。每个桶内记录按 (流前 2 字节已编码进路径文件内按后续 4 字节流 6 字节状态) 排序datacmp用memcmp比较前DATASIZE - 6 4字节见下文搜索阶段的同款比较器。排序线程各自维护一块 50MB 排序缓冲逐文件 mmap 读入、qsort、写出sorted/对应文件后unlink原文件。四、用 ht2crack2gentest 验证表表建好后必须先自测不能跳过。ht2crack2gentest.c 用/dev/urandom随机生成 48 位 key、32 位 UID、32 位 nR然后hitag2_init(hstate, key, uid, nR)初始化 PRNGAPI 定义见 hitagcrypto.h48 位共享密钥 32 位序列号 32 位初始化向量hitag2_nstep(hstate, 64)跳过认证阶段消耗的 64 位输出对应 aR 响应 32 位 page 3 32 位循环 64 次输出 32 位共2048 位密钥流每行 8 个十六进制字符写入文件文件名即答案keystream.key-KEYVALUE.uid-UIDVALUE.nR-NRVALUE使用方式继承自 README# 生成 N 个测试文件 ./ht2crack2gentests NUMBER_OF_TESTS # 单测脚本自动从文件名解析 UID/nR/期望 key 并调用搜索程序 ./runtest.sh KEYSTREAMFILE # 或手动执行 ./ht2crack2search KEYSTREAMFILE UIDVALUE NRVALUE # 或一次跑完当前目录所有 keystream* 文件 ./runalltests.shruntest.sh 的解析逻辑值得注意它用cut从文件名反解参数UIDVecho $1 | cut -d- -f3 | cut -d. -f1 # keystream.key-K.uid-U.nR-N 的第 3 段 NRecho $1 | cut -d- -f4 # 第 4 段 KEYVecho $1 | cut -d- -f2 | cut -d. -f1 # 期望 key用于人工比对 ./ht2crack2search $filename $UIDV $NR而 runalltests.sh 就是一行for i in keystream*; do ./runtest.sh $i; done。README 提醒shell 脚本里的路径可以自行编辑以定位你的工具另外可以给你的sorted/目录建一个名为sorted的符号链接方便 ht2crack2search 找到表它硬编码了#define INPUTFILE sorted/%02x/%02x.bin。如果测试全部通过说明表是健全的。五、在真实密钥流中搜索密钥输入准备真实场景下需要三个输入2048 位密钥流文件用 RFIDler 从目标 RFID 标签恢复对应攻击 2 的修改版攻击 1 流程文件内容为每行 8 字符 hexUID标签 UID32 位 hex可通过 RFIDler 读取nR你提供给标签的加密 nonce32 位 hex。搜索命令./ht2crack2search KEYSTREAMFILE UIDVALUE NRVALUEUIDVALUE/NRVALUE允许带0x前缀源码会去掉。程序退出码为 0 表示找到 key输出 48 位密钥的十六进制形式。搜索算法拆解源码级ht2crack2search.c 的主流程是滑动 48 位窗口 → 分桶定位 → 二分查找 → 前后验证 → 状态回滚 → 恢复密钥加载loadrngdatammap 文件把 hex 文本逐 nibble 还原为二进制流得到约 256 字节密钥流滑窗findmatch从 bit 0 到bitlen-48逐位滑动每次取 6 字节作为候选cand。候选前 2 字节决定表文件sorted/xx/yy.bin后 4 字节作为二分查找键datacmp只比DATASIZE - 6 4字节。注意它按位滑动而非按字节——因为表中记录的 48 位流与真实密钥流之间的对齐位置未知验证testcand候选命中后不能轻信4 字节碰撞概率不小。代码把记录的 6 字节状态装入Hitag_Statebuildlfsr重建 LFSR然后向前或靠近流末尾时向后推进 48 位比对产生的 6 字节流与密钥流中紧邻候选之后或之前的 6 字节是否一致一致才确认回滚rollbackrng把状态rollback回退bitoffset位到认证后状态再回退 64 位认证输出 aR 32 位 page 3 32 位得到初始化状态。回退操作由 ht2crackutils.h 声明的rollback()实现恢复密钥recoverkey初始化状态的 48 位 shiftreg 中低 16 位是 key 的低 16 位高 32 位是nR XOR key的中间量再按 UID 逐位推演 32 步非线性函数fnf得到 32 位掩码bnR nRenc XOR b最后keyupper nRxork XOR nR拼出完整 48 位 key 并打印key hstate-shiftreg 0xffff; // key 低 16 位 nRxork (hstate-shiftreg 16) 0xffffffff; ... nR nRenc ^ b; keyupper nRxork ^ nR; key key | (keyupper 16);多线程版本 ht2crack2search_multiREADME 之外当前仓库还提供 ht2crack2search_multi.cIceman 2024 年加入与 mwalker33 讨论后实现。它与单线程版用法完全相同ht2crack2search_multi rngdatafile UID nR区别在于线程数自动取sysconf(_SC_NPROCESSORS_CONF)最少 2 个各线程按i thread_count交错分配滑窗偏移而不是各扫整个文件的不同区段用__atomic标志 全局互斥打印避免输出交错任一线程命中即全线程退出源码头部注释提醒测试时注意OS 页缓存会干扰性能测量同一组测试值第二次运行会显著更快。六、适用前提、限制与相关资源在使用 ht2crack2 之前请对照 tools/hitag2crack/README.md 的边界说明确认前提是否满足硬件数据获取ht2crack2 本身不接触射频。2048 位密钥流、UID 和 nR 需要从目标标签获取官方建议路径是 RFIDler 设备Proxmark3 的lf hitag sniff目前不足以采集所需数据仓库作者也明确欢迎在这方面的贡献资源门槛约 1.5TB 连续磁盘空间、数十 GB 级可用内存按 DATAMAX 公式、数天时间以及一个能编译多线程 C 程序的 Linux 环境Makefile 面向 LinuxMinGW 下已通过Makefile.host处理 printf 差异;表的一次性表与具体 key/UID 无关只依赖 HiTag2 PRNG 算法本身建一次可反复使用与其他攻击的关系ht2crack2 是攻击 2 的桌面端实现前提是你能拿到 2048 位密钥流。若只能采集多组 (nR, aR) 对应考虑攻击 3≥136 对或攻击 416–32 对见 crack3、crack4若已有两组 (nR, aR)攻击 5 系列crack5、crack5opencl可在 GPU 上直接恢复密钥密钥恢复后的下一步拿到 key 后Proxmark3 可以配置为 RWD 模拟角色捕获使用该 key 的标签标签可用标准 Proxmark3 命令复制——这部分在父级 README 中标注为 TODO尚未给出完整示例。仓库内与 ht2crack2 直接相关的核心文件汇总如下便于进一步深入文件内容tools/hitag2crack/crack2/README.md本套件的官方说明参数公式、命令、测试流程tools/hitag2crack/crack2/Makefile构建配置链接 pthread复用 Makefile.hosttools/hitag2crack/crack2/ht2crack2buildtable.c表构建/排序主程序DATAMAX 与线程数定义tools/hitag2crack/crack2/ht2crack2search.c单线程搜索与密钥恢复tools/hitag2crack/crack2/ht2crack2search_multi.c多线程搜索Iceman 2024tools/hitag2crack/crack2/ht2crack2gentest.c测试向量生成器tools/hitag2crack/crack2/runtest.sh / runalltests.sh测试驱动脚本tools/hitag2crack/common/hitagcrypto.h / hitagcrypto.cHiTag2 PRNG 参考实现双 48 位移位寄存器模型tools/hitag2crack/common/ht2crackutils.hrollback、buildlfsr、位序反转宏等工具声明【免费下载链接】proxmark3Iceman Fork - Proxmark3项目地址: https://gitcode.com/GitHub_Trending/pr/proxmark3创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考