區塊鏈研究實驗室|Akropolis駭客攻擊事件:根本原因分析

買賣虛擬貨幣

此事件是由於協議中的錯誤而導致的,該錯誤沒有(1)驗證支援的代幣,以及(2)對存款邏輯實施可重入保護。這種利用導致大量的池代幣沒有得到有價值資產的支援然後贖回這些鑄造的池代幣,從受影響的YCurve和sUSD池中抽走約200萬DAI。
攻擊細節詳解
我們從駭客背後的交易開始分析:0xe1f…e04d。此駭客是從類似ERC20的惡意合約(位於0xe230)初始化的。此惡意合約實現了一個鉤子,只要呼叫transferFrom()(函式簽名:0x23b872dd),該鉤子就會被呼叫。
有了這個準備,駭客首先透過以準備好的0xe230合約作為令牌在SavingsModule.sol中呼叫deposit()來發起攻擊,並在呼叫令牌的transferFrom()函式時,呼叫鉤子函式,該鉤子函式實質上重新 輸入相同的deposit()但具有真實的DAI資產(0x6b17)。但是計算鑄造的代幣池數量的方法取決於存款前後的餘額差(第234-236行)。事實證明,具有真實DAI資產的第二筆存款將被有效計數兩次,以計算鑄造的代幣池數量:一個用於0xe230存款,另一個用於DAI存款。換言之,如果第二筆存款轉移了2.5萬DAI,則造幣池代幣的總數將翻倍,估值為5萬DAI(因為可重入)。


我們的分析表明,攻擊者發起了17次交易攻擊,一共獲得了2,030,841.0177個DAI。請注意,在一開始,就借用了dYdX快速借貸來啟動一系列交易攻擊。
存款邏輯
接下來,我們詳細闡述脆弱存款邏輯。任何Akropolis使用者都可以將代幣存入Delphi儲蓄池,該池將為使用者生成相應的代幣池。核心邏輯是用SavingsModule::deposit()編寫的(第1944行),如下圖所示。


*SavingsModule中的脆弱存款邏輯*
  1. 步驟1:攻擊者使用指定的_tokens作為輸入來呼叫deposit()。此函式計算存款函式depositToProtocol(_protocol,_tokens,_dnAmounts)之前和之後的代幣餘額。然後它使用餘額更改來鑄造poolTokens(第1970行)。在計算餘額變化之間,depositToProtocol()函式在目標代幣上呼叫safeTransferFrom()函式以執行實際的代幣傳輸(第2004行)。但是,沒有對deposit()函式進行重新入場檢查,也沒有對可能是精心設計和惡意的存入代幣進行有效性檢查。

  2. 步驟2:攻擊者在呼叫其transferFrom()函式來呼叫鉤子例程時再次重新輸入deposit()函式。

  3. 步驟3:由於這是第二次存款,該池將向攻擊者鑄造poolToken,因為實際的DAI資產已轉移到協議中並更改餘額。

  4. 第4步:第二次存款完成後,它將在depositToProtocol()中返回到第一次存款的證明,然後再次計算餘額變化!事實證明,餘額差額與第二筆存款完全相同。因此向攻擊者鑄造了相同數量的poolToken。

最終被盜資金目前存放在該錢包中:0x9f26。
---------------------------------------------
原文作者:
PeckShield
譯者:鏈三豐
譯文出處:http://bitoken.world
---------------------------------------------

作者:鏈三豐,來源:區塊鏈研究實驗室

免責聲明:

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

推荐阅读

;