CVE-2021-0870 NFC竟也存在高危漏洞?看他如何分析

概述
NFC在人们的日常生活中扮演了重要角色,已经成为移动设备不可或缺的组件,NFC和蓝牙类似,都是利用无线射频技术来实现设备之间的通信 。因此芯片固件和主机NFC子系统都是远程代码执行(RCE)攻击的目标 。
CVE-2021-0870是一枚NFC中的RCE高危漏洞,2021年10月漏洞通告中显示已被修复 。漏洞成因是pe 可以通过将NFC的TCB(tagblock)置零的方式实现在不同tag之间切换,TCB所在的内存区域是固定不变的,这块内存被不同tag复用 。当TCB被置零后即表示上一状态已被禁用 。但是新tag激活后,上一个状态的超时检测定时器仍然在工作,并且仍然引用TCB里的数据和指针,然而此时TCB已经被置零 。随后新状态启动自己的定时器重写TCB中相应偏移的数据时,会产生条件竞争 。
NFC技术框架 NFC的三种运行模式
/Write模式:简称R/W 和NFC Tag/NFC 有关;
Peer-to-Peer模式:简称P2P 它支持两个NFC设备进行交互;
NFC Card (CE):他能把NFC功能的设备模拟成智能卡,这样就可以实现手机支付/门禁卡功能 。
漏洞存在于/Write模式(R/W)
/Write模式
NFC Tag/NFC 是NFC系统RFID中的两个重要的组件,其中Tag是一种用于存储数据的被动式RFID tag,它自身不包含电源,而是依赖其他组件,如NFC 通过线圈里的电磁感应给他供电,然后通过某些射频通信协议来存取NFC tag里的数据 。
NFC Forum 定义了两个数据结构用于设备间的通信(不仅仅是设备之间,也包括R/W模式种的NFC 和NFC Tag之间交互数据),分别是NDEF和NFC。
R/W模式下使用NDEF数据结构通信时,NFC设备的每一次数据交互都会被封装在一个NDEF 中,一个包括多个NFC的数据结构如下,它是多个组合而成 。
单个的结构如下:
本文不对详细的数据结构的各个字段做出解释 。
漏洞存在于使用NDEF数据包通信的过程中 。
Tag
NFC Forum 定义了4种tag,分别为Type1,2,3,4。他们之间的区别在于占用存储空间的大小和使用底层协议不同 。但能被NFC 和NFC Tag 读写的tag类型远多于4种,Java层提供了".nfc.tech"包用来处理不同类型的tag,下表列出了该包里的几个类,这些类分别处理不同类型的tag 。例如,NDEF 是用来处理Type1-4的类 。
to ISO-DEP (ISO 14443-4)and I/Oon aTag.
toand I/Oon aTag.
toand I/Oon aTag.
Ndef
to NDEFandon aTag.
to NDEFon aTag.
NfcA
to NFC-A (ISO 14443-3A)and I/Oon aTag.
NfcB
to NFC-B (ISO 14443-3B)and I/Oon aTag.
to tagsjust a .
NfcF
to NFC-F (JIS 6319-4)and I/Oon a Tag.
NfcV
to NFC-V (ISO 15693)and I/Oon aTag.
漏洞代码中出现的T1T,T2T...TT,I93,是R/W模式下,探测、读写NDEF数据包的具体实现方法,是一种的技术标准 。比如I93是基于 ISO 15693 的实现方法,T1T基于NFC-A,也就是ISO 14443-3A 。
【CVE-2021-0870NFC竟也存在高危漏洞?看他如何分析】漏洞分析 POC代码
基于的测试框架gtest编写了一个集成测试文件,TEST函数是测视例的main函数,自动化测试框架从TEST调用poc代码:
TEST(NfcIntegrationTest, test_mifare_state_bug) {CallbackTracker tracker;g_callback_tracker = &tracker;NfcAdaptation& theInstance = NfcAdaptation::GetInstance();theInstance.Initialize();NFA_Init(&entry_funcs);NFA_Enable(nfa_dm_callback, nfa_conn_callback);usleep(5000);std::vector reset_core = {0x1, 0x29, 0x20};g_callback_tracker->SimulatePacketArrival(NCI_MT_NTF, 0, NCI_GID_CORE, NCI_MSG_CORE_RESET, reset_core.data(),reset_core.size());{std::unique_lock reset_done_lock(cv_mutex);reset_done_cv.wait(reset_done_lock);}NFA_EnableListening();NFA_EnablePolling(NFA_TECHNOLOGY_MASK_F | NFA_TECHNOLOGY_MASK_V);NFA_EnableDtamode(NFA_DTA_DEFAULT_MODE);NFA_StartRfDiscovery();{std::unique_lock enable_lock(cv_mutex);enable_cv.wait(enable_lock);}std::vector