作者:Revan Zhang 來源:Medium近年來,硬體錢包在區塊鏈行業中,被視爲相對安全的私鑰存儲方式之一。私鑰生成後,會存儲在硬體錢包的安全芯片(Secure Element)中,僅用於對外部傳入的信息進行籤名。這種無法聯網的封閉式硬件設計,配合禁止導出私鑰的軟件機制,構建起了強大的保護屏障。然而,這種安全架構也有其“軟肋” — — 硬體錢包高度依賴外部客戶端軟件和通信通道。一旦這些外圍環節被篡改,攻擊者便可實施“中間人攻擊”(MITM),在用戶毫無察覺的情況下替換信息,造成資產損失。# 什麼是中間人攻擊中間人攻擊是指攻擊者祕密地介入通信雙方之間,攔截、篡改或僞造雙方的通信內容,而通信雙方誤以爲他們在直接交互。這種攻擊常見於網路監聽、數據僞造、身分盜用和地址替換等場景。在加密資產領域尤其危險,因爲攻擊者只需替換一個地址,就可能造成巨大的資產損失。舉個生活中的例子:你寄給朋友一封重要信件。一個“壞郵差”在途中截獲,將信件內容進行替換,然後重新封好寄出。朋友收到信件後,此時獲取的信息因爲被郵差替換,已經不再準確了。在這個例子中,郵差扮演了中間人的角色,通過替換信件內容實施了中間人攻擊。在區塊鏈系統中,由於大多數公鏈轉帳只需要收款地址,而不需要額外的諸如姓名的驗證。這種場景的中間人攻擊更容易得手,且造成的損失往往更大,更難追回。  # 硬體錢包通信流程:看不見的郵差市面上主流的硬體錢包大致採用四種通信方式:* USB:最常見且穩定,通過數據線實現雙向傳輸* 藍牙:低功耗藍牙 BLE,常用於移動端* 二維碼:airgap,較爲新型的方式,物理隔離,通過互相掃碼達到通信的目的* NFC:近場通信,暫時較少使用其中,USB 與藍牙最爲常見。無論採用哪種方式,通信流程大致相同:1. “錢包端”發起連接,例如瀏覽器插件錢包或者手機 APP 錢包2. 向“硬體錢包”發送請求,例如獲取硬件內部的地址,發起籤名等等3. 請求經上述“通信通道”送達硬件設備4. 設備完成處理並返回響應5. “錢包端”接收並顯示結果盡管硬體錢包自身是安全的“保險庫”,但通信過程卻依賴客戶端、通信通道這一“郵差鏈條”。一旦“郵差”遭到劫持或者作惡,傳遞的數據信息就可能早已被調包。這正是“達摩克利斯之劍”懸於硬體錢包之上的隱祕威脅 — — 中間人攻擊。## 實戰案例:基於惡意腳本的中間人攻擊## 聲明* 所有代碼和操作均發生在 2023 年 9 月,距本文發布時間(2025 年 6 月)已超過 20 個月。* 所有演示基於當時公開版本的官方軟件,具體版本信息已在文中注明。* 所涉及的攻擊方式,已於當時向相關團隊披露並確認。* 本文所有內容僅供學習與安全研究之用,觀點僅代表作者本人。* 本文不對由此引發的任何行爲或後果承擔責任。## Trezor 通信的基本流程Trezor 通過 USB 連接 Metamask 瀏覽器錢包時可選擇通過 Trezor Bridge 進行通信,Trezor Bridge 的基本流程* 安裝軟件之後,會在用戶的電腦中,在本地 21325 端口啓動 HTTP 服務器* Metamask 連接 Trezor 硬體錢包時,會通過彈出 網頁來加載 JS SDK* Trezor 的 SDK 會嘗試的將基於 protobuf 的序列化數據,發送向這個本地服務器* Trezor Bridge 接收到數據後,通過 lib-usb 庫查找本地滿足條件的 PID VID Trezor 設備並傳輸數據當檢測到本地已安裝 Trezor Bridge 時,所有通過 網頁,也就是 Trezor SDK 的序列化數據都會經由本地 Trezor Bridge 服務器轉發給設備,而不使用 Web USB。## Trezor Bridge 的基本信息Trezor Bridge 使用 Golang 開發,當前用戶版本爲 v2.0.27。從 GitHub 開源倉庫可見,v2.0.27 使用 xgo 進行跨平台編譯,從而生成 MacOS,Windows 和 linux 的安裝包。以 MacOS 爲例,安裝時會在 /Applications/Utilities/TREZOR\ Bridge/trezord 目錄創建 trezord 服務器二進制文件,並在用戶本地創建 com.bitcointrezor.trezorBridge.trezord.plist 文件,通過 KeepAlive 實現開機自啓和進程守護。## 攻擊的基本流程在 Metamask 連接 Trezor 設備時,立刻就會讀取設備內部的 ETH 公鑰,然後基於派生地址序號在 Metamask 軟件端計算出不同路徑的地址。在這個過程中,沒有任何的硬件確認或者提示,這也爲一個簡單的中間人攻擊,提供了可實現的路徑。一旦 Trezor Bridge 被本地惡意軟件控制,整個通信鏈路上就會出現一個“壞郵差”。攻擊者便可將其變爲一個中轉服務器,劫持所有與硬體錢包的通信數據。這樣,發送給硬件的數據和從硬件返回的數據都可能被篡改,造成界面顯示信息與實際硬件信息不一致,一旦軟件流程有漏洞或者硬件上的信息沒有認真確認,中間人攻擊就能操作成功。## 攻擊測試* 首先安裝 Trezor Suite v23.8.1、Trezor Bridge v2.0.27 和 Metamask v11.0.0* 準備兩臺 Trezor Model T:一臺按正常流程操作,另一臺用於中間人攻擊測試* 首先展示正常流程:兩臺設備在 Trezor Suite 和 Metamask 中均能正確讀取地址* 執行惡意腳本替換 trezord 進程* 第一臺設備在 Metamask 中仍能正確讀取地址,流程正常* 第二臺設備在 Metamask 中讀取的地址被中間人替換,與 Trezor Suite 和硬件顯示的地址不一致## 代碼分析在 Trezor Bridge 關鍵位置添加日志標記,記錄設備通信過程中的請求體和響應體數據:SDK 讀取公鑰階段的 hexbodyStr 和 hexres 在多次調用時,對同一設備的不同時間操作參數和返回結果完全相同。通過日志篩選,發現 Metamask 讀取 ETH 地址時的 call 函數調用數據如下:根據日志比對,003700000000 和 000b0000001f08ac8080800808bc80808008088080808008080008002207426974636f696e 等數據,均爲發送、接收報文的序列化結果。經過重放測試,在信息構建過程中並沒有時間戳等參數,可以非常簡單輕易的模擬攻擊手法,即針對部分發送報文,硬編碼返回的結果,進行結果替換:在這個例子中,我們針對性的將數據進行了替換,當接收到 SDK 獲取 ETH 公鑰的請求時,不再使用硬件返回的結果,而是直接使用上述代碼中硬編碼的結果。重新通過文檔編譯後制作二進制文件,同時制作守護進程等攻擊必要組件。準備工作完成後,當用戶不慎安裝和運行惡意軟件後。每當用戶使用 Metamask 連接 Trezor 並且發送數據時,通過 bridge 通信的數據不再是硬件讀取出來的信息,而是上述代碼中硬編碼的序列化數據,再基於業務 SDK 的反序列化,讀取地址的信息即替換成功。完整的攻擊如上述視頻所示。## 與團隊的溝通整理好問題及操作之後,我第一時間已與 Metamask 和 Trezor 團隊進行了溝通,以下是所有溝通信息及郵件信息* Metamask 溝通記錄:* Trezor 郵件溝通信息:# 問題的核心及建議## Metamask 讀取完整地址,無需硬件確認硬件整體可以作爲一個封閉的安全環境,所以所有信息都應以硬件爲準。但是在 Metamask 的產品設計流程當中,在硬件沒有任何顯示的情況下,直接讀取完整地址的明文信息並進行展示。Trezor SDK ethereumGetAddress 方法提供了 showOnTrezor 參數,他的作用是讀取硬件的地址,並在硬件當中展示,以供用戶二次確認。這是一個產品設計的取舍問題,如果每次都需要用戶確認過才能讀取地址,那麼在批量添加地址的場景用戶會非常痛苦。所以在主流的支持硬體錢包的 APP 內,同時支持靜默讀取地址,但是如果想要接收資產,都需要先進行地址的硬件確認,就是爲了防止上述攻擊場景出現。Metamask 靜默讀取地址之後,沒有讓用戶確認,就直接展示了完整地址,那麼首次使用的用戶,一旦被攻擊,就很容易中招。## 盲籤的威脅,可能比我們想象中的更大按照這種攻擊手段和攻擊方式,我們可以得出結論:所有硬件非確定性的信息,都是理論上不安全的。所有的盲籤同理,雖然盲籤硬件上有確認,但是這個確認的信息對於用戶來說並不可讀,所以他也滿足硬件非確定性的信息,無法確保不被中間人攻擊。safe 多簽錢包的案件就是一個典型,錢包構造的籤名信息被服務器惡意 javascript 代碼替換,同時因爲 ledger 錢包是盲籤,導致這一次攻擊的發生。## 通信通道的中間人攻擊,方式衆多除了用戶本地有惡意軟件以外,一些錢包的通信和構建流程可能涉及到服務器(例如一些錢包 encodeTx 需要通過服務端進行構建)。這些都是潛在的攻擊對象和被攻擊點。通信通道當然還包括硬件層面,例如不安全的電腦攝像頭外設,不安全的 USB 數據線等等。從物理層到應用層,在通信層面,所有環節都有被攻擊的可能。## 主動提升安全意識,任重而道遠客戶端到硬體錢包的完整通信,核心流程理論上是不需要聯網的。所以即使有端到端的加密通信,也無法 100% 確保流程安全。增加端到端的加密之後,對於真正的黑客來說,增加的只是逆向客戶端,對通信信道的破解成本。而對於攻擊本身,從來都不是難度的較量,而是黑客付出的成本和法律後果的考量。同時,大部分區塊鏈的產品團隊,一般在面對這類中間人攻擊的威脅時,會將這部分的優化放在整個迭代中處於低優先級,變相等於允許一部分中間人攻擊的風險出現。如上面的團隊溝通郵件,如 Metamask 的 bug bounty 界面,就將 MITM 中間人攻擊排除在外:所以對於用戶來說,更需要主動我們自身提高防範意識。對於重要資產,即使是使用硬體錢包,也最好隔離電腦,不連接不可信的網路,不訪問不可信的網頁等等等等。# 寫在最後硬體錢包的“安全神話”並非來自單一設備本身,而是建立在整個生態系統的協作安全。當我們忽視客戶端的可信性、放松對通信通道的防護,那把“達摩克利斯之劍”便悄然懸於我們的資產之上。真正的安全,從不止於硬件,而在於每一個你以爲“無關緊要”的細節。
硬體錢包上的達摩克利斯之劍:隱祕的中間人威脅
作者:Revan Zhang 來源:Medium
近年來,硬體錢包在區塊鏈行業中,被視爲相對安全的私鑰存儲方式之一。私鑰生成後,會存儲在硬體錢包的安全芯片(Secure Element)中,僅用於對外部傳入的信息進行籤名。這種無法聯網的封閉式硬件設計,配合禁止導出私鑰的軟件機制,構建起了強大的保護屏障。
然而,這種安全架構也有其“軟肋” — — 硬體錢包高度依賴外部客戶端軟件和通信通道。一旦這些外圍環節被篡改,攻擊者便可實施“中間人攻擊”(MITM),在用戶毫無察覺的情況下替換信息,造成資產損失。
什麼是中間人攻擊
中間人攻擊是指攻擊者祕密地介入通信雙方之間,攔截、篡改或僞造雙方的通信內容,而通信雙方誤以爲他們在直接交互。
這種攻擊常見於網路監聽、數據僞造、身分盜用和地址替換等場景。在加密資產領域尤其危險,因爲攻擊者只需替換一個地址,就可能造成巨大的資產損失。
舉個生活中的例子:你寄給朋友一封重要信件。一個“壞郵差”在途中截獲,將信件內容進行替換,然後重新封好寄出。朋友收到信件後,此時獲取的信息因爲被郵差替換,已經不再準確了。
在這個例子中,郵差扮演了中間人的角色,通過替換信件內容實施了中間人攻擊。
在區塊鏈系統中,由於大多數公鏈轉帳只需要收款地址,而不需要額外的諸如姓名的驗證。這種場景的中間人攻擊更容易得手,且造成的損失往往更大,更難追回。
硬體錢包通信流程:看不見的郵差
市面上主流的硬體錢包大致採用四種通信方式:
其中,USB 與藍牙最爲常見。無論採用哪種方式,通信流程大致相同:
盡管硬體錢包自身是安全的“保險庫”,但通信過程卻依賴客戶端、通信通道這一“郵差鏈條”。一旦“郵差”遭到劫持或者作惡,傳遞的數據信息就可能早已被調包。
實戰案例:基於惡意腳本的中間人攻擊
聲明
Trezor 通信的基本流程
Trezor 通過 USB 連接 Metamask 瀏覽器錢包時可選擇通過 Trezor Bridge 進行通信,Trezor Bridge 的基本流程
當檢測到本地已安裝 Trezor Bridge 時,所有通過 網頁,也就是 Trezor SDK 的序列化數據都會經由本地 Trezor Bridge 服務器轉發給設備,而不使用 Web USB。
Trezor Bridge 的基本信息
Trezor Bridge 使用 Golang 開發,當前用戶版本爲 v2.0.27。
從 GitHub 開源倉庫可見,v2.0.27 使用 xgo 進行跨平台編譯,從而生成 MacOS,Windows 和 linux 的安裝包。
以 MacOS 爲例,安裝時會在 /Applications/Utilities/TREZOR\ Bridge/trezord 目錄創建 trezord 服務器二進制文件,並在用戶本地創建 com.bitcointrezor.trezorBridge.trezord.plist 文件,通過 KeepAlive 實現開機自啓和進程守護。
攻擊的基本流程
在 Metamask 連接 Trezor 設備時,立刻就會讀取設備內部的 ETH 公鑰,然後基於派生地址序號在 Metamask 軟件端計算出不同路徑的地址。
在這個過程中,沒有任何的硬件確認或者提示,這也爲一個簡單的中間人攻擊,提供了可實現的路徑。
一旦 Trezor Bridge 被本地惡意軟件控制,整個通信鏈路上就會出現一個“壞郵差”。攻擊者便可將其變爲一個中轉服務器,劫持所有與硬體錢包的通信數據。這樣,發送給硬件的數據和從硬件返回的數據都可能被篡改,造成界面顯示信息與實際硬件信息不一致,一旦軟件流程有漏洞或者硬件上的信息沒有認真確認,中間人攻擊就能操作成功。
攻擊測試
代碼分析
在 Trezor Bridge 關鍵位置添加日志標記,記錄設備通信過程中的請求體和響應體數據:
SDK 讀取公鑰階段的 hexbodyStr 和 hexres 在多次調用時,對同一設備的不同時間操作參數和返回結果完全相同。通過日志篩選,發現 Metamask 讀取 ETH 地址時的 call 函數調用數據如下:
根據日志比對,
003700000000 和 000b0000001f08ac8080800808bc80808008088080808008080008002207426974636f696e 等數據,均爲發送、接收報文的序列化結果。
經過重放測試,在信息構建過程中並沒有時間戳等參數,可以非常簡單輕易的模擬攻擊手法,即針對部分發送報文,硬編碼返回的結果,進行結果替換:
在這個例子中,我們針對性的將數據進行了替換,當接收到 SDK 獲取 ETH 公鑰的請求時,不再使用硬件返回的結果,而是直接使用上述代碼中硬編碼的結果。重新通過文檔編譯後制作二進制文件,同時制作守護進程等攻擊必要組件。
準備工作完成後,當用戶不慎安裝和運行惡意軟件後。每當用戶使用 Metamask 連接 Trezor 並且發送數據時,通過 bridge 通信的數據不再是硬件讀取出來的信息,而是上述代碼中硬編碼的序列化數據,再基於業務 SDK 的反序列化,讀取地址的信息即替換成功。完整的攻擊如上述視頻所示。
與團隊的溝通
整理好問題及操作之後,我第一時間已與 Metamask 和 Trezor 團隊進行了溝通,以下是所有溝通信息及郵件信息
問題的核心及建議
Metamask 讀取完整地址,無需硬件確認
硬件整體可以作爲一個封閉的安全環境,所以所有信息都應以硬件爲準。但是在 Metamask 的產品設計流程當中,在硬件沒有任何顯示的情況下,直接讀取完整地址的明文信息並進行展示。
Trezor SDK ethereumGetAddress 方法提供了 showOnTrezor 參數,他的作用是讀取硬件的地址,並在硬件當中展示,以供用戶二次確認。
這是一個產品設計的取舍問題,如果每次都需要用戶確認過才能讀取地址,那麼在批量添加地址的場景用戶會非常痛苦。所以在主流的支持硬體錢包的 APP 內,同時支持靜默讀取地址,但是如果想要接收資產,都需要先進行地址的硬件確認,就是爲了防止上述攻擊場景出現。
Metamask 靜默讀取地址之後,沒有讓用戶確認,就直接展示了完整地址,那麼首次使用的用戶,一旦被攻擊,就很容易中招。
盲籤的威脅,可能比我們想象中的更大
按照這種攻擊手段和攻擊方式,我們可以得出結論:所有硬件非確定性的信息,都是理論上不安全的。
所有的盲籤同理,雖然盲籤硬件上有確認,但是這個確認的信息對於用戶來說並不可讀,所以他也滿足硬件非確定性的信息,無法確保不被中間人攻擊。
safe 多簽錢包的案件就是一個典型,錢包構造的籤名信息被服務器惡意 javascript 代碼替換,同時因爲 ledger 錢包是盲籤,導致這一次攻擊的發生。
通信通道的中間人攻擊,方式衆多
除了用戶本地有惡意軟件以外,一些錢包的通信和構建流程可能涉及到服務器(例如一些錢包 encodeTx 需要通過服務端進行構建)。這些都是潛在的攻擊對象和被攻擊點。
通信通道當然還包括硬件層面,例如不安全的電腦攝像頭外設,不安全的 USB 數據線等等。從物理層到應用層,在通信層面,所有環節都有被攻擊的可能。
主動提升安全意識,任重而道遠
客戶端到硬體錢包的完整通信,核心流程理論上是不需要聯網的。所以即使有端到端的加密通信,也無法 100% 確保流程安全。
增加端到端的加密之後,對於真正的黑客來說,增加的只是逆向客戶端,對通信信道的破解成本。而對於攻擊本身,從來都不是難度的較量,而是黑客付出的成本和法律後果的考量。
同時,大部分區塊鏈的產品團隊,一般在面對這類中間人攻擊的威脅時,會將這部分的優化放在整個迭代中處於低優先級,變相等於允許一部分中間人攻擊的風險出現。如上面的團隊溝通郵件,如 Metamask 的 bug bounty 界面,就將 MITM 中間人攻擊排除在外:
所以對於用戶來說,更需要主動我們自身提高防範意識。對於重要資產,即使是使用硬體錢包,也最好隔離電腦,不連接不可信的網路,不訪問不可信的網頁等等等等。
寫在最後
硬體錢包的“安全神話”並非來自單一設備本身,而是建立在整個生態系統的協作安全。
當我們忽視客戶端的可信性、放松對通信通道的防護,那把“達摩克利斯之劍”便悄然懸於我們的資產之上。
真正的安全,從不止於硬件,而在於每一個你以爲“無關緊要”的細節。