以太坊代幣「假充值」漏洞細節披露及修複方案

以太坊代幣“假充值”漏洞影響面非常之廣,影響對象至少包括:相關中心化交易所、中心化錢包、代幣合約等。單代幣合約,我們的不完全統計就有 3619 份存在“假充值”漏洞風險,其中不乏知名代幣。相關項目方應儘快自查。由於這不僅僅是一個漏洞那麼簡單,這已經是真實在發生的攻擊!出於影響,我們採取了負責任的披露過程,這次攻擊事件的披露前後相關時間線大致如下:

2018/6/28 慢霧區情報,USDT “假充值”漏洞攻擊事件披露

2018/7/1 慢霧安全團隊開始分析知名公鏈是否存在類似問題

2018/7/7 慢霧安全團隊捕獲並確認以太坊相關代幣“假充值”漏洞攻擊事件

2018/7/8 慢霧安全團隊分析此次影響可能會大於 USDT “假充值”漏洞攻擊事件,並迅速通知相關客戶及慢霧區夥伴

2018/7/9 慢霧區對外發出第一次預警

2018/7/10 慢霧安全團隊把細節同步給至少 10 家區塊鏈生態安全同行

2018/7/11 細節報告正式公開

漏洞細節

以太坊代幣交易回執中 status 字段是 0x1(true) 還是 0x0(false),取決於交易事務執行過程中是否拋出了異常(比如使用了 require/assert/revert/throw 等機制)。當用戶調用代幣合約的 transfer 函數進行轉賬時,如果 transfer 函數正常運行未拋出異常,該交易的 status 即是 0x1(true)。

以太坊代幣“假充值”漏洞細節披露及修復方案

如圖代碼,某些代幣合約的 transfer 函數對轉賬發起人(msg.sender)的餘額檢查用的是 if 判斷方式,當 balances[msg.sender] < _value 時進入 else 邏輯部分並 return false,最終沒有拋出異常,我們認為僅 if/else 這種溫和的判斷方式在 transfer 這類敏感函數場景中是一種不嚴謹的編碼方式。而大多數代幣合約的 transfer 函數會採用 require/assert 方式,如圖:

以太坊代幣“假充值”漏洞細節披露及修復方案

當不滿足條件時會直接拋出異常,中斷合約後續指令的執行,或者也可以使用 EIP 20 推薦的 if/else + revert/throw 函數組合機制來顯現拋出異常,如圖:

以太坊代幣“假充值”漏洞細節披露及修復方案

我們很難要求所有程序員都能寫出最佳安全實踐的代碼,這種不嚴謹的編碼方式是一種安全缺陷,這種安全缺陷可能會導致特殊場景下的安全問題。攻擊者可以利用存在該缺陷的代幣合約向中心化交易所、錢包等服務平臺發起充值操作,如果交易所僅判斷如 TxReceipt Status 是 success(即上文提的 status 為 0x1(true) 的情況) 就以為充幣成功,就可能存在“假充值”漏洞。如圖:

以太坊代幣“假充值”漏洞細節披露及修復方案

參考示例 TX:

https://etherscan.io/tx/0x9fbeeba6c7c20f81938d124af79d27ea8e8566b5e937578ac25fb6c68049f92e

修復方案

除了判斷交易事務 success 之外,還應二次判斷充值錢包地址的 balance 是否準確的增加。其實這個二次判斷可以通過 Event 事件日誌來進行,很多中心化交易所、錢包等服務平臺會通過 Event 事件日誌來獲取轉賬額度,以此判斷轉賬的準確性。但這裡就需要特別注意合約作惡情況,因為 Event 是可以任意編寫的,不是強制默認不可篡改的選項:

emit Transfer(from, to, value); // value 等參數可以任意定義

作為平臺方,在對接新上線的代幣合約之前,應該做好嚴格的安全審計,這種安全審計必須強制代幣合約方執行最佳安全實踐。

作為代幣合約方,在編碼上,應該嚴格執行最佳安全實踐,並請第三方職業安全審計機構完成嚴謹完備的安全審計。

後記 Q&A

Q:為什麼我們採取這種披露方式?

A:本質是與攻擊者賽跑,但是這個生態太大,我們的力量不可能覆蓋全面,只能盡我們所能去覆蓋,比如我們第一時間通知了我們的客戶,然後是慢霧區夥伴的客戶,再然後是關注這個生態的安全同行的客戶,最終不得不披露出細節。

Q:為什麼說披露的不僅僅是漏洞,而是攻擊?

A:其實,以我們的風格,我們一般情況下是不會單純去提漏洞,漏洞這東西,對我們來說太普通,拿漏洞來高調運作不是個好方式。而攻擊不一樣,攻擊是已經發生的,我們必須與攻擊者賽跑。披露是一門藝術,沒什麼是完美的,我們只能盡力做到最好,讓這個生態有安全感。

Q:至少 3619 份存在“假充值”漏洞風險,這些代幣該怎麼辦?

A:很糾結,一般來說,這些代幣最好的方式是重發,然後新舊代幣做好“映射”。因為這類代幣如果不這樣做,會像個“定時炸彈”,你不可能期望所有中心化交易所、中心化錢包等平臺方都能做好安全對接,一旦沒做好這個“假充值”漏洞的判斷,那損失的可是這些平臺方。而如果平臺方損失嚴重,對整個市場來說必然也是一種損失。

Q:有哪些知名代幣存在“假充值”漏洞?

A:我們不會做點名披露的事。

Q:有哪些交易所、錢包遭受過“假充值”漏洞的攻擊?

A:恐怕沒人會公開提,我們也不會點名。

Q:這些代幣不重發是否可以?

A:也許可以,但不完美。不選擇重發的代幣要麼很快是發佈主網就做“映射”的,要麼得做好通知所有對接該代幣的平臺方的持續性工作。

Q:為什麼慢霧可捕獲到這類攻擊?

A:我們有健壯的威脅情報網絡,捕獲到異常時,我們默認直覺會認為這是一種攻擊。

Q:除了 USDT、以太坊代幣存在“假充值”漏洞風險,還有其他什麼鏈也存在?

A:暫時不做披露,但相信我們,“假充值”漏洞已經成為區塊鏈生態裡不可忽視的一種漏洞類型。這是慢霧安全團隊在漏洞與攻擊發現史上非常重要的一筆。


分享到:


相關文章: