PeckShield:bZx協議再遭駭客“二連擊”背後的技術命門

買賣虛擬貨幣
PeckShield 團隊在上一篇文章《PeckShield:硬核技術解析,bZx協議遭駭客漏洞攻擊始末》中分析了 bZx 於02月15日遭到駭客一次可組合資產流動性攻擊,那是由於 bZx 合約對抵押品狀態判斷不完善導致的。02月18日,bZx 再次遭遇了類似的攻擊,這一次的攻擊從技術原理與上一次不同,此次駭客是透過操縱 Oracle 價格對 bZx 合約進行了“矇騙”。

從攻擊流程上來看,這一次與上次剛好相反,但整體上的套利手段還是一致的,根本原因主要是由於平臺間共享流動性過小以及價格機制設計缺陷導致的。

本文的初衷是希望透過分析此漏洞的一些攻擊細節讓大家能夠更直觀的瞭解此次攻擊事件,並希望可以引起更深入的討論。我們相信,這些討論將對 DeFi 社羣的完善和發展是十分有益的,特別是專案方在開發下一代的 DeFi 類產品時,可以有助於設計出更安全,更可靠的流動性共享模型。

漏洞的攻擊細節如下:

此攻擊事件發生在北京時間 2020-02-18 11:18:58(塊高度#9504627 )。攻擊者的交易資訊可以在 etherscan 上查到。此攻擊過程可以分為以下五個步驟:

第一步:閃貸獲取可用資產

bZx 合約有一個 flashBorrowToken() 介面,允許呼叫者可以“零成本”從 bZx 平臺上借出資產參與 DeFi 活動,之後在完成這一筆交易的時候償還這部分資產。且呼叫者在借出資產的同時,可以指定資產的接收方地址。 

本次攻擊者向 bZx 平臺借出 7,500 ETH,並指定攻擊者的合約(此前已經部署)為資產接收方地址,這部分是基本的借貸功能,此處不做進一步解釋。

當這一步操作過後,如下表中所示系統資產分佈:

第二步:拉昇 sUSD

首先,我們介紹一下今天攻擊者的最佳配角:sUSD,sUSD 是由 Synthetix 專案方發行的穩定幣,其幣價正常情況下與 1 美元持平,總髮行量為 5,563,037 枚(統計於 2020年02月18日)。

透過第一步閃貸獲得 ETH 後,攻擊者分兩批共 900 ETH 透過 KyberNetwork DEX 換取成 sUSD。其中第一次 使用 540 ETH 換取,(KyberNetwork 內部查詢得到 KyberUniswap 的價格是最優的)攻擊者得到 92,419 枚 sUSD;第二批分 18 次,每次 20 ETH 換取,(KyberNetwork 查詢之後確認 Kyber-sUSD 的價格是最合適的),攻擊者獲得 63,584 枚 sUSD,總共獲得了 156,003 枚 sUSD。 

這兩步驟也是正常的 DEX 幣幣交換的過程,在這兩個批次操作之後 sUSD 對 ETH 的價格瘋漲到了 0.00899,是市場價的 2.5 倍。

在這一步之後,使得 sUSD 價格被抬高了 1.5 倍,攻擊者手裡的資產還是正常與 KyberNetwork 互動,並沒有實質性的攻擊發生。然而,KybrNetwork 內部透過 Uniswap 完成 sUSD 與 ETH 轉換,這使得那些將 Uniswap 作為 sUSD/ETH Oracle 的其它平臺(比如說 bZx)誤認為當前 sUSD 價格的確有這麼高,這才觸發了後面的攻擊事件。此時,系統的資產如下:

第三步:吸納更多籌碼

攻擊者希望將手裡的 6,000 ETH 透過 Synthetix exchangeEtherForSynths() 介面全部換成 sUSD。而 Synthetix 這邊也沒有足額的 sUSD 來促成這筆交易,只交換了其中的 3,518 枚 ETH,並將剩餘的 2,482 枚 ETH 返還給攻擊者,攻擊者獲得了 943,837 枚 sUSD。

到此為止,攻擊者手裡已經擁有的 sUSD 總量為 1,099,841 枚,佔總發行量的  19.7%。

當前系統中的賬本資料如下:

第四步:抵押借款

攻擊者將手裡擁有的 1,099,841 枚 sUSD 透過 bZx 的 borrowTokenFromDeposit() 介面全部抵押到 bZx 合約之中,按照 sUSD/ETH 正常價格的話,bZx 應當借給攻擊者 3,928 ETH,但是 bZx 從 Oracle Kyber 這邊獲取的價格偏高,使得借出了 6,796 枚 ETH,多借了 2,868 ETH。

到此為止,系統的賬本資訊如下:

第五步:閃貸還款

攻擊者利用從 bZx 借到的 6,796 枚 ETH 以及手中剩餘的資產一起還給之前從 bZx 借出來的 7,500 ETH,然後退場離開,完成閃貸操作。 

完成整個閃電貸流程之後,當前資產情況:

1)bZx 平臺對攻擊者借出的 6,796 ETH;
2)bZx 平臺持有 1,099,841 枚 sUSD;
3)攻擊者手上還持有 2,378 枚 ETH。

最終攻擊者手中持有的 2,378 ETH 部分為其獲利,合計 $665,840(當前 ETH 價格$280);而 bZx 平臺負債為 2,868 ETH(6,796 - 1,099,841/280),即 $803,040。

總結

這一次的攻擊事件中,我們能看出 DeFi 產品在設計過程中幾個明顯的問題點:

1)當引入第三方 Token 的時候,需要考察第三方 Token 的安全性,有沒有可能被單方面市場操縱,從而引起價格波動;
2)DeFi 平臺自身應當有價格容錯與檢驗機制,使用第三方 Oracle 獲取價格的時候,對他方的資料有儘可能多的驗證;
3)平臺自身對於價格也應當設立止水閥機制。

從第一次 bZx 被攻擊損失 1,271 枚 ETH,這一次又損失 2,378 枚,且這兩次攻擊之間只相差了 3 天時間,可見 DeFi 特別專案的安全問題非常嚴峻。

由於各專案由不同團隊開發,對各自產品的設計與實現理解有限,整合的產品很可能在與第三方平臺互動的過程中出現安全問題,進而腹背受敵。PeckShield 在此建議,DeFi 專案方在上線之前,應當儘可能尋找對 DeFi 各環節產品設計有深入研究的團隊做一次完整的安全審計,以避免潛在存在的安全隱患。

免責聲明:

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

推荐阅读

;