Android NFC条件竞争漏洞分析(CVE-2021-0870)
字数 1485 2025-08-29 08:31:35
Android NFC条件竞争漏洞分析(CVE-2021-0870)技术文档
1. 漏洞概述
CVE-2021-0870是Android NFC子系统中的一个高危远程代码执行(RCE)漏洞,于2021年10月安全公告中被修复。该漏洞存在于NFC的Reader/Write模式中,涉及Tag控制块(TCB)的状态切换机制。
漏洞核心问题:当通过RW_SetActivatedTagType函数在不同tag类型之间切换时,会使用memset将TCB置零表示上一状态已被禁用,但上一个状态的超时检测定时器仍然在工作并引用TCB中的数据指针。当新状态启动自己的定时器重写TCB中相应偏移的数据时,会产生条件竞争,最终可能导致内存破坏和代码执行。
2. NFC技术背景
2.1 NFC运行模式
- Reader/Write模式(R/W):与NFC Tag/NFC reader交互
- Peer-to-Peer模式(P2P):支持两个NFC设备间交互
- Card Emulation模式(CE):将NFC设备模拟为智能卡(如支付/门禁)
2.2 NFC数据结构
NFC Forum定义了两种主要数据结构:
- NDEF:NFC数据交换格式
- NFC Record:数据记录单元
在R/W模式下使用NDEF通信时,数据交互被封装在NDEF Message中,一个Message包含多个Record。
2.3 Tag类型
Android支持多种Tag类型,通过android.nfc.tech包中的类处理:
Ndef:处理Type1-4 TagIsoDep:处理ISO-DEP (ISO 14443-4)MifareClassic/MifareUltralight:处理MIFARE标签NfcA/NfcB/NfcF/NfcV:处理不同射频技术标准
3. 漏洞详细分析
3.1 漏洞位置
漏洞位于RW_SetActivatedTagType函数中,该函数负责在不同Tag类型间切换:
tNFC_STATUS RW_SetActivatedTagType(tNFC_ACTIVATE_DEVT* p_activate_params, tRW_CBACK* p_cback) {
// ...
memset(&rw_cb.tcb, 0, sizeof(tRW_TCB)); // 问题代码:直接清零TCB
// ...
}
3.2 漏洞触发流程
- 系统处于i93模式(IsoDep)
- 发起读数据请求(
NFA_RwReadNDef),启动定时器 - 立即从i93切换到t3t模式(FeliCa)
- 新t3t模式启动自己的定时器
- 两个定时器同时操作TCB导致条件竞争
3.3 根本原因
- TCB复用:不同Tag状态复用同一块TCB内存区域
- 不完整的状态切换:切换时仅清零TCB,未停止前一个状态的定时器
- 定时器竞争:新旧状态的定时器同时操作TCB中的相同字段
4. PoC分析
4.1 PoC关键步骤
-
初始化NFC环境:
NfcAdaptation& theInstance = NfcAdaptation::GetInstance(); theInstance.Initialize(); NFA_Init(&entry_funcs); NFA_Enable(nfa_dm_callback, nfa_conn_callback); -
模拟i93 Tag激活:
std::vector<uint8_t> activate_rf = {/* disc_id */0x0, NFC_DISCOVERY_TYPE_POLL_V, static_cast<uint8_t>(NFC_PROTOCOL_T5T)}; g_callback_tracker->SimulatePacketArrival(NCI_MT_NTF, 0, NCI_GID_RF_MANAGE, NCI_MSG_RF_INTF_ACTIVATED, activate_rf.data(), activate_rf.size()); -
发起读请求并触发定时器:
NFA_RwReadNDef(); -
快速切换到t3t模式:
std::vector<uint8_t> activate_another_rf = {/* disc_id */0x0, NFC_DISCOVERY_TYPE_LISTEN_F, NFC_PROTOCOL_T3T}; g_callback_tracker->SimulatePacketArrival(NCI_MT_NTF, 0, NCI_GID_RF_MANAGE, NCI_MSG_RF_INTF_ACTIVATED, activate_another_rf.data(), activate_another_rf.size());
4.2 关键同步机制
PoC使用条件变量实现精确时序控制:
{
std::unique_lock<std::mutex> i93_detect_lock(cv_mutex);
i93_detect_cv.wait(i93_detect_lock); // 等待i93检测完成
}
5. 漏洞修复方案
修复方法是在切换Tag类型前停止所有相关定时器:
tNFC_STATUS RW_SetActivatedTagType(tNFC_ACTIVATE_DEVT* p_activate_params, tRW_CBACK* p_cback) {
// 根据当前Tag类型停止相应定时器
switch (rw_cb.tcb_type) {
case RW_CB_TYPE_T1T: nfc_stop_quick_timer(&rw_cb.tcb.t1t.timer); break;
case RW_CB_TYPE_T2T: nfc_stop_quick_timer(&rw_cb.tcb.t2t.t2_timer); break;
case RW_CB_TYPE_T3T:
nfc_stop_quick_timer(&rw_cb.tcb.t3t.timer);
nfc_stop_quick_timer(&rw_cb.tcb.t3t.poll_timer);
break;
// ... 其他类型处理
}
// 然后再清零TCB
memset(&rw_cb.tcb, 0, sizeof(tRW_TCB));
// ...
}
6. 技术要点总结
- NFC子系统架构:理解NFC的任务模型和消息传递机制(GKI)
- TCB管理:Tag控制块的内存管理和状态切换机制
- 定时器机制:NFC中的定时器实现和使用场景
- 条件竞争:多任务环境下共享资源的同步问题
- 安全修复原则:状态切换时应完整清理所有相关资源
7. 防御建议
- 及时更新Android安全补丁
- 对NFC子系统进行模糊测试
- 在状态切换时确保完整清理所有相关资源
- 使用静态分析工具检测类似的条件竞争问题
8. 参考资源
- Android 2021-10安全公告
- NFC Forum技术规范
- Android NFC子系统源代码