安全事件一直都是區塊鏈生態最大的威脅之一,需要專案方時刻保持警惕。

作者:Sivan,Beosin 安全研究專家

封面:Photo by Mika Baumeister on Unsplash

上一篇文章我們介紹了近期區塊鏈生態中發生的騙局類資金安全問題,包括後門以及貔貅盤。 除了這些騙局事件,近期安全事件也對整個區塊鏈生態造成了巨大的影響。

最近發生大量的安全攻擊事件,這些事件對於專案方來說具有重大影響。 攻擊事件的發生主要原因之一是業務邏輯設計不當,其中可能存在漏洞或弱點,被駭客利用進行攻擊。 另外,價格操控也是導致安全攻擊事件的因素之一,駭客可能通過操縱價格或市場行為來實施攻擊。

本篇文章我們一起來盤點一下近期常見攻擊都有些什麼特點,以及專案方如何避免這些問題。

一、業務邏輯設計不當

Pair 代幣意外銷毀

近期因為業務邏輯設計不當發生的安全事件,大多都是由於 pair 代幣餘額異常導致的。
一些代幣專案,會在業務設計中添加交易手續費或代幣通縮的功能,也就是在代幣轉移過程中,會收取相關比例的手續費或者直接銷毀部分轉移的代幣。  這本是一個專案的創收或激勵使用者持有代幣或其他有助於專案發展的業務邏輯,但如果代碼設計不夠完善,便會出現嚴重的問題。

例如,在轉賬過程中,有些專案進行額外代幣扣除時,沒考慮到 pair 意外扣除將導致嚴重後果。 該類項目的轉帳函數邏輯一般是發送方和接收方進行正常的代幣轉移,並且額外扣除某個位址部分費用,用於手續費或銷毀。 但額外扣除位址為 pair 時,會導致 pair 中其中一個代幣餘額通過非交易的方式變少,k 值異常變化,從而使用少量代幣便能兌換出大量另一個代幣。

以下列項目代碼為例:

該代幣合約中存在意外銷毀 pair 餘額的問題,當代幣轉移發起者不是 pair 合約時,會進行更新池子的操作,該更新池子的方式是將 pair 的代幣餘額扣除交易金額的 1%,再更新儲備量。  駭客可以通過調用 transfer 函數自己給自己轉帳,反覆操作,將會使得 pair 中的一個代幣消耗得極少,最後利用極少代幣將 pair 中大量的價值幣兌換出來。

以下是真實安全事件過程:

首先使用 2555 枚 WBNB 兌換了 1390 億枚 Bamboo 代幣;

不斷通過 transfer 將代幣發送給自己,導致 pair 中 Bamboo 代幣異常減小;

使用 139B 枚 Bamboo 代幣兌換回 2772 枚 WBNB,完成攻擊。

再以另一個意外銷毀 pair 代幣的例子說明一下,如下圖代碼。 合約會判斷當前交易類型,如果為 2(to 位址為 pair 合約,相當於賣幣),合約會記錄一個交易量的 20% 作為銷毀數量,後續可以調用 goDead()函數將 pair 中這個累積數量銷毀,該功能對穩定幣價能起部分作用。

但是合約沒考慮到一些特殊情況,例如直接向 pair 裡面轉幣,這時會使得合約誤以為使用者是在賣幣,這部分幣可以通過 pair 的 skim 函數全部提取出來。 相當於 pair 沒有任何變化,再次調用 goDead()函數時,卻能使得 pair 中的代幣意外減少,重複操作,便能耗盡 pair 其中一種代幣。

以下同樣是真實安全事件過程:

不停通過 transfer 與 skim 操作,將 amountToDead 值控制得異常大。

調用 goDead()函數將 pair 中的代幣銷毀掉。

使用少量代幣兌換了大量的 USDT。

總結:

代幣的 transfer 函數一定要認真設計代幣轉移邏輯,一定要避免 pair 餘額意外扣除的情況,pair 餘額僅在添加流動性、移除流動性以及交易過程中才能改變,並且改變數量盡量不要大於或小於傳入數量,才能保障 pair 資金健康。

二、價格操控問題

對於價格操控的攻擊事件,主要是由於專案方合約在獲取價格的時候沒有考慮到價格被意外控制的情況。 特別是對於存在兩個逆向計算的業務邏輯函數,如 stake&unstake、deposit&withdraw 等,兩種操作一般都使用相同的參數但相反的計算邏輯。

而在這兩種操作之間,如果能通過其他函數或合約將其中的部分或全部參數進行不對等的控制,那麼兩種操作之間便可能存在價格差,從而導致資產被盜。

1、只讀重入

重入一直是區塊鏈生態中最常見也是危害最大的漏洞之一。 在乙太坊最開始盛行的時候,重入攻擊大多是因為乙太坊轉帳調用的目標函數 fallback()中再次發起了對該專案合約的調用,此時專案合約變數還未更新,可以繞過相關檢查,如 DAO 事件。

隨著乙太坊生態越來越豐富,各個專案方更加註重這一方面的防護以及 solidity0.8.0 版本之後對溢出的主動檢查,現在更多的攻擊事件是通過重入來控制某些價格或參數,來達到攻擊的目的。

例如近期發生頻繁的只讀重入,便是通過重入前後變數未修改完全,使得重入中調用的計算價格的函數出現異常,從而導致資產被盜。

有興趣的讀者可以參考如下連結:安全審計必備知識 | 難以防範的 “只讀重入攻擊” 是什麼?

2、Pair 餘額依賴

Pair 可以最直觀的表現出代幣價格變化,也是最準確的價格獲取管道,但 pair 中的價格是暫態價格,並且可以通過大量代幣兌換來控制,導致瞬間暴漲或暴跌。 如果依賴 pair 中的價格作為業務中的參數參與計算,那麼便可能導致異常的結果。

如下代碼,burnForEth 函數通過依賴 pair 中能兌換出的數量來作為本合約發送給調用者的 ETH 數量,該數量是通過 pair 中兩種代幣餘額來進行計算。 正常情況下這是一個最準確的價格,但是如果提前使用 ETH 將 pair 中的另一個代幣大量兌換出來,會導致 ETH 在該 pair 中的價格暴跌,從而計算出能兌換的 ETH 就會異常大,使得合約給調用者發送更多的 ETH。 最後,調用者通過 pair 將 ETH 兌換回來,使價格恢復正常。

以下是真實安全事件過程:

攻擊者使用閃電貸的 ETH 將大量 WAX 代幣兌換出來,導致 WAX 價格暴漲。

攻擊者不斷調用 burnForEth 函數,銷毀 WAX 來取出 ETH,此時使用的 WAX 價格時暴漲過後的,可以獲得更多的 ETH。

最後,攻擊者將 ETH 兌換出來,歸還閃電貸並獲利。

總結:

安全事件一直都是區塊鏈生態最大的威脅之一,需要專案方時刻保持警惕。  對於需要計算價格的業務邏輯要有嚴格的流程把控,盡量避免直接使用 pair 餘額進行價格計算,調用外部函數獲取價格也需要考慮其是否能被操控。  專案方也可以與專業的安全合作夥伴合作,及時發現並應對潛在的安全威脅。

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