梅開二度:PancakeBunny 被黑分析

買賣虛擬貨幣

By:Kong@慢霧安全團隊

據慢霧區訊息,2021 年 07 月 17 日,DeFi 收益聚合器 PancakeBunny 在 Polygon 上的版本遭受閃電貸攻擊,慢霧安全團隊第一時間介入分析,並將結果分享如下。

值得注意的是本次攻擊與 5 月 20 日 PancakeBunny 在幣安智慧鏈上的版本遭受的閃電貸攻擊類似。此前慢霧安全團隊也進行了簡要分析,具體可檢視:代幣閃崩,差點歸零 - PancakeBunny 被黑簡析。

攻擊細節分析

首先攻擊者從 AAVE 中閃電貸借出大量的 USDC、USDT、WETH 代幣,並將借來的 USDC 與 USDT 代幣轉入 SushiSwap 中新增流動性以獲得 SLP。

隨後攻擊者進行了本次攻擊最為關鍵的操作:將新增流動性獲得的 LP 的一小部分抵押至 VaultSushiFlipToFlip 合約中,為獲得 polyBUNNY 代幣獎勵做準備。而其餘大部分 LP 都抵押到 MiniChefV2 中,並將存款收益地址指定為 VaultSushiFlipToFlip 合約。

接下來為了減少攻擊成本,使用借來的 100,000 個 WETH 代幣,在 QuickSwap 中將其兌換成 WMATIC 代幣 (在後面的分析將會說明為何這樣會減少攻擊成本)

隨後攻擊者呼叫了 VaultSushiFlipToFlip 合約的 withdrawAll 函式,以獲取抵押的 SLP 與 polyBUNNY 代幣獎勵。我們切入此函式進行具體分析:

在上圖程式碼第 162 行與 163 行,分別透過 balanceOf 函式與 principalOf 函式獲取攻擊者抵押憑證換算成使用者透過 VaultSushiFlipToFlip 合約在 MiniChefV2 中抵押的 SLP 數量以及使用者在 VaultSushiFlipToFlip 合約中抵押時記錄的 SLP 數量。理論上這兩個數量不應相差太多,但透過分析 balanceOf 函式我們發現:其是透過 balance 函式獲取 VaultSushiFlipToFlip 合約在 MiniChefV2 中抵押的 SLP 數量與使用者持有的憑證佔比相乘得到 amount 的。

由於攻擊者已提前將大量的 SLP 未透過 VaultSushiFlipToFlip 合約直接在 MiniChefV2 合約中抵押並將受益地址指給 VaultSushiFlipToFlip 合約,因此 balance 函式將會獲取到一個比預期大得多的值,而攻擊者的憑證佔比卻又是正常的,最後導致賦給 amount 的是個比預期大得多的值。這就直接導致了在上圖程式碼第 176 行計算出的 performanceFee 引數是個非預期的巨大值。

隨後將此異常的 performanceFee 引數傳入 mintForV2 函式中參與鑄造 polyBUNNY 代幣獎勵的計算,我們切入此函式進行分析:

我們可以發現其透過呼叫 mintFor 函式進行具體的邏輯處理,首先在上圖程式碼第 205 行將 SLP 傳送給 Pair 合約,為後續移除流動性做準備。由於 shouldMarketBuy 函式最終價格比較計算為 false,因此將透過 if 邏輯呼叫 _zapAssets 函式。我們切入 _zapAssets 函式繼續分析:

在 _zapAssets 函式,由於 asset 為 SLP 因此將透過 else if 邏輯先透過呼叫 SushiSwap Router 合約的 removeLiquidity 函式進行移除流動性,隨後透過 _tokenToAsset 函式將移除流動性獲得 USDC 與 USDT 代幣分別在 QuickSwap 中兌換成 polyBUNNY 與 WETH 代幣並在 QuickSwap 中新增流動性。接下來我們對 _tokenToAsset 函式進行分析:

透過簡單分析我們可以發現,其將透過 if 邏輯直接呼叫 zapPolygon 合約的 zapInToken 函式,這裡不再贅述判斷條件的分析。接下來跟進 zapInToken 函式分析:

同樣透過對判斷條件的簡單分析,我們可以指定其將透過上圖程式碼第 133 行進入 else 邏輯,接下來呼叫 _swapTokenForMATIC 函式透過下圖程式碼第 221 行 if 邏輯設定的代幣兌換路徑 “USDC -> WETH -> WMATIC",USDT 代幣的兌換路徑同樣如此。

由於在此之前,攻擊者已經使用借來的 100,000 個 WETH 代幣在 QuickSwap 中 透過 “WETH -> WMATIC” 將其兌換成大量的 WMATIC 代幣,所以上述透過 “USDC/USDT -> WETH -> WMATIC” 路徑兌換到的 WMATIC 代幣變得很少,因此接下來透過 _swapMATICToFlip 函式將 WMATIC 代幣兌換成的 WETH 與 polyBUNNY 代幣就會較少,導致最後轉給 BUNNY_POOL 的 LP 會較少,達到減少消耗攻擊者付出的 SLP 目的,最終減少了一部分攻擊成本。

接下來我們再看 mintFor 函式,在完成上述一系列操作後,將透過 amountBunnyToMint 函式計算需要鑄造的 polyBUNNY 代幣數量,而透過下圖我們可以看出參與計算的 contributionInETH 引數來自於 priceCalculator 合約的 valueOfAsset 函式,但 valueOfAsset 函式接收的引數卻是我們先前所說的 _performanceFee 引數,這是一個非預期的巨大值。

我們可以對 valueOfAsset 函式進行簡單的分析:

由於 asset 是 SLP,因此將透過上圖程式碼第 155 行呼叫 _getPairPrice 函式,透過對此函式進行分析我們可以發現,參與價格獲取的途徑都為可信的預言機,因此攻擊者無法直接操控預言機進行攻擊。但由於參與計算的 amount 即 _performanceFee 是個非預期的巨大值,因此最終透過乘法計算得出的 valueInETH 與 valueInUSD 都是非預期的巨大值。

隨後會將獲得的非預期的 contributionInETH 引數傳入 amountBunnyToMint 函式進行鑄幣數量計算。

而這裡的 priceOfETH 與 priceOfBunny 都取自可信的 ChainLink 與 官方自行喂價的預言機,因此最終經過乘法計算後,得到的鑄幣數量 mintBunny 是個非預期的巨大值。導致最終攻擊者獲得了大量的 polyBUNNY 代幣獎勵。

攻擊流程

1. 攻擊者在 AAVE 閃電貸借出 USDT/USDC/WETH 代幣,並在 SushiSwap 中新增流動性獲得 SLP。

2. 將大部分的 SLP 轉入 MiniChefV2 中並將受益地址指定給 VaultSushiFlipToFlip 合約,小部分抵押到 VaultSushiFlipToFlip 合約中。

3. 由於攻擊者的大部分抵押到 MiniChefV2 中的 SLP 受益地址指定給 VaultSushiFlipToFlip 合約,導致 VaultSushiFlipToFlip 獲取到錯誤的 balanceOf 造成 performanceFee 變成一個非預期的巨大值。

4. 最終鑄造 polyBUNNY 代幣獎勵使用了此非預期的 performanceFee 引數,導致額外鑄造了大量的 polyBUNNY 代幣給攻擊者。

5. 最後攻擊者拋售 polyBUNNY 代幣,歸還閃電貸,獲利走人。

總結

此次攻擊與第一次不同的點在於:並非是預言機被操控導致鑄幣數量錯誤,而是 VaultSushiFlipToFlip 合約獲取在 MiniChefV2 中抵押的抵押品數量時,錯誤地獲取了攻擊者未透過 VaultSushiFlipToFlip 抵押的抵押品數量,導致引數鑄幣的引數異常。最終鑄造出額外的 polyBUNNY 代幣。

參考交易連結:

https://polygonscan.com/tx/0x25e5d9ea359be7fc50358d18c2b6d429d27620fe665a99ba7ad0ea460e50ae55

慢霧導航

慢霧科技官網

https://www.slowmist.com/

慢霧區官網

https://slowmist.io/

慢霧GitHub

https://github.com/slowmist

Telegram

https://t.me/slowmistteam

Twitter

https://twitter.com/@slowmist_team

Medium

https://medium.com/@slowmist

幣乎

https://bihu.com/people/586104

知識星球

https://t.zsxq.com/Q3zNvvF

火星號

http://t.cn/AiRkv4Gz

鏈聞號

https://www.chainnews.com/u/958260692213.htm

免責聲明:

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

推荐阅读

;