慢霧認爲,攻擊主要在於 EthCrossChainData 合約的 keeper 被修改,而非私鑰泄漏導致。目前,黑客已開始陸續歸還資金。

撰文:慢霧安全團隊

2021 年 08 月 10 日,據慢霧區消息,跨鏈互操作協議 Poly Network 遭受黑客攻擊,慢霧安全團隊第一時間介入分析,並將分析結果分享如下。

攻擊背景

Poly Network 是由 Neo、Ontology、Switcheo 基金會共同作爲創始成員,分佈科技作爲技術提供方共同發起的跨鏈組織。

如下圖,通過官方的介紹我們可以清楚的看出 Poly Network 的架構設計:用戶可以在源鏈上發起跨鏈交易,交易確認後由源鏈 Relayer 將區塊頭信息同步至 Poly Chain,之後由 Poly Chain 將區塊頭信息同步至目標鏈 Relayer,目標鏈 Relayer 將驗證信息轉至目標鏈上,隨後在目標鏈進行區塊頭驗證,並執行用戶預期的交易。

慢霧:詳細覆盤 Poly Network 被黑 6.1 億美元過程及原因

以下是本次攻擊涉及的具體地址:

慢霧:詳細覆盤 Poly Network 被黑 6.1 億美元過程及原因

攻擊核心

  1. 源鏈未對發起的跨鏈操作的數據進行檢查。
  2. 目標鏈未對解析出的目標調用合約以及調用參數進行檢查。
  3. EthCrossChainData 合約的 owner 爲 EthCrossChainManager。
  4. bytes4(keccak256(abi.encodePacked(_method, \”(bytes,bytes,uint64)\”))) 可以被 hash 碰撞。

攻擊細節

Poly Network 會在各個鏈上部署智能合約以便進行跨鏈互操作(分析將以在以太坊部署的智能合約爲例),其中 EthCrossChainManager 合約用於驗證 Poly Chain 同步來的區塊頭以確認跨鏈信息的真實。EthCrossChainData 合約用於存儲跨鏈數據,中繼鏈驗證人 (即 Keeper) 的公鑰也存儲在這個合約中。LockProxy 則用於資產管理。

本次攻擊中,攻擊者分兩步來完成這次攻擊,我們接下來進行詳細分析:

首先攻擊者通過在其他鏈調用 crossChain 函數構造數據發起跨鏈交易。

我們切入此函數進行分析 :

EthCrossChainManager.crossChain

慢霧:詳細覆盤 Poly Network 被黑 6.1 億美元過程及原因

從上圖我們可以清晰的看出,此函數只是用於幫助用戶構造 makeTxParam 並存儲了構造後的哈希以便後續驗證,其並未對用戶傳入的跨鏈操作參數進行任何限制,因此攻擊者完全可以通過構造任意想構造的數據而讓 Relayer 毫無防備的將其同步至 Poly Chain,通過 Poly Chain 將其同步至以太坊 Relayer。

隨後在以太坊上的 Relayer 通過調用 EthCrossChainManager 合約中

的 verifyHeaderAndExecuteTx 函數提交區塊頭信息來驗證這筆跨鏈信息的真實性。

我們切入此函數進行分析:

EthCrossChainManager.verifyHeaderAndExecuteTx

慢霧:詳細覆盤 Poly Network 被黑 6.1 億美元過程及原因

通過上圖代碼我們可以看出其先對區塊頭進行反序列化,以解出所需要驗證的具體信息。隨後調用 getCurEpochConPubKeyBytes 函數從 EthCrossChainData 合約中獲取 Keeper 公鑰,並通過 deserializeKeepers 函數得到 Keeper 地址。

接下來將通過 ECCUtils.verifySig 驗證簽名是否爲 Keeper,從以下代碼中我們可以發現 verifySig 函數中會切出簽名者的 v r s,並通過 ecrecover 接口獲取簽名者地址,然後調用 containMAddresses 函數循環比較簽名者是否爲 Keeper,只要 Keeper 簽名數量符合要求即可通過檢查,數量要求即爲 EthCrossChainManager 合約傳入的 n – ( n – 1) / 3)。

慢霧:詳細覆盤 Poly Network 被黑 6.1 億美元過程及原因

慢霧:詳細覆盤 Poly Network 被黑 6.1 億美元過程及原因

簽名驗證後會通過 ECCUtils.merkleProve 進行默克爾根驗證,只要是正常跨鏈操作即可通過此項檢查。隨後會對交易是否重複發送進行檢查並存儲已驗證後的數據。這裏只需保證不重複提交即可。

慢霧:詳細覆盤 Poly Network 被黑 6.1 億美元過程及原因

最後,也是最關鍵的一步,其將通過內部調用 _executeCrossChainTx 函數執行構造的數據。

慢霧:詳細覆盤 Poly Network 被黑 6.1 億美元過程及原因

慢霧:詳細覆盤 Poly Network 被黑 6.1 億美元過程及原因

從上圖我們可以看出 _executeCrossChainTx 函數未對傳入的 _toContract、_method 等參數進行檢查就直接以 _toContract.call 的方式執行交易。

其中通過鏈上數據我們可以看出 EthCrossChainData 合約的 owner 即爲 EthCrossChainManager 合約,而先前我們知道中繼鏈驗證人 (即 Keeper) 的公鑰存在 EthCrossChainData 合約中,且此合約存在 putCurEpochConPubKeyBytes 函數可以直接修改 Keeper 公鑰。

經過以上分析,結果已經很明確了,攻擊者只需在其他鏈通過 crossChain 正常發起跨鏈操作的交易,此交易目的是爲了調用 EthCrossChainData 合約的 putCurEpochConPubKeyBytes 函數以修改 Keeper 角色。隨後通過正常的跨鏈流程,Keeper 會解析用戶請求的目標合約以及調用參數,構造出一個新的交易提交到以太坊上。這本質上也只是一筆正常的跨鏈操作,因此可以直接通過 Keeper 檢查與默克爾根檢查。最後成功執行修改 Keeper 的操作。

但我們注意到 putCurEpochConPubKeyBytes 函數定義爲

    function putCurEpochConPubKeyBytes(bytes calldata curEpochPkBytes) external returns (bool);

而 _executeCrossChainTx 函數執行的定義爲

    abi.encodePacked(bytes4(keccak256(abi.encodePacked(_method, \"(bytes,bytes,uint64)\")))

我們可以知道這兩個函數的函數簽名在正常情況下傳入的 _method 爲 putCurEpochConPubKeyBytes 肯定是完全不同的,因此通過 _toContract.call 理論上是無法調用到 putCurEpochConPubKeyBytes 函數的。但 _method 是攻擊者可以控制的,其完全可以通過枚舉各個字符組合以獲得與調用 putCurEpochConPubKeyBytes 函數相同的函數簽名,這要求其只需枚舉前 4 個字節符合即可。我們也可以自己嘗試枚舉驗證,如下所示:

慢霧:詳細覆盤 Poly Network 被黑 6.1 億美元過程及原因

慢霧:詳細覆盤 Poly Network 被黑 6.1 億美元過程及原因

可以看出前四個字節與 putCurEpochConPubKeyBytes 函數是一致的

慢霧:詳細覆盤 Poly Network 被黑 6.1 億美元過程及原因

至此我們就已還原出攻擊者的攻擊細節。

通過解析鏈上數據,我們可以發現攻擊者將 Keeper 替換爲了
0xA87fB85A93Ca072Cd4e5F0D4f178Bc831Df8a00B。

慢霧:詳細覆盤 Poly Network 被黑 6.1 億美元過程及原因

慢霧:詳細覆盤 Poly Network 被黑 6.1 億美元過程及原因

最後攻擊者只需使用替換後的 Keeper 地址進行簽名即可通過所有檢查執行調用 LockProxy 合約將其管理的資產轉出。

攻擊流程

  1. 攻擊者在源鏈精心構造一筆修改目標鏈 Keeper 的操作。

  2. 利用官方 Relayer 正常在目標鏈提交數據並執行替換 Keeper 操作。

  3. 攻擊者通過替換後的 Keeper 地址對其轉出資產的操作進行簽名提交至 EthCrossChainManager 進行驗證。

  4. 驗證 Keeper 爲攻擊者已替換完的地址通過檢查,執行將資產轉移至攻擊者指定地址。

  5. 獲利走人。

MistTrack 分析過程

慢霧 AML 團隊分析統計,本次攻擊損失共計超 6.1 億美元

具體如下:

慢霧:詳細覆盤 Poly Network 被黑 6.1 億美元過程及原因

資金流向分析

慢霧 AML 旗下 MistTrack 反洗錢追蹤系統分析發現,攻擊者初始的資金來源是門羅幣 (XMR)。

然後在交易所裏換成了 BNB/ETH/MATIC 等幣種並分別提幣到 3 個地址,不久後在 3 條鏈上發動攻擊。

事件梳理

慢霧:詳細覆盤 Poly Network 被黑 6.1 億美元過程及原因

資金情況 (截止到北京時間 08 月 11 日 13:00)

BSC 上

黑客地址 1,黑客將近 1.2 億美元(包括約 3210 萬枚 BUSD 和約 8760 萬枚 USDC)的流動性添加到 Curve 分叉項目 Ellipsis Finance 中,目前仍在做市無異動。
慢霧:詳細覆盤 Poly Network 被黑 6.1 億美元過程及原因Polygon 上

資金無異動。

Ethereum 上

1)黑客地址 3,只有一筆轉出 13.37 ETH 到地址
0xf8b5c45c6388c9ee12546061786026aaeaa4b682 的交易;

2)黑客在 Curve 上添加了超 9706 萬美元(包括 67 萬枚 DAI 和 9638 萬枚 USDC)的流動性。後又撤銷流動性將 9638 萬枚 USDC 和 67 萬枚 DAI 換成 9694 萬枚 DAI,這筆資金仍停留在地址 3。目前,3343 萬枚 USDT 已被 Tether 凍結。

慢霧:詳細覆盤 Poly Network 被黑 6.1 億美元過程及原因

慢霧:詳細覆盤 Poly Network 被黑 6.1 億美元過程及原因

疑難問答

注:eccm 爲 EthCrossChainManager 合約的簡稱,eccd 爲 EthCrossChainData 合約的簡稱。

:爲什麼 keeper 能更換成功,合約代碼沒有進行鑑權嗎?

:eccd 合約有進行鑑權,僅允許 owner 調用 putCurEpochConPubKeyBytes 更改 keeper,因爲 eccd 合約的 owner 是 eccm,所以通過 eccm 可以更改 keeper 的值。

:爲什麼能簽名一筆更換 keeper 的交易?

:因爲跨鏈要執行的數據沒有判斷好 toContract,所以可能原先的 keeper 以爲是一筆正常的跨鏈交易就簽名了 , 但是他是一筆更換 keeper 的交易。

:爲什麼能繞過代碼 bytes4(keccak256(abi.encodePacked(_method, \”(bytes,bytes,uint64)\”))) 的這個限制,然後執行 putCurEpochConPubKeyBytes(bytes) 函數?

:函數簽名用的是 keccak-256 進行哈希,然後取前面的 4bytes,這種情況下是較容易被 hash 碰撞的。

:黑客更換 keeper 的交易如何被舊的 keepers 簽名?

:keepers 是一個鏈中繼器 (Replayer),會對所有正常用戶的跨鏈請求進行簽名。當用戶在 BSC 上發起跨鏈交易時,keepers 會解析用戶請求的目標合約以及調用參數,構造出一個新的交易提交到以太坊上,並在以太坊上用 eccm 合約調用用戶交易裏包含的目標合約。黑客替換 keeper 的交易本質上也是一筆正常的跨鏈交易,只不過調用的目標合約是 eccd 合約,調用的參數是更換 keeper,所以能被正常簽名。

總結

本次攻擊主要在於 EthCrossChainData 合約的 keeper 可由 EthCrossChainManager 合約進行修改,而 EthCrossChainManager 合約的 verifyHeaderAndExecuteTx 函數又可以通過 _executeCrossChainTx 函數執行用戶傳入的數據。因此攻擊者通過此函數傳入精心構造的數據修改了 EthCrossChainData 合約的 keeper 爲攻擊者指定的地址,並非網傳的是由於 keeper 私鑰泄漏導致這一事件的發生。

慢霧 AML 旗下 MistTrack 反洗錢追蹤系統將持續監控被盜資金的轉移,拉黑攻擊者控制的所有錢包地址,提醒交易所、錢包注意加強地址監控,避免相關惡意資金流入平臺。此外, 特別感謝虎符 Hoo、Poly Network、火幣 Zlabs、鏈聞、WePiggy、TokenPocket 錢包、Bibox、歐科雲鏈等團隊及許多個人夥伴在合規的前提下及時與慢霧安全團隊同步相關攻擊者信息,爲追蹤攻擊者爭取了寶貴的時間。

目前,在多方努力下,黑客開始陸續歸還資金。

來源鏈接:mp.weixin.qq.com