閃電貸攻擊偷襲

封面:Photo by Abdullah Ahmad on Unsplash

北京時間 2024 年 1 月 30 日,據 Beosin 旗下 EagleEye 安全風險監控、預警與阻斷平臺監測顯示,DeFi 協定 MIM_Spell 遭駭客閃電貸攻擊,導致了超 600 萬美元的損失。  目前攻擊者將被盜資金兌換為 ETH,並轉移到兩個攻擊者位址上,Beosin KYT 將對資金進行持續監控,同時我們對本次漏洞進行了分析。

漏洞分析

該事件發生的主要原因是攻擊者利用了專案方合約使用了向上取整的演算法,並且控制了參數為 1,將向上取整的誤差控制的最大,從而導致帳本失衡。

合約存在兩個函數,分別是 borrow 和 repay,一個是向合約借錢,一個是還錢給合約。

Borrow 函數將指定借款數額,並且通過比例轉換計算出債務值,更新到調用者的總債務值。 如下圖,這裏合約的 add 演算法採用了向上取整。

Borrow 函數將指定還款債務值,並且通過比例轉換計算出還款數額,將還款數額轉移到本合約。 如下圖,這裏合約的 sub 演算法依然採用了向上取整。

瞭解了借款和還款的過程,我們來看看駭客是如何利用該漏洞的。

駭客先將合約的借款數額與債務值控制為了 0 與 97(如何控制將在下一節介紹)。

接下來不停調用 borrow 和 repay 函數,並且借款和還款數值都為 1,最後將借款數額與債務值控制為了 0 和 120080183810681886665215049728,導致比例嚴重失衡。

根據上述代碼規則(elastic=0,base=97),當攻擊者調用一次 borrow 並傳入 1 時,兩個帳本將變為 elastic=1、base=98(elastic 為 0 時,將按數值同步增加),再次調用一次 borrow 並傳入 1 時,將變成 elastic=2、base=196(elastic 不為 0 時,將按比例同步增加)。

接下來攻擊者調用 repay 函數傳入 1,將調用 sub 函數,此時計算出來的 elastic 應該等於 1*1/196=>0,但是演算法向上取整,導致計算出來 elastic=1,結果將變成 elastic=1、base=195。 可以看到,此時 elastic 不變,base 卻翻倍。

攻擊者通過多次上述方式,將 elastic=0、base=120080183810681886665215049728。 最終通過一筆 borrow 將合約 500 多萬 MIM 借貸出來。

攻擊流程

明白了函數問題點,我們來看看攻擊者是如何實施攻擊的(其中一筆交易為例)。
1. 攻擊者首先借貸了 30 萬枚 MIM。

2. 隨後,攻擊者在回調函數中查詢借款數額與債務值,可以看到,此時為 24 萬和 23 萬。

3. 接下来攻击者调用 repayForAll 函数,归还了 24 万 MIM 代币,将 elastic 控制得极小

4. 接下来,攻击者通过 repay 函数归还了其他用户的负债,最终将借款数额与债务值控制为了 0 与 97。 

5. 攻击者新创建合约,并通过上诉 borrow 与 repay 的方式,将借款数额与债务值控制为了 0 和 120080183810681886665215049728。 

6. 最終通過一筆 borrow 將 500 萬 MIM 借貸出來,並歸還閃電貸。

資金追蹤

截止發稿,被盜的超 600 萬美元的資金,全部被攻擊者兌換為了 ETH,並且一直分散存在駭客位址未移動,Beosin KYT 反洗錢平臺將對資金進行持續監控。

免責聲明:作為區塊鏈資訊平臺,本站所發佈文章僅代表作者及嘉賓個人觀點,與 Web3Caff 立場無關。 文章內的資訊僅供參考,均不構成任何投資建議及要約,並請您遵守所在國家或地區的相關法律法規。