0x協議漏洞原理剖析:惡意掛單可擾亂正常交易秩序

買賣虛擬貨幣

昨天,去中心化交易所協議 0x 專案方稱其發現嚴重安全漏洞。PeckShield 安全人員跟進分析發現,0x Exchange 合約在校驗訂單簽名時存在缺陷,導致攻擊者可以進行惡意掛單,進而將使用者的數字資產低價賣出,擾亂正常的交易秩序。所幸專案方及時發現並修復問題,截至目前,尚未有真實攻擊發生,並沒有產生數字資產損失。

背景

北京時間2019年07月13日,去中心化交易所 0x 協議專案方稱其發現嚴重安全漏洞,並緊急關閉了 0x Exchange v2.0 合約,隨後部署了修復後的合約。受此影響,基於 0x 協議的交易所及錢包,包括 Radar Relay,Tokenlon, Star Bit 等緊急暫停了相關交易服務。

PeckShield 安全人員跟進分析發現,0x Exchange 合約在校驗訂單簽名時存在缺陷,導致攻擊者可以進行惡意掛單,進而將使用者的數字資產低價賣出,擾亂正常的交易秩序。

0x 協議簡介

0x 協議是一個基於以太坊的開放協議,實現鏈上資產的點對點交易。它期望在以太坊上建立一種標準協議,使得任何人能夠基於此協議執行去中心化交易所,實現以太坊上的代幣之間的交易。0x 協議上的交易特點是鏈下訂單撮合,鏈上結算,其中為使用者交易提供訂單服務的參與者稱為中繼者。0x 專案發行了自己的代幣 ZRX,一方面作為去中心化治理投票權的證明,同時也被作為交易服務費,用於建立在 0x 協議之上的中繼者提供服務的收益。

0x 協議受到不少去中心化交易所和錢包的青睞,從 Etherscan 的 DEX 過去七天交易份額的餅圖中能看到,排名靠前的 Radar Relay 和 Tokenlon 都是基於 0x 協議:

另外,從 DAppTotal 的 DEX 24小時交易額排名中也能看到它們的排名:

由於 Ethereum 平臺上大量的 DEX 都使用了 0x 協議,而作為最根本的 Token Tranfer 主合約出問題,這對於整個 DEX 領域來說,都是比較重大的事件。

漏洞原理分析

本次漏洞共涉及 isValidWalletSignature() 和  isValidValidatorSignature() 兩個相似的漏洞,由於兩者出問題的程式碼是相似的,本文只以前者為例說明。

isValidWalletSignature(bytes32, address, bytes) 函式用於驗證給定的 Wallet 合約所定義的簽名資訊與給定的簽名是否一致,用於確保 Order 是由正確的 Maker/Taker 執行的交易。但是 0x Exchange 合約在驗證的過程中,存在著比較嚴重的問題:

上圖是這一函式的全部邏輯,分為兩部分:

1. 組裝簽名具體欄位為 ABI 編碼格式;
2. 根據組裝的 ABI 編碼內容計算簽名值正確性。

其中,第 2 步的邏輯,在 0x v2 合約程式碼中是用匯編實現的:

1. 引入 cdStart 指標,指向 calldata 中對應的位置;
2. 對 WalletAddress 呼叫 staticcall() OpCode 計算簽名正確性,

注意觀察程式碼,其中的 input 和 output 都為 cdStart 這一指標,即複用 input/output 的記憶體;

3. 檢驗步驟 2.2 中的結果是否正確。

WalletAddress 為合約的前提下,這樣子的流程沒有問題。先來看下 EVM 中合約的執行流程是怎樣的,PeckShield 安全人員查閱 EVM 原始碼的時候發現:

當被呼叫的合約(即這裡的 WalletAddress )沒有 code, 也就是 EOA 賬號的情況下,什麼都沒有的執行,直接返回。因此,對應到 isValidWalletSignature(bytes32, address, bytes) 函式來說,其中的 cdStart 所對應的記憶體內容在呼叫 staticcall() 前後並沒有變化,而後面在判斷簽名是否正確的 isValid 取值的時候,也就取到了錯誤的值。

使用者透過 fillOrder(Order, uint256, bytes) 函式完成 Token 買賣,PeckShield 安全人員發現,這一函式的三個引數可以由使用者自由配置:

分別為:

1. 代表訂單資訊的 Order 型別;
2. 使用者為此訂單付出的 Token 數量;
3. Order 對應的簽名資訊 signature

其中比較關鍵的是 Order 及對應的 signature 資訊的一致性正是透過上面的 isValidWalletSignature() 類函式校驗,因此,當攻擊者精心構造 signature 為 SignatureTypeWallet 時,可『跳過』簽名合法性檢查,從而使得使用者在不經意之間被惡意掛單(甚至是低價掛單),從而被攻擊者順利吃單,由於這一訂單資訊是由攻擊者直接傳入合約的,因此這一訂單資訊線上下的中繼者也無法查詢。

漏洞影響分析

基於上述分析發現,曾在 0x 協議 Exchange 上做過授權轉賬的普通使用者帳號都將受到影響:

攻擊者可偽造使用者掛單,低價獲得使用者代幣。

鑑於此安全漏洞的危害性,PeckShield 安全人員發現 0x 專案方在漏洞被發現的時候先緊急關閉了 0x Exchange v2.0 合約的 Token transfer 功能,將所有的 ERC20、ERC721、以及 MultiAsset 的 Transfer  功能全部下線;隨後部署了修復後的合約,同時告知使用者及使用了 0x Exchange 的所有 DEX 及 Relayer,相關的遷移升級工作正在進行中。受此影響,基於 0x 協議的交易所及錢包,包括 Radar Relay, Tokenlon, Star Bit 等緊急暫停了交易服務。

PeckShield 安全人員透過漏洞特性分析鏈上資料發現,從 0x Exchange 2018-09 上線至今,並沒有因此安全漏洞造成的使用者直接資產損失。

對於使用了 0x 的 DEX 及錢包來說,當前的階段需要暫停交易服務,如無法暫停交易服務的話,可將對應的 0x Exchange 合約地址變更為當前已經修復的合約地址。

結語

0x 協議本次出現漏洞的合約程式碼,主要是內聯彙編程式碼編寫簽名驗證功能出現的問題,直接編寫彙編程式碼雖然在編譯器無法最佳化合約程式碼的情況下非常有用,可控性更強且能提高執行效率,減少 Gas 消耗,但是編寫 Solidity 彙編程式碼需要對 EVM 執行機制有非常熟悉的理解,不然 EVM 的某些特性可能導致編寫的合約無法正常執行,同時也缺少了 Solidity 提供的多種安全機制。

PeckShield 安全人員在此提醒廣大開發者及時排查合約的相關程式碼,避免類似問題可能造成的安全風險,對於 DEX 等 DeFi 類專案,專案方在上線前需要找有資質的安全公司審計安全風險。

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;