Back to Blog

#10:ThirdWeb 事件:受信任模塊間的不兼容性導致漏洞暴露

Code AuditingPhalcon Security
February 22, 2024
8 min read
Key Insights

2023 年 12 月 5 日,著名的 Web3 開發平台 Thirdweb 披露了影響其預構建合約的重大智慧合約安全漏洞。這一嚴重缺陷影響了所有使用這些特定易受攻擊合約部署的 ERC-20、ERC-721 和 ERC-1155 代幣。在披露後的幾天裡,使用這些易受攻擊合約部署的代幣在一系列攻擊中逐漸被利用,凸顯了底層不兼容性的嚴重性。

理解 ThirdWeb 智慧合約漏洞

ThirdWeb 事件的根本原因在於智慧合約開發中兩個基本組件之間的意外交互:ERC-2771 和 OpenZeppelin 的 Multicall 實作。為了完全理解該漏洞,必須分別理解每個組件,然後了解它們的交互是如何創建可利用路徑的。

ERC-2771:元交易 (Meta-Transactions) 與受信任轉發器 (Trusted Forwarders)

EIP-2771 定義了一種合約層級協議,允許 Recipient (接收者) 合約透過受信任的 Forwarder (轉發器) 合約接受 元交易。該標準對於改善用戶體驗至關重要,它允許第三方(轉發器)代用戶支付 Gas 費用,從而無需用戶持有原生區塊鏈代幣。

在實踐中,OpenZeppelin 的 ERC2771Context 是一種被廣泛採用的實作。其核心功能涉及將來自受信任轉發器的 calldata 最後 20 個位元組視為有效的 _msgSender()。對於使用此庫的開發者來說,常見的做法是用 _msgSender() 取代所有對 msg.sender 的直接使用,以確保與元交易的兼容性。同樣,_msgData() 用於檢索原始交易數據,不包括附加的發送者資訊。

function _msgSender() internal view virtual override returns (address) {
    uint256 calldataLength = msg.data.length;
    uint256 contextSuffixLength = _contextSuffixLength();
    if (isTrustedForwarder(msg.sender) && calldataLength >= contextSuffixLength) {
        return address(bytes20(msg.data[calldataLength - contextSuffixLength:]));
    } else {
        return super._msgSender();
    }
}

function _msgData() internal view virtual override returns (bytes calldata) {
    uint256 calldataLength = msg.data.length;
    uint256 contextSuffixLength = _contextSuffixLength();
    if (isTrustedForwarder(msg.sender) && calldataLength >= contextSuffixLength) {
        return msg.data[:calldataLength - contextSuffixLength];
    } else {
        return super._msgData();
    }
}

Multicall:批次處理交易以提高效率

Multicall 功能允許用戶將多個函數呼叫捆綁到單個交易中,從而顯著降低 Gas 成本並提高交易效率。OpenZeppelin 的 MulticallUpgradeable 是用於此目的的流行實作。它接收一組 calldata 位元組陣列,並為每個條目執行 delegatecall,從而在呼叫合約的上下文中執行它們。

function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results) {
    results = new bytes[](data.length);
    for (uint256 i = 0; i < data.length; i++) {
        results[i] = _functionDelegateCall(address(this), data[i]);
    }
    return results;
}

(注意:此處討論的錯誤已在後來版本的 OpenZeppelin Multicall 中修復。)

不兼容性:ERC-2771 與 Multicall 衝突

ThirdWeb 事件中智慧合約漏洞的核心在於 ERC-2771 和 Multicall 處理 calldata 方式的一致性嚴重缺失。ERC-2771 要求受信任的轉發器將訊息數據和發送者資訊封裝在一起。隨後,接收者合約使用 _msgData()_msgSender() 來正確解包該資訊。

然而,Multicall 函數在其易受攻擊的實作中,並未被設計為與 ERC-2771 封裝元交易數據的方式兼容。具體來說,當 Multicall 處理一批呼叫時,它應該正確地從初始元交易中提取 _msgSender(),然後在執行這些呼叫之前,將此發送者資訊附加到每個單獨呼叫的 calldata 中。這項關鍵步驟缺失了。

由於每個由 Multicall 處理的子呼叫內的 calldata 沒有正確附加發送者資訊,目標合約中的 ERC-2771 上下文就會嘗試從子呼叫 _msgData()最後 20 個位元組中解包發送者資訊。關鍵在於,攻擊者可以控制這最後 20 個位元組。這使得惡意行為者能夠精心製作特定的 calldata,當其被 Multicall 處理並隨後被啟用了 ERC-2771 的合約解釋時,就會以被操縱的 _msgSender() 值(例如由攻擊者控制的地址,甚至是協議自己的池地址)執行任意邏輯。這有效地繞過了預期的安全檢查,並違反了兩項規範設定的期望,導致了未經授權的操作。

ThirdWeb 事件:攻擊分析與利用

讓我們透過 BlockSec 的 Phalcon 平台分析的 攻擊交易,來審視 ThirdWeb 事件中智慧合約漏洞利用的真實案例。

攻擊者的策略涉及操控 _msgSender() 來冒充 Uniswap 池,從而耗盡其代幣餘額。

  • 第 1 步:初始代幣獲取。 攻擊者開始在去中心化交易所將 5 WETH 兌換為 3,455,399,346 枚 TIME 代幣。這為隨後的操縱提供了必要的代幣。

  • 第 2 步:惡意 Multicall 執行。 這是漏洞利用的核心。攻擊者呼叫了受信任的轉發器,並附帶了精心製作的 calldata,旨在利用 ERC-2771/Multicall 的不兼容性。當此 calldata 被 Multicall 函數解析時,導致 TIME 代幣合約的 burn 函數被呼叫。關鍵在於,由於該漏洞,_msgSender() 被錯誤地解釋為 Uniswap 池地址。這使得攻擊者能夠在未經實際授權的情況下,有效地銷毀 Uniswap 池持有的相當大一部分 TIME 代幣。BlockSec Phalcon 平台提供了詳細的交易追蹤來觀察這一流程。

    顯示惡意多重呼叫的交易追蹤
    顯示惡意多重呼叫的交易追蹤

    上圖說明了攻擊者的 Forwarder.execute 呼叫是如何被處理的。multicall 函數接收一個位元組陣列,隨後導致 burn 函數以被操控的 _msgSender() 被呼叫。

    多重呼叫解析與銷毀函數呼叫的詳細視圖
    多重呼叫解析與銷毀函數呼叫的詳細視圖

    來自 Phalcon 的此詳細視圖顯示了長度為 1 的 bytes[] 被用作呼叫合約的數據,導致在偽造的 _msgSender() 下執行了 burn 函數。

  • 第 3 步:價格操縱。 透過銷毀 Uniswap 池中大量的 TIME 代幣,攻擊者急劇減少了池中 TIME 的流動性。這種人為的稀缺性導致 TIME 相對於 WETH 的價格在池內飆升。

  • 第 4 步:獲利套利。 隨著 TIME 價格被人為抬高,攻擊者隨後將剩餘的 3,455,399,346 枚 TIME 代幣換回 94 WETH,從操縱的價格中實現了實質性獲利。

這一系列事件證明了一種精密的攻擊方式,它利用了源於模組不兼容的細微智慧合約漏洞。

使用 BlockSec 保護您的智慧合約

不要讓隱藏的不兼容性使您的項目面臨風險。我們的專家審計員會進行全面的智慧合約審計,以在漏洞被利用之前識別並降低其風險。

Web3 最佳安全審計員

在發布前驗證設計、程式碼和業務邏輯

ThirdWeb 事件的關鍵啟示與經驗教訓

ThirdWeb 事件提醒我們 Web3 安全固有的複雜性,特別是涉及第三方庫交互的部分。

  • 互操作性風險: 在快速發展的 DeFi 領域,項目嚴重依賴第三方庫和模組的堆疊。雖然這些組件加快了開發速度,但它們的交互可能會引入意外且隱蔽的漏洞。ThirdWeb 事件清楚地表明,即使是廣泛使用、看似魯棒的組件(如 OpenZeppelin 的 ERC2771ContextMulticallUpgradeable),如果其整合未得到謹慎處理,也會造成嚴重的安全漏洞。
  • 深入的技術審計至關重要: 這類智慧合約漏洞並不容易被表面檢查發現。它需要深厚的技術專長來分析不同模組如何處理和解釋數據(尤其是 calldata),並識別潛在的不一致性。徹底的智慧合約審計,重點關注跨模組交互和邊緣情況,是至關重要的。
  • 持續監控與事件響應: 即使有嚴格的審計,新的攻擊向量也可能出現。持續的區塊鏈安全監控(例如 BlockSec 的 Phalcon 所提供的監控)對於即時檢測可疑活動並實現快速事件響應以最大限度地減少損失至關重要。
  • 超越單個模組的安全: 開發者必須超越單個組件的安全性,考慮整個智慧合約系統的整體安全態勢。數據如何在不同模組之間流動、上下文如何被保留或更改,以及外部呼叫如何被處理,都是關鍵考量因素。

ThirdWeb 事件強調了採取主動和全面方法處理區塊鏈安全的重要性。僅僅依賴單個庫的聲譽是不夠的;必須對它們之間的相互作用進行嚴格審查。

Best Security Auditor for Web3

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

BlockSec Audit

Get Real-Time Protection with Phalcon Security

Audits alone are not enough. Phalcon Security detects attacks in real time and blocks threats mid-flight.

phalcon security