Flipper Zero NFC 黑客攻击 - cannon fooder
在上一篇文章中,我们了解了如何使用 Flipper Zero 实现透明阅读器。如果我们采用相同的概念,但这次实现一个透明的卡模拟器呢?我们可以像大炮一样使用 Flipper Zero,通过发送错误的请求来攻击数字堡垒,例如阅读器或智能手机。格式错误的命令、生命周期中不期望的命令、模糊测试、缓冲区溢出——没有极限!
1 - 背景
就像透明读卡器一样,我想从我的计算机使用其串行 CLI 与 Flipper 进行通信。计算机处理所有逻辑,这意味着它根据命令决定给出什么响应,例如使用 Python 脚本。
现在,关于卡片模拟器命令的实现,与读卡器相比,它本质上是一种镜像模式:
- 我们需要检测终端何时激活射频场。
- 我们需要检测终端何时停用 RF 场。
- 我们需要能够向终端接收/发送位。
- 我们需要能够向终端接收/发送字节。
除了一个让事情变得复杂的小细节。请记住,在卡/读卡器通信期间,读卡器充当主机,这意味着它是发起通信并发送命令的人。
因此,如果我们要创建一个卡片模拟器,它必须等待来自读卡器的事件。您可以将其视为服务器,而读者则充当客户端。我们需要将其编码到 Flipper Zero 中。
好吧,首先,让我们快速回顾一下使用 ISO 14443-A 的读卡器和卡之间的通信交换。
2 - 使用 ISO 14443-A 的读卡器和卡之间的通信交换
下面的图表总结了读卡器和通过 ISO 14443-A 进行通信的卡之间的主要交换。
+----------------+ +----------------+ | Reader | | Card | +----------------+ +----------------+ | | Field activation | | | | --- REQA (Request Command Type A) -------------> | | 26 | | | | <------------ ATQA (Answer to Request Type A) ---| | 04 00 | | | --- ANTICOLLISION Command ---------------------->| | | | <------------ UID (Unique Identifier) -----------| | | | --- SELECT [UID] Command ----------------------->| | | | <------------ SAK (Select Acknowledge) ----------| | | | --- RATS (Request for Answer To Select) -------->| | E0 50 BC A5 | | | | <------------ ATS (Answer To Select) ------------| | 0A 78 80 82 02 20 63 CB A3 A0 92 43 | | | | ---- [Opt] PPS (Proto and Parameter Selection) ->| | D0 73 87 | | | | <------------ [PPS Response] --------------------| | D0 73 87 | | | | --- TPDU [Encapsulated APDU Command] ----------->| | 0200A404000E325041592E5359532E444446303100E042 | | | | <------------ TPDU [Encapsulated APDU Response] -| | 00a404000e325041592e5359532e444446303100 |
现在的问题是,“我们如何在 Flipper 上实现所有这些?”
4 - Flipper 零实施
和我之前的文章一样,我将继续扩展文件applications/main/nfc/nfc_cli.c(请参阅我的分支上的文件)。
首先,一个快速的硬件点。对于 NFC 管理,Flipper Zero 使用 ST25R3916 芯片。这很棒,因为它允许我们创建非接触式读卡器和卡模拟器。该芯片自动处理发送从现场激活到防碰撞所涉及的命令。我们需要做的就是指定 ATQA、SAK、UID 及其要发回的长度。
Flipper 提供了函数 furi_hal_nfc_iso14443a_listener_set_col_res_data 来处理所有这些。
这就是为什么我向 Flipper 的 NFC CLI 添加了 3 个命令来配置这些元素:
- set_atqa
- set_sak
- 设置_uid
在开始仿真之前,我们将使用这些参数调用 furi_hal_nfc_iso14443a_listener_set_col_res_data。
+----------------+ +----------------+ | Reader | | Card | +----------------+ +----------------+ | | Field activation | | | | --- REQA (Request Command Type A) -------------> | | 26 | | | | <------------ ATQA (Answer to Request Type A) ---| | 04 00 | | | --- ANTICOLLISION Command ---------------------->| | | | <------------ UID (Unique Identifier) -----------| | | | --- SELECT [UID] Command ----------------------->| | | | <------------ SAK (Select Acknowledge) ----------| | | | --- RATS (Request for Answer To Select) -------->| | E0 50 BC A5 | | | | <------------ ATS (Answer To Select) ------------| | 0A 78 80 82 02 20 63 CB A3 A0 92 43 | | | | ---- [Opt] PPS (Proto and Parameter Selection) ->| | D0 73 87 | | | | <------------ [PPS Response] --------------------| | D0 73 87 | | | | --- TPDU [Encapsulated APDU Command] ----------->| | 0200A404000E325041592E5359532E444446303100E042 | | | | <------------ TPDU [Encapsulated APDU Response] -| | 00a404000e325041592e5359532e444446303100 |
接下来,使用函数 furi_hal_nfc_set_mode 将 Flipper Zero 设置为卡模拟器模式。这次,我们指定模式 FuriHalNfcModeListener,对于技术,我们使用标准值:FuriHalNfcTechIso14443a、FuriHalNfcTechIso14443b 和 FuriHalNfcTechIso15693。
最后,为了开始模拟,我实现了命令 run_emu,它将启动一个无限循环,等待附近的读取器。事件监听由函数furi_hal_nfc_listener_wait_event处理。
if(g_NfcTech == FuriHalNfcTechIso14443a) { furi_hal_nfc_iso14443a_listener_set_col_res_data(g_uid, g_uid_len, g_atqa, g_sak); fdt = ISO14443_3A_FDT_LISTEN_FC; }
接下来,事件可以根据检测到的内容采用多个值:
- FuriHalNfcEventFieldOn 表示已检测到场激活。
- FuriHalNfcEventFieldOff 表示该字段已关闭。
- 最重要的事件是FuriHalNfcEventRxEnd,它表示已收到来自终端的命令。此时,我们需要发送响应。再次强调,命令发送的所有处理(包括防冲突)都是自动完成的。因此,我们基本上可以开始处理像 select 这样的命令。
FuriHalNfcEvent event = furi_hal_nfc_listener_wait_event(100);
5 - 处理命令的接收并发送响应
现在,让我们看看如何处理命令的接收和发送响应。
while(true) { FuriHalNfcEvent event = furi_hal_nfc_listener_wait_event(100); if(event == FuriHalNfcEventTimeout) { if(cli_cmd_interrupt_received(cli)) { break; } } if(event & FuriHalNfcEventAbortRequest) { break; } if(event & FuriHalNfcEventFieldOn) { printf("on\r\n"); } if(event & FuriHalNfcEventFieldOff) { furi_hal_nfc_listener_idle(); printf("off\r\n"); } if(event & FuriHalNfcEventListenerActive) { // Nothing } if(event & FuriHalNfcEventRxEnd) {
- 数据接收通过furi_hal_nfc_listener_rx(rx_data, rx_data_size, &rx_bits);处理。我们使用 printf 显示接收到的数据,该 printf 将响应发送到连接到 Flipper 的终端。 需要理解的重要一点是,一旦我们收到命令,我们必须非常迅速地做出反应。这意味着我们无法在 shell 中手动编写响应——那就太晚了。这就是为什么与 Flipper 通信的唯一方法是使用带有调度程序的 Python 脚本,该调度程序指定对每个收到的命令给出哪个响应.
-
然后,终端发送一个响应,我们使用函数 nfc_emu_get_resp(cli, rx_cmd) 检索该响应。这部分有点棘手,因为在 shell 命令中,通常不会进行来回交换。所以,我使用函数 cli_getc(cli) 来读取一个字符。
- 有时,我会收到不需要的字符 0xA。如果这是收到的第一个字符,我会跳过它,因为我会逐个字符地阅读。
- 第一个字符指示 Flipper Zero 是否应该计算并将 CRC 添加到命令本身(0x31 表示是,否则表示否)。
- 然后,我以十六进制字符串格式读取响应的字符。当我们收到字符0xA时,表示接收完成。
最后,我们使用 unhexify(tmp, (uint8_t*)bit_buffer_get_data(rx_data), len); 将十六进制字符串转换为 uint8_t 数组。
如有必要,我们使用 add_crc 添加 CRC。
最后,我们可以使用以下方式将回复发送给读者:
FuriHalNfcError r = furi_hal_nfc_listener_tx(rx_data, bit_buffer_get_size(rx_cmd));.
现在,我们如何验证这一切?
6 - 卡模拟验证
6.1 - 它是如何开始的......(Hydra NFC v2)
好吧,我们可以使用上一篇文章中的透明阅读器来验证我们的模拟器。所以,我们需要两个脚蹼零点……但我没有。不过,我有 Hydra NFC v2,它允许透明的读取器设置。
我只需要使用 pynfc 中的脚本。
+----------------+ +----------------+ | Reader | | Card | +----------------+ +----------------+ | | Field activation | | | | --- REQA (Request Command Type A) -------------> | | 26 | | | | <------------ ATQA (Answer to Request Type A) ---| | 04 00 | | | --- ANTICOLLISION Command ---------------------->| | | | <------------ UID (Unique Identifier) -----------| | | | --- SELECT [UID] Command ----------------------->| | | | <------------ SAK (Select Acknowledge) ----------| | | | --- RATS (Request for Answer To Select) -------->| | E0 50 BC A5 | | | | <------------ ATS (Answer To Select) ------------| | 0A 78 80 82 02 20 63 CB A3 A0 92 43 | | | | ---- [Opt] PPS (Proto and Parameter Selection) ->| | D0 73 87 | | | | <------------ [PPS Response] --------------------| | D0 73 87 | | | | --- TPDU [Encapsulated APDU Command] ----------->| | 0200A404000E325041592E5359532E444446303100E042 | | | | <------------ TPDU [Encapsulated APDU Response] -| | 00a404000e325041592e5359532e444446303100 |
它非常实用,因为它允许我们一一发送命令来验证一切:
- 发送 REQA
- 防碰撞
- 选择
- PPS
- 发送 TPDU
6.2 - 它是如何完成的...(PC/SC 阅读器)。
然而,实际上,沟通要复杂一些。因此,我使用 PC/SC 读卡器 ACR122U 来发送/接收完整的 APDU 命令,并结合 Python 脚本(使用 pyscard )进行实际测试。
就我而言,我只需选择 PPSE 应用程序即可。
if(g_NfcTech == FuriHalNfcTechIso14443a) { furi_hal_nfc_iso14443a_listener_set_col_res_data(g_uid, g_uid_len, g_atqa, g_sak); fdt = ISO14443_3A_FDT_LISTEN_FC; }
所以现在,卡片模拟器需要处理更多的事件。因此,我在下面创建了一个 Python 脚本来管理这种情况。有很多东西需要解释,例如不同类型的 TPDU(i-block、r-block、s-block),但这将在以后的博客文章中介绍。
FuriHalNfcEvent event = furi_hal_nfc_listener_wait_event(100);
这样就很好用了,仿真也极其稳定。我可以将 Flipper 从读卡器上放置或移除,并多次发送命令,而且每次都有效。 Flipper 再次出色地实现了 NFC 层,并且其 API 允许在实现过程中以最少的工作量实现大量功能。
下面是 Python 脚本的输出示例。
+----------------+ +----------------+ | Reader | | Card | +----------------+ +----------------+ | | Field activation | | | | --- REQA (Request Command Type A) -------------> | | 26 | | | | <------------ ATQA (Answer to Request Type A) ---| | 04 00 | | | --- ANTICOLLISION Command ---------------------->| | | | <------------ UID (Unique Identifier) -----------| | | | --- SELECT [UID] Command ----------------------->| | | | <------------ SAK (Select Acknowledge) ----------| | | | --- RATS (Request for Answer To Select) -------->| | E0 50 BC A5 | | | | <------------ ATS (Answer To Select) ------------| | 0A 78 80 82 02 20 63 CB A3 A0 92 43 | | | | ---- [Opt] PPS (Proto and Parameter Selection) ->| | D0 73 87 | | | | <------------ [PPS Response] --------------------| | D0 73 87 | | | | --- TPDU [Encapsulated APDU Command] ----------->| | 0200A404000E325041592E5359532E444446303100E042 | | | | <------------ TPDU [Encapsulated APDU Response] -| | 00a404000e325041592e5359532e444446303100 |
6.3 还有一点 Proxmark
使用 Proxmark 3 对于调试嗅探模式下的通信非常有用:我将其放置在读卡器和卡(可以是正品卡或 Flipper)之间,并且我能够检查数据交换。
if(g_NfcTech == FuriHalNfcTechIso14443a) { furi_hal_nfc_iso14443a_listener_set_col_res_data(g_uid, g_uid_len, g_atqa, g_sak); fdt = ISO14443_3A_FDT_LISTEN_FC; }
接下来怎么办?
很好,下一步是什么?
- 首先,我可以对卡片模拟 Python 脚本进行更多解释。
- 此外,我应该实现一种在按下按钮时停止卡模拟的方法,因为当前事件等待循环永远不会完成。退出的唯一方法是重新启动 Flipper。
- 此外,我们还可以通过同时使用透明读卡器和卡模拟器来做一些有趣的事情,例如,执行中间人攻击并实时修改通信!
以上是Flipper Zero NFC 黑客攻击 - cannon fooder的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Python适合数据科学、Web开发和自动化任务,而C 适用于系统编程、游戏开发和嵌入式系统。 Python以简洁和强大的生态系统着称,C 则以高性能和底层控制能力闻名。

2小时内可以学会Python的基本编程概念和技能。1.学习变量和数据类型,2.掌握控制流(条件语句和循环),3.理解函数的定义和使用,4.通过简单示例和代码片段快速上手Python编程。

Python在游戏和GUI开发中表现出色。1)游戏开发使用Pygame,提供绘图、音频等功能,适合创建2D游戏。2)GUI开发可选择Tkinter或PyQt,Tkinter简单易用,PyQt功能丰富,适合专业开发。

Python更易学且易用,C 则更强大但复杂。1.Python语法简洁,适合初学者,动态类型和自动内存管理使其易用,但可能导致运行时错误。2.C 提供低级控制和高级特性,适合高性能应用,但学习门槛高,需手动管理内存和类型安全。

两小时内可以学到Python的基础知识。1.学习变量和数据类型,2.掌握控制结构如if语句和循环,3.了解函数的定义和使用。这些将帮助你开始编写简单的Python程序。

要在有限的时间内最大化学习Python的效率,可以使用Python的datetime、time和schedule模块。1.datetime模块用于记录和规划学习时间。2.time模块帮助设置学习和休息时间。3.schedule模块自动化安排每周学习任务。

Python在web开发、数据科学、机器学习、自动化和脚本编写等领域有广泛应用。1)在web开发中,Django和Flask框架简化了开发过程。2)数据科学和机器学习领域,NumPy、Pandas、Scikit-learn和TensorFlow库提供了强大支持。3)自动化和脚本编写方面,Python适用于自动化测试和系统管理等任务。

Python在自动化、脚本编写和任务管理中表现出色。1)自动化:通过标准库如os、shutil实现文件备份。2)脚本编写:使用psutil库监控系统资源。3)任务管理:利用schedule库调度任务。Python的易用性和丰富库支持使其在这些领域中成为首选工具。
