以太坊遭到攻擊而導致分叉事件的技術分析 - 冷萃財經

以太坊遭到攻擊而導致分叉事件的技術分析

以太坊遭到攻擊而導致分叉事件的技術分析

北京時間 2021 年 8 月 27 日 20 點 50 分左右(區塊高度 13107518),以太坊突然出現分叉。我們通過分析 Geth 的代碼版本修改和這筆造成分叉的交易(0x1cb6fb36633d270edefc04d048145b4298e67b8aa82a9e5ec4aa1435dd770ce4)釐清了以太坊分叉的根本原因:Geth 舊版本在處理預編譯合約調用時,並未考慮特殊情況(corner case)下參數值的處理,從而引發重疊拷貝(overlapping copy),導致返回值異常。該漏洞(CVE-2021-39137)已提交 Geth 官方,目前尚未披露細節,但攻擊者已經利用漏洞實施了攻擊。我們認為及時的分析和披露是必要的,也希望我們的分析能夠為社區提供必要的理解和幫助。

攻擊分析

運用我們的 ,可以看出:

以太坊遭到攻擊而導致分叉事件的技術分析圖一

這筆交易執行了一個精心構造的 STATICCALL, 攻擊者將 addr 設為 0x04 (是預編譯合約 dataCopy), inOffset 為 0, inSize 為 32, retOffset 為 7, retSize 為 32。

以太坊遭到攻擊而導致分叉事件的技術分析圖二

由於 STATICCALL 的目標地址是預編譯合約,所以會執行圖二中的 RunPrecompiledContract。

以太坊遭到攻擊而導致分叉事件的技術分析圖三

以太坊遭到攻擊而導致分叉事件的技術分析圖四

根據圖三和圖四的代碼,可以看到預編譯合約 0x04 真正執行的邏輯只是簡單地把 in (指針)返回。

以太坊遭到攻擊而導致分叉事件的技術分析圖五

以太坊遭到攻擊而導致分叉事件的技術分析圖六

圖五是 STATICCALL 的執行過程,753 行是執行預編譯合約的入口,751 行的 args 指向 EVM 的 Memory 中 inOffset ~ inOffset + inSize 這篇區域的指針,也就是說 args 指向 Mem[0:32]。

根據圖六以及前文對預編譯合約 0x04 (dataCopy)的分析,我們可以知道 753 行的返回值 ret 是與 args 完全相同的指針,也指向 Mem[0:32]。

  • 在 1.10.7 版本的 Geth 中(有 Bug): 762 行將 ret 指向的值賦給 EVM 的 Memory 中 retOffset ~ retOffset + retOffset 這篇區域 , 也就是將 Mem[0:32] 的值賦給 Mem[7:7+32],而由於 ret 是一個指向 Mem[0:32] 的指針,這次 Memory.Set 修改了 Mem[7:32] 的值,也就修改了 ret 所指的值。所以在第 771 行返回的 ret 已經不是預編譯合約執行結束時的 ret 了。
  • 在 1.10.8 版本的 Geth 中(無 Bug): 增加了 766 行:ret = common.CopyBytes (ret), 將 Mem[0:32] 中的值做了一次深拷貝賦給 ret,那麼在 767 行執行的 Memory.Set 只會修改 Memory 而不會修改 ret, 在 771 行返回的 ret 就是正確的 ret。

總結

通過對整個攻擊流程的梳理和 Geth 源代碼的分析,我們認為根本原因在於 Geth 舊版本在處理預編譯合約的調用時並未考慮異常值的處理,導致攻擊者利用該漏洞實施了重疊拷貝,影響了返回值,最終導致分叉的出現。由於 Geth 是 BSC、HECO、Polygon 等公鏈的基礎,因此該漏洞影響範圍甚廣。目前各公鏈也先後推出了升級和補丁,我們也呼籲各相關節點儘早升級打上補丁,以確保基礎設施的安全。

冷萃財經原創,作者:Awing,轉載請註明出處:https://www.lccjd.top/2021/08/30/%e4%bb%a5%e5%a4%aa%e5%9d%8a%e9%81%ad%e5%88%b0%e6%94%bb%e5%87%bb%e8%80%8c%e5%af%bc%e8%87%b4%e5%88%86%e5%8f%89%e4%ba%8b%e4%bb%b6%e7%9a%84%e6%8a%80%e6%9c%af%e5%88%86%e6%9e%90/?variant=zh-tw

0

掃一掃,分享到微信

猜你喜歡

文章評論

電子郵件地址不會被公開。 必填項已用*標註

後發表評論

    上一篇

    NFT闖進收藏品市場背後,隱藏著巨大的商機

    下一篇

    鎖倉量 3 天流入 10 億美元,Avalanche 雪崩協議估值是否合理?

    微信公眾號

    微信公眾號