Back to Blog

Telcoin 安全事件事後回顧與深度分析

Code Auditing
January 10, 2024
7 min read

2023 年 12 月 25 日,我們的監控系統偵測到一系列針對 Telcoin 的惡意活動。我們協助 Telcoin 團隊確定了根本原因:錢包合約初始化不當,這是由於錢包的實際實現與其對應的代理合約(Proxy)之間存在不一致所致。本報告旨在提供詳盡的分析,以全面了解此次事件。

0x0: 基礎設計

在檢視該漏洞之前,首先了解相關智慧合約之間的關係非常重要。本質上,這些可以抽象為三種設計模式的組合:CloneFactory(克隆工廠)、Cloneable Proxy(可克隆代理)和 Beacon Proxy(信標代理)模式,如下圖所示。

0x1: 漏洞分析

該漏洞源於錢包合約的初始化不當,這是由於錢包的實際實現與其對應的代理合約之間存在不匹配。具體來說,在初始化過程中,代理合約透過寫入儲存槽(storage slot)0 的最低有效位元,將該槽位初始化為非零狀態。隨後,錢包程式碼也對儲存槽 0 進行了寫入,從而覆蓋了代理合約在最低有效位元中的初始值。此問題並非任何一個智慧合約固有的漏洞,而是兩者互動的結果。

以下我們根據下文提供的 交易追蹤 (transaction trace) 來進行說明:

具體而言,在 CloneableProxy:Proxy.initialize() 函數中,存在一個 delegatecall,它呼叫了 Wallet.initialize() 函數。此呼叫是透過對 CloneableProxy:Implementation.initialize() 的 delegatecall 進行的。因此,Wallet.initialize() 函數對儲存空間所做的任何修改,都會反映在 CloneableProxy:Proxy 合約的儲存空間中。

為了完整理解其影響,必須檢查 CloneableProxy:Proxy 合約的儲存佈局。該合約的定義如下所示:

鑑於 Proxy 合約和 ERC1967Upgrade 合約都沒有儲存變數,槽位 0 反而被兩個儲存變數——_initialized 和 _initializing——所使用,這兩者皆繼承自 Initializable 合約。

現在,讓我們審視 Wallet 合約。在 Wallet.initialize() 函數中,很明顯槽位 0xaa 作為初始化標記。這一點透過第 3-4 行和第 11-12 行的程式碼片段得到了強調:

請注意,槽位 0 被分配給了 _state,它儲存了函數選擇器之後 calldata 中的後 32 個位元組,如第 21 行所示。有關更多詳細資訊,請參閱 Wallet 合約開頭的註釋:

關於槽位 0 的使用存在明顯的錯位:CloneableProxy:Proxy 合約將其解釋為初始化標記,而 Wallet:initialize() 函數則將其視為錢包的狀態。

因此,初始化過程完成後,槽位 0 的最低兩個位元組將被重置為零。這有效地將 _initialized 和 _initializing 都設置為零。結果,CloneableProxy:Proxy 合約變得容易受到透過 initialize() 函數進行「重新初始化」的攻擊,因為 initializer 修飾符的保護機制被繞過了。

顯然,被利用的可能性取決於錢包的狀態。一旦更新為非零值,錢包的狀態就會防止該合約被進一步重新初始化。初始化後,由於錢包狀態隨每筆交易更新,槽位 0 的最低兩個位元組變為非零的可能性增加,這有效地使錢包免於被重新初始化。這解釋了為什麼大多數受影響的錢包幾乎沒有或完全沒有交易歷史,從而暴露在攻擊之下。

0x2: 攻擊分析

攻擊者首先重新初始化了易受攻擊的 CloneableProxy:Proxy 合約,以更改 Beacon 合約的地址。隨後,攻擊者轉移了 CloneableProxy:Proxy 合約中包含的資產,詳細情況如下:

值得注意的是,多個易受攻擊的合約在單筆交易中被侵入,攻擊者重複執行了此策略。

0x3: 攻擊總結

我們觀察到總共 4,958 次攻擊,由六個不同的帳戶執行,情況如下:

0x4: 修復與建議

我們的調查顯示,問題的核心在於對儲存槽 0 的不一致使用,導致了重新初始化易受攻擊合約的可能性。顯然,修復方法涉及對儲存分配進行謹慎管理。

從這次事件中,我們獲得了幾個重要的啟示:

  • 在使用內聯組合語言(inline assembly)操作儲存槽時要格外小心,錯誤可能會導致嚴重的漏洞。

  • 對合約狀態保持警惕監控。快速反應的能力取決於是否能及時收到警報。

  • 在合約中實現暫停機制,以便在檢測到受損時能夠立即中止活動。

此外,此事件涉及多筆針對不同錢包合約的攻擊交易,這凸顯了對威脅監控和攻擊阻斷方案(例如 Phalcon)的迫切需求。這類工具對於減輕未來風險和防止預期損失至關重要。

0x5: 事件時間軸

太平洋標準時間 12 月 25 日上午 09:23:我們的系統偵測到 Polygon 網路上第一筆惡意交易

太平洋標準時間 12 月 25 日上午 10:28:Telcoin 支援團隊在內部溝通管道報告了該事件。

太平洋標準時間 12 月 25 日上午 10:32 — 10:37:Telcoin 團隊成員通知了 Telcoin Discord 社群,並與所有相關關鍵團隊成員召開了緊急通話。

太平洋標準時間 12 月 25 日上午 10:45:部署了 Web 應用程式防火牆規則,以限制對 Telcoin 基礎設施的所有存取。

太平洋標準時間 12 月 25 日上午 11:02:Telcoin 團隊與 Seal 911 啟動對談。

太平洋標準時間 12 月 25 日上午 11:11:Telcoin 團隊與其他安全成員成立了戰情室,以找出問題的根本原因並討論阻斷攻擊的潛在解決方案。

太平洋標準時間 12 月 25 日下午 01:14:Telcoin 團隊透過 X(Twitter)公開向用戶發出警報

太平洋標準時間 12 月 25 日下午 03:39:Telcoin 聯繫了 Chainalysis 和 Slowmist,協助調查被盜資金。他們透過調查對被盜錢包和地址進行了標記,並與交易所共享了這些情報。

太平洋標準時間 12 月 25 日下午 10:35:應 Telcoin 團隊邀請,我們加入了戰情室並分享了我們確定的根本原因分析結果。

太平洋標準時間 12 月 25 日晚上 11:00 至 12 月 26 日凌晨 02:06:確定根本原因後,Telcoin 團隊透過在一個安全且受控的環境中複製利用過程,成功制定了緩解策略。此過程涉及重新初始化錢包代理,以使其與新的信標(Beacon)對齊。鑑於此漏洞利用是一次性的機會,Telcoin 可以預先更新錢包配置,從而停用攻擊者進一步利用這些漏洞的能力。

太平洋標準時間 12 月 26 日凌晨 02:07 至 02:14:Telcoin 團隊在所有未受損的錢包上執行了緩解程序,以確保全面覆蓋。為了快速且有效地部署,該過程在嚴格定義的時間窗口內分批次執行。隨後,Telcoin 開始準備並內部測試補救方案,以全面恢復所有受影響的錢包並為所有錢包進行永久修復。

太平洋標準時間 12 月 26 日下午 04:52:Telcoin 與我們團隊就以下主題展開討論:

  • 事件概述

  • 事件時間軸:事件發展過程的按時間順序說明。

  • 根本原因分析:對事件潛在原因的深入分析。

  • 改進建議

  • 程式碼審計

太平洋標準時間 12 月 29 日下午 12:27:經過幾輪討論,我們開始與 Telcoin 團隊合作撰寫事後報告並審計補救措施。

2024 年 1 月 3 日:提供了事後報告草稿。

2024 年 1 月 4 日:提交了我們的審計結果,包括已識別的問題與建議。

2024 年 1 月 4 日至 1 月 10 日:我們與 Telcoin 團隊合作,完成了事後報告並審查了修復措施。

此外,值得注意的是,從 12 月 25 日至今,Telcoin 一直在與區塊鏈調查公司和執法部門就此事件進行密切合作。

關於 BlockSec

BlockSec 是一家開拓性的區塊鏈安全公司,由一群全球傑出的安全專家於 2021 年成立。公司致力於提升新興 Web3 世界的安全性和易用性,以促進其大規模採用。為此,BlockSec 提供智慧合約與 EVM 鏈安全審計服務、用於主動式安全開發與威脅攔截的 Phalcon 平台、用於資金追蹤與調查的 MetaSleuth 平台,以及協助 Web3 建設者在加密世界中高效探索的 MetaDock 擴展程式。

迄今為止,公司已服務超過 300 家知名客戶,如 MetaMask、Uniswap Foundation、Compound、Forta 和 PancakeSwap,並獲得了包括 Matrix Partners、Vitalbridge Capital 和 Fenbushi Capital 在內的頂尖投資者兩輪數千萬美元的融資。

網站:https://blocksec.com/

X(Twitter):@BlockSec @Phalcon

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit