去中心化借貸平台 Lendf.Me 攻擊分析

# 事件簡介

2020 年 4 月 19 日,去中心化的借貸平台 Lendf.Me 遭到攻擊,損失大約 2500 萬美元:

p1

來源:Medium

# 漏洞分析

本次事件的主要是利用 ERC777 的 tokensToSend 的 hook 函數進行重入攻擊,ERC777 相對於 ERC20 多了 tokensToSendtokensReceived 的 hook 函數,token 發送者可以透過 setInterfaceImplementer 註冊一個包含 tokensToSend 方法的合約,當 token 由發送者送出時會就調用 tokensToSend 函數,這個設計讓發送者可以利用這個機制統一控制 token 的轉移。

Lendf.Me 為一個借貸平台,其中 MoneyMarket 為存款(supply)與提款(withdraw)的主要合約,存款與提款流程如下圖所表示:

p2

攻擊者利用 tokensToSend hook 函數調用 withdraw,導致錯誤的餘額被更新至合約。

如下圖所示,按照箭頭的執行順序會發現在 withdraw 最後更新完用戶餘額後回到 supply 又更新了一次餘額 但這次的更新的餘額卻是 withdraw 之前所取得的餘額:

p3

# 攻擊分析

攻擊者地址為 0xa9bf70a420d364e923c74448d9d817d3f2a77822,在 4 月 19 日 12:43:52 建立了 0x538359785a8d5ab1a741a0ba94f26a800759d91d 攻擊合約,接著展開一系列的攻擊。

0xae7d664bdfcc54220df4f18d339005c6faf6e62c9ca79c56387bc0389274363b 為例,可以看到它存了 0.002 顆 imBTC,卻取了 0.004 出來:

p4

就這樣不斷存入再以兩倍取出,過了約 12 分鐘後,在交易 0x111aef012df47efb97202d0a60780ec082125639936dcbd56b27551ce05c4214 可以看到存入的數量已經是 113 顆,而取出的數量為 226 顆。

# 修補建議

防止重入攻擊主要有兩種方法:

# 第一種:ReentrancyGuard

原理是利用一個 private 變數紀錄進出函數的狀態,每次進入函數都會先檢查狀態,以確保進入函數後不會調用同一合約的函數。

以本事件為例 如果 supplywitdraw 函數都受到 ReentrancyGuard 保護,那進入 supply 函數後就不能再進入 withdraw 函數了,所以交易會直接失敗。

這個方式的優點是開發容易,但缺點則是會失去一些智能合約的可組合性,可參考 openzeppelin 的實作:https://docs.openzeppelin.com/contracts/4.x/api/security#ReentrancyGuard

# 第二種:Checks-Effects-Interactions 模式

防止重入最好的方法應該是讓開發者使用 Checks-Effects-Interactions 模式;以本事件為例,若將更新餘額與轉移資產順序對調,就會符合 Checks-Effects-Interactions 模式,如下圖所示:

p5

# 總結

在智慧合約進行外部呼叫相關的操作時,應該注意是否有重入攻擊的風險,如果有的話,請務必使用上面提到的兩種方式去做保護,才能杜絕此類攻擊。

另外,Lendf. Me 的智慧合約其實是從 Compound v1 修改而來,而 Compound 本身當時因為不接受 ERC777 的 token,所以才沒出事。而許多借貸合約都是從 Compound fork 出來的,就需要特別留意同類型的風險。

參考資料:

  1. A Summary of the Attack on Lendf.Me on April 19, 2020
  2. Uniswap/Lendf.Me Hacks: Root Cause and Loss Analysis
  3. 慢霧分析|DeFi 借貸協議 Lendf.Me 被駭細節分析及防禦建議
  4. [BlockSec DeFi攻击系列之六] 终而复始:Uniswap重入事件
  5. Uniswap / Lendf.Me遭受攻击的根本原因和损失分析
  6. 去中心化金融平台Lendf.Me黑客攻击事件分析

Tag

Recommendation

  1. OpenAI Embeddings 與 Retrieval-Augmented Generation在實務中的應用與挑戰
  2. DNS Hacking 小番外之:談談 zone walk
  3. 關於我在 Glints 找到的高風險漏洞
  4. 來談談後端快取策略
  5. Intigriti 七月份 XSS 挑戰:突破層層關卡

Discussion(login required)