news 2026/9/17 5:06:04

Proxmark3 HF_CRAFTBYTE 独立模式:ISO14443A 卡 UID 窃取与即时仿真原理及实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Proxmark3 HF_CRAFTBYTE 独立模式:ISO14443A 卡 UID 窃取与即时仿真原理及实战指南

Proxmark3 HF_CRAFTBYTE 独立模式:ISO14443A 卡 UID 窃取与即时仿真原理及实战指南

【免费下载链接】proxmark3Iceman Fork - Proxmark3项目地址: https://gitcode.com/GitHub_Trending/pr/proxmark3

HF_CRAFTBYTE 是 Proxmark3 的一个 HF(13.56 MHz)独立(Standalone)模式:设备无需连接主机电脑,即可持续扫描进入感应区的 ISO14443A 卡片,捕获其 UID/ATQA/SAK,并依据卡片类型自动切换为对应的仿真器,向读卡器回放该 UID。阅读本文后,你将理解"仅凭 UID 鉴权"的访问控制系统为何可被低成本绕过,掌握该模式的编译烧录方法(make STANDALONE=HF_CRAFTBYTE -j+./pm3-flash-fullimage)、按钮交互约定与状态机,并能在源码层面解释它如何调用iso14443a_select_card()完成防碰撞读卡、如何通过 ATQA/SAK 特征表判定 MIFARE 卡型,以及SimulateIso14443aTag()如何以预编译调制响应实现低延迟仿真。

模式定位:独立模式生态中的 UID 窃取器

HF_CRAFTBYTE 由 Anze Jensterle 开发,面向通用硬件(Generic Proxmark3),即不依赖 RDV4 扩展板、外部闪存或蓝牙,任何标准 Proxmark3 硬件均可运行。它属于 Standalone 模式文档索引 中列出的 HF 模式之一:

Mode ID文档描述硬件
HF_CRAFTBYTECraftByte UID StealerScan and emulate ISO14443A UIDsGeneric

与生态中其他模式相比,HF_CRAFTBYTE 的定位非常聚焦:

  • 做完整数据区读取(对比 HF_AVEFUL 可读取/仿真整个 Ultralight 数据);
  • 做密钥攻击或整卡克隆(对比 HF_MATTYRUN 的 MIFARE Classic 密钥检查、转储与仿真);
  • 它只关心一件事:把"卡是谁"(UID)这一身份标识偷过来并原样回放。

这一取舍正是它作为安全演示工具的价值所在:许多门禁系统主要(甚至唯一)依赖 NFC 卡的 UID 做身份识别,而完全不执行任何密码学鉴权(如 MIFARE Classic 的 Crypto-I/II 密钥认证、Ultralight-C 的 EAS 认证)。HF_CRAFTBYTE 通过捕获并回放 UID,直观演示了纯 UID 鉴权可被轻易突破的事实。该模式在 CHANGELOG 中登记为 "AddedHF_CRAFTBYTEstandalone mode that reads and emulates 14a UID (@craftbyte)"。

工作流程:READ → EMULATE 双态循环

原文档给出的核心流程是两步:

  1. READ:执行 ISO14443A 防碰撞(anticollision),读取卡片的 UID、ATQA、SAK;
  2. EMULATE:使用捕获到的 UID 在目标读卡器上仿真该卡。

模式从 ATQA/SAK 自动判定卡片类型,并据此配置仿真参数。对应的状态机如下:

LED 使用极少(保持"读取/仿真"循环的专注),交互完全靠按钮与 USB。

按钮控制与退出机制

操作效果
按住 1000ms(单击级)在 READ 与 EMULATE 两个状态间切换;持续不放则退出
USB 命令退出 standalone 模式

对照源码 hf_craftbyte.c,按钮处理位于内层循环顶部:

button_pressed = BUTTON_HELD(1000); if (button_pressed != BUTTON_NO_CLICK || data_available()) break;
  • BUTTON_HELD(1000)等待 1000ms 判断按键状态:若期间产生按键事件,内层for(;;)循环跳出,重新进入状态判定;
  • 外层主循环在循环顶部检查data_available()——只要主机通过 USB 发来任何命令(客户端发送data_available()即可打断),RunMod()立即break退出,回到常规固件行为;
  • 内层循环末尾if (button_pressed == BUTTON_HOLD) break;处理"持续长按":当按键保持时长达到 hold 判定阈值(超过 1000ms 单击窗口仍不松手)时,跳出外层主循环,打印-=[ exit ]=-并关闭 LED,完成退出。

因此实际操作体验是:短按约 1 秒切换"扫描/仿真",一直不松手退出模式;任何 USB 命令也会立即退出。

源码剖析:READ 阶段——防碰撞读卡

RunMod()的入口动作是加载 HF FPGA 比特流并进入主循环:

void RunMod(void) { StandAloneMode(); Dbprintf(_YELLOW_("HF CRAFTBYTE mode started")); FpgaDownloadAndGo(FPGA_BITSTREAM_HF); for (;;) { WDT_HIT(); // exit from RunMod, send a usbcommand. if (data_available()) break; ...

注意三个要点:

  1. FpgaDownloadAndGo(FPGA_BITSTREAM_HF)载入 HF 模式 FPGA bitstream(fpga/fpga_pm3_hf.bit一类产物),此后 FPGA 以 HF 射频模式工作;
  2. 每轮WDT_HIT()喂狗,避免看门狗复位;
  3. data_available()是 standalone 模式被主机"夺回控制权"的唯一 USB 通道,符合 Standalone 开发指南 对RunMod()的强制要求。

READ 状态下,每次扫描尝试调用 ISO14443A 读卡器流程:

iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD); if (iso14443a_select_card(NULL, &card, NULL, true, 0, true) == false) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_D_OFF(); SpinDelay(500); continue; } else { Dbprintf("Found card with SAK: %02X, ATQA: %02X %02X, UID: ", card.sak, card.atqa[0], card.atqa[1]); Dbhexdump(card.uidlen, card.uid, 0); state = STATE_EMUL; }

参数含义可对照 iso14443a.h 中的声明:

int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats);
  • anticollision = true:执行完整防碰撞/选卡序列;
  • num_cascades = 0:不预设级联层数,由实际防碰撞结果决定(1 级 = 4 字节 UID,2 级 = 7 字节,3 级 = 10 字节);
  • no_rats = true:跳过 RATS/ATS 交换——对纯 UID 窃取场景没有必要,可缩短卡片驻留时间窗口。

iso14443a_select_card()在 iso14443a.c 中直接委托给iso14443a_select_cardEx(),后者(见 iso14443a.c)按标准 14443A 时序依次完成:REQA 获取 ATQA(含对 Fudan 11RF005 类芯片的 8B 选卡重读 UID 特判)、逐级位仲裁防碰撞提取 CUID/UID、SECTAG/SEL 选卡获得 SAK;no_rats为真时不再请求 ATS。结果回填到iso14a_card_select_t card结构:card.uid[0..9]card.uidlencard.atqa[0..1]card.sak。捕获成功后打印 SAK/ATQA/UID 并转入仿真状态;失败则关闭 FPGA(FPGA_MAJOR_MODE_OFF)、关灯,500ms 后再来一轮——这是一个"非阻塞轮询 + 按钮/USB 可随时打断"的扫描循环。

卡片类型自动识别:ATQA/SAK 特征表

这是本模式最有信息量的部分。识别逻辑是一段按(sak, atqa[0], atqa[1])三元组精确匹配的分支链,位于 hf_craftbyte.c:

判定条件(源码字面值)打印的卡型仿真参数tagType
sak == 0x08 && atqa[0] == 0x04 && atqa[1] == 0x00Mifare Classic 1k1
sak == 0x08 && atqa[0] == 0x44 && atqa[1] == 0x00Mifare Classic 4k8
sak == 0x00 && atqa[0] == 0x44 && atqa[1] == 0x00Mifare Ultralight2
sak == 0x20 && atqa[0] == 0x04 && atqa[1] == 0x03Mifare DESFire3
sak == 0x20 && atqa[0] == 0x44 && atqa[1] == 0x03Mifare DESFire Ev1/Plus/JCOP3
其他任何组合未识别 → 回退1(默认按 Mifare Classic 仿真)
if (card.sak == 0x08 && card.atqa[0] == 0x04 && card.atqa[1] == 0) { DbpString("Mifare Classic 1k"); SimulateIso14443aTag(1, flags, card.uid, 0); } else if (card.sak == 0x08 && card.atqa[0] == 0x44 && card.atqa[1] == 0) { DbpString("Mifare Classic 4k "); SimulateIso14443aTag(8, flags, card.uid, 0); } else if (card.sak == 0x00 && card.atqa[0] == 0x44 && card.atqa[1] == 0) { DbpString("Mifare Ultralight"); SimulateIso14443aTag(2, flags, card.uid, 0); } else if (card.sak == 0x20 && card.atqa[0] == 0x04 && card.atqa[1] == 0x03) { DbpString("Mifare DESFire"); SimulateIso14443aTag(3, flags, card.uid, 0); } else if (card.sak == 0x20 && card.atqa[0] == 0x44 && card.atqa[1] == 0x03) { DbpString("Mifare DESFire Ev1/Plus/JCOP"); SimulateIso14443aTag(3, flags, card.uid, 0); } else { Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation"); SimulateIso14443aTag(1, flags, card.uid, 0); }

两点值得注意:

  • 回退策略:无法识别的卡默认按 Mifare Classic(tagType=1)仿真并给出提示,保证"总能仿真点什么",但也意味着对非 MFC 卡,后续若读卡器发起密钥认证,仿真大概率无法通过——对纯 UID 门禁无影响;
  • 识别粒度:这里用的是捕获到的真实 ATQA/SAK 做精确匹配,而不是猜测。ATQA 第二字节的容量位(0x44vs0x04)与 SAK 的组合是 14443A 生态里区分 MFC/UL/DESFire 家族的常用指纹,从源码结构看,该特征表与 hf_young.c 等同类模式的判定分支保持一致。

EMULATE 阶段:UID 注入标志与仿真入口

进入仿真前,先把 UID 长度编码进 flags:

uint16_t flags = 0; FLAG_SET_UID_IN_DATA(flags, card.uidlen); if (IS_FLAG_UID_IN_EMUL(flags)) { Dbprintf("Unusual UID length, something is wrong. Try again please."); state = STATE_READ; continue; }

这两个宏定义在 pm3_cmd.h:

#define FLAG_SET_UID_IN_DATA(flags, len) \ { \ flags = (flags & (~FLAG_MASK_UID)) | \ (len == 4 ? FLAG_4B_UID_IN_DATA : (len == 7 ? FLAG_7B_UID_IN_DATA : (len == 10 ? FLAG_10B_UID_IN_DATA : FLAG_UID_IN_EMUL))); \ } #define IS_FLAG_UID_IN_EMUL(flags) ((flags & FLAG_MASK_UID) == FLAG_UID_IN_EMUL)

即 UID 长度只允许 4 / 7 / 10 字节三种合法值(对应 14443A 的一级/两级/三级级联);若防碰撞读出的uidlen落在三者之外(异常情况),FLAG_SET_UID_IN_DATA会退化为FLAG_UID_IN_EMUL,此时IS_FLAG_UID_IN_EMUL()为真,代码打印 "Unusual UID length, something is wrong." 并打回 READ 状态重扫——这是一道防御性校验,防止畸形 UID 污染仿真。

真正的仿真工作交给SimulateIso14443aTag(tagType, flags, card.uid, 0),声明于 iso14443a.c:

void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads) { SimulateIso14443aTagEx(tagType, flags, useruid, exitAfterNReads, NULL, 0, NULL, 0, NULL, 0, false); }

tagType就是上表中的 1/2/3/8:它告诉仿真器"以哪种卡的身份应答",例如 MFC 会响应 Crypto-I/II 选块/认证请求的帧结构,Ultralight 会按页读/页写应答,DESFire 则进入desfiresim体系。第四个参数exitAfterNReads = 0表示不做读取次数限制,仿真循环一直运行直到外部状态改变(如按钮被按下,仿真任务随之被RunMod的状态机接管回 READ)。

一个关键的工程细节在于仿真的低延迟预编译SimulateIso14443aTagEx()初始化阶段会把 12 组"预编译"应答帧(ATQA、三级防碰撞 UID、三级 SAK、ATS、版本、签名、PPS、PACK 等)连同 CRC 一起预先调制进位级缓冲区——源码注释明确写道 "These exist for speed reasons. There are no time in the anti collision phase to calculate responses."(见 iso14443a.c)。14443A 防碰撞阶段对位级时序极其苛刻,任何现场计算都会破坏帧同步;HF_CRAFTBYTE 正是依赖这一机制,才能让"扫到即仿真"在毫秒级完成握手,对目标读卡器表现得与真实卡片无异。

编译与烧录

按照 hf_craftbyte.md 给出的构建步骤:

make clean make STANDALONE=HF_CRAFTBYTE -j ./pm3-flash-fullimage
  • make clean强制全量重编,避免残留其他 standalone 模式的目标文件;
  • STANDALONE=HF_CRAFTBYTE使构建系统注入WITH_STANDALONE_HF_CRAFTBYTE编译宏。该宏与源文件的绑定在 Makefile.inc 中:
    # WITH_STANDALONE_HF_CRAFTBYTE ifneq (,$(findstring WITH_STANDALONE_HF_CRAFTBYTE,$(APP_CFLAGS))) SRC_STANDALONE = hf_craftbyte.c endif
  • ./pm3-flash-fullimage将完整镜像刷入设备。

需要牢记的约束(来自 Standalone 开发指南):固件一次只能编译进一个 standalone 模式(除非使用 DANKARMULTI 多模式加载器)。HF_CRAFTBYTE 已在 Makefile.hal 的模式清单(STANDALONE_MODES += ... HF_CRAFTBYTE ...)与帮助表中登记:

| HF_CRAFTBYTE | UID stealer - Emulates scanned 14a UID |

同时它也被 tools/build_all_firmwares.sh 列入批量构建列表,并登记在 4_Advanced-compilation-parameters.md 的编译参数表中。编译产物烧入后,按下设备按钮长按可触发 LED 提示并进入该独立模式;连接 USB 时还能在客户端看到模式运行时的调试输出(如 "Scanning..."、捕获到的 SAK/ATQA/UID),便于验证工作状态。

实战要点与局限

结合源码行为,使用 HF_CRAFTBYTE 时有以下几点实际观察依据:

  • 适用目标:仅以 UID 做判定的 14443A 门禁/考勤/储物柜系统。仿真器会完整应答防碰撞握手并回放 UID,读卡器在只核对 UID 的场景下无法分辨真假卡;
  • 不适用目标:读卡器一旦发起密钥级鉴权(MFC 的 Crypto-I/II 认证、Ultralight-C 的 EAS 认证、DESFire 的 AES 认证),本模式不具备密钥材料,无法完成后续会话。要绕过这类鉴权应改用具备数据读取/密钥攻击能力的模式(如 HF_AVEFUL、HF_MATTYRUN、HF_COLIN);
  • 未识别卡型:回退为 Mifare Classic 仿真,UID 仍然被回放,但卡型相关行为可能与原卡不一致;
  • UID 长度异常:防碰撞得到非 4/7/10 字节的 UID 时会被拦截并重扫,不会带着脏数据进入仿真。

相关模式与延伸阅读

  • Aveful UL Reader — 完整的 Ultralight 数据读取/仿真(不止 UID);
  • MattyRun MFC Clone — MIFARE Classic 完整攻击(密钥 + 数据);
  • Young MFC Sniff/Sim — MIFARE UID 捕获与双 bank 存储;
  • Standalone Modes 开发指南 — 如何为 Proxmark3 实现新的 standalone 模式(ModInfo()/RunMod()约定、Makefile 注册流程);
  • 核心实现与库:hf_craftbyte.c、iso14443a.c、pm3_cmd.h。

HF_CRAFTBYTE 的全部逻辑集中在一个约 120 行的源文件中,是理解 Proxmark3 standalone 模式骨架(FPGA 加载、WDT_HITdata_available()退出协议、SimulateIso14443aTag仿真接口)与 ISO14443A 防碰撞时序交互的极佳范例,也是演示"UID 即身份"这类弱鉴权设计缺陷的最小化、可复现工具。

【免费下载链接】proxmark3Iceman Fork - Proxmark3项目地址: https://gitcode.com/GitHub_Trending/pr/proxmark3

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 5:02:17

WiFi图标消失不用慌:从软件到硬件的完整修复指南

说实话,干了这么多年装机维护,遇到最多的情况之一就是“网络重置后WiFi图标不见了”或者“电脑恢复出厂后无线网络直接消失”。这问题看着小,真碰上的时候非常折腾人,尤其是在急着联网干活的时候,网线一拔、图标一消失…

作者头像 李华
网站建设 2026/9/17 5:01:39

Dynamics 365 FO 建表全指南:从AOT到数据库同步的完整流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/17 5:01:35

DPABI fMRI预处理中NIfTI头文件写入错误的解决方案

1. 问题现象与背景解析最近在使用DPABI进行fMRI数据预处理时,不少同行遇到了一个典型报错:"错误使用 nifti/create (line 26) Unable to write header for..."。这个错误通常发生在协变量分析阶段,表现为程序突然中断并弹出红色错误…

作者头像 李华
网站建设 2026/9/17 5:00:13

AD域管理升级实战:从脚本运维到可审计可追溯的企业级运营

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/17 4:59:54

Buck电路滑模控制设计与Simulink仿真实践

1. 项目背景与核心价值Buck电路作为电力电子领域最基础的DC-DC降压拓扑,在电源适配器、车载供电、工业控制等领域应用广泛。但传统PID控制在负载突变或输入电压波动时容易出现超调、振荡等问题。去年我在设计一款医疗设备电源模块时,就遇到过输出纹波超标…

作者头像 李华