By:yudan@慢霧安全團隊

據慢霧區消息,2021 年05 月28 日, 幣安智能鏈(BSC) DeFi 項目BurgerSwap 被黑,損失達330 萬美元。慢霧安全團隊第一時間介入分析,並將結果分享如下:

攻擊細節分析

BurgerSwap 是一個仿Uniswap AMM 項目,但是和Uniswap 架構有所區別。 BurgerSwap 架構總體分成【Delegate -> lpPlatForm -> Pair】。其中Delegate 層管理了所有的Pair 的信息,並負責創建lpPlatForm 層。然後lpPlatForm 層再往下創建對應的Pair 合約。在整個架構中,lpPlatForm 層充當了Uniswap 中Router 的角色,負責將計算交易數據和要兌換的代幣轉發到Pair 合約中,完成兌換。

本次事件的根本正是出在這種架構的問題上。通過一步步分析攻擊者的交易行為,我們來還原整個攻擊過程的核心:

本次攻擊開始於Pancake 的閃電貸,攻擊者從Pancake 中藉出了大量的WBNB,然後將這些WBNB 通過BurgerSwap 兌換成Burger 代幣。在完成以上的操作後,攻擊者使用自己控制的代幣(攻擊合約本身) 和Burger 代幣通過Delegate 層創建了一個交易對並添加流動性,為後續攻擊做準備。

在完成代幣的創建和準備之後,攻擊者立馬通過PaltForm 層的swapExactTokensForTokens 函數發起了兌換,兌換路徑為【攻擊者自己控制的代幣-> Burger -> WBNB】

接下來進行了最關鍵的一次操作。

由於先前攻擊者在創建交易對的時候使用的是自己控制的代幣,在代幣兌換過程中, _innerTransferFrom 函數會調用攻擊者控制的代幣合約,於是攻擊者可以_innerTransferFrom 函數中重入swapExactTokensForTokens 函數。為什麼攻擊者要這樣做呢?

通過對PlatForm 層的swapExactTokensForTokens 函數進行代碼分析,我們不難發現,合約在調用_innerTransferFrom 函數時首先計算了用戶的兌換數據,然後在_innerTransferFrom 函數的操作後使用預先計算的數據來轉發到底層進行真正的代幣兌換。從這個函數層面來看,就算攻擊者重入了swapExactTokensForTokens 函數,底層調用的swap 函數也是獨立的,咋一看並沒有什麼問題,但是鏈上的一個行為引起了慢霧安全團隊的注意:

我們驚訝地發現,在重入的兌換過程中,兌換的數量竟然沒有因為滑點的關係而導致兌換數量的減少。這究竟是什麼原因呢?看來關鍵是底層的Pair 合約的問題了。我們又進一步分析了底層調用的Pair 合約,代碼如下:

通過分析Pair 的代碼,我們再次驚訝地發現在swap 的過程中,合約竟然沒有在兌換後根據恆定乘積公式檢查兌換後的數值! !也就是說,Pair 合約完全依賴了PlatForm 層的數據進行兌換,導致了本次事件的發生。由於Pair 層本身並不做恆定乘積的檢查,在重入的過程中,PlatForm 層的兌換數據預先進行了計算,在_innerTransferFrom 函數完成後,Pair 的更新數據也沒有反映到PlatForm 層中,導致重入交易中的兌換產生的滑點並不影響下一次的兌換,從而造成了損失。用圖來看的話大概如下:

總結

本次攻擊屬於BurgerSwap 架構上的問題,由於Pair 層完全信任PaltForm 層的數據,並沒有自己再做一次檢查,導致攻擊的發生。最近DeFi 安全事件頻發,針對越來越密集的DApp 攻擊事件,慢霧安全團隊建議DApp 開發者在移植其他協議的代碼時,需充分了解移植協議的架構,並充分考慮移植協議和自身項目的兼容性,且需通過專業安全審計機構的審計後才上線,防止資金損失情況的發生。

攻擊交易參考:

https://bscscan.com/tx/0xac8a739c1f668b13d065d56a03c37a686e0aa1c9339e79fcbc5a2d0a6311e333