在上一篇文章中,我們了解如何使用 Flipper Zero 實作透明閱讀器。如果我們採用相同的概念,但這次實作一個透明的卡片模擬器呢?我們可以像大砲一樣使用 Flipper Zero,透過發送錯誤的請求來攻擊數位堡壘,例如閱讀器或智慧型手機。格式錯誤的指令、生命週期中不期望的指令、模糊測試、緩衝區溢位-沒有極限!
就像透明讀卡機一樣,我想從我的電腦使用其串行 CLI 與 Flipper 進行通訊。電腦處理所有邏輯,這意味著它根據命令決定給出什麼回應,例如使用 Python 腳本。
現在,關於卡片模擬器命令的實現,與讀卡器相比,它本質上是一種鏡像模式:
除了一個讓事情變得複雜的小細節。請記住,在卡片/讀卡機通訊期間,讀卡機充當主機,這意味著它是發起通訊並發送命令的人。
因此,如果我們要建立一個卡片模擬器,它必須等待來自讀卡機的事件。您可以將其視為伺服器,而讀者則充當客戶端。我們需要將其編碼到 Flipper Zero 中。
好吧,首先,讓我們快速回顧一下使用 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 上實現所有這些?」
和我之前的文章一樣,我將繼續擴展檔案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 個指令來設定這些元素:
在開始模擬之前,我們將使用這些參數來呼叫 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; }
接下來,事件可以根據偵測到的內容採用多個值:
FuriHalNfcEvent event = furi_hal_nfc_listener_wait_event(100);
現在,讓我們看看如何處理命令的接收和發送回應。
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) {
然後,終端發送一個回應,我們使用函數 nfc_emu_get_resp(cli, rx_cmd) 檢索該回應。這部分有點棘手,因為在 shell 指令中,通常不會進行來回交換。所以,我使用函數 cli_getc(cli) 來讀取一個字元。
最後,我們使用 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));.
現在,我們要如何驗證這一切?
好吧,我們可以使用上一篇文章中的透明閱讀器來驗證我們的模擬器。所以,我們需要兩個腳蹼零點……但我沒有。不過,我有 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 |
它非常實用,因為它允許我們一一發送命令來驗證一切:
然而,實際上,溝通要複雜一些。因此,我使用 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 |
使用 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; }
很好,下一步是什麼?
以上是Flipper Zero NFC 駭客攻擊 - cannon fooder的詳細內容。更多資訊請關注PHP中文網其他相關文章!