2023年12月5日,著名的Web3开发平台Thirdweb披露了影响其预建合约的重大智能合约安全漏洞。这一关键缺陷影响了使用这些特定易受攻击合约部署的所有ERC-20、ERC-721和ERC-1155代币。在披露后的几天里,使用这些易受攻击合约部署的代币在一系列攻击中被逐步利用,凸显了根本不兼容性的严重性。
理解ThirdWeb智能合约漏洞
ThirdWeb事件的根本原因在于智能合约开发两个基本组件之间的意外交互:ERC-2771和OpenZeppelin的多重调用实现。要完全理解该漏洞,必须单独理解每个组件,然后了解它们的交互如何创建了一个可被利用的途径。
ERC-2771:Meta交易和受信任的Forwarder
EIP-2771定义了一个合约级别的协议,允许“接收方”合约通过受信任的“Forwarder”合约接受“meta交易”。该标准对于改善用户体验至关重要,它允许第三方(forwarder)代表用户支付Gas费用,从而消除了用户持有原生区块链代币的需求。
在实践中,OpenZeppelin的ERC2771Context是一个被广泛采用的实现。其核心功能包括将来自受信任forwarder的calldata的最后20字节视为有效的_msgSender()。对于使用此库的开发者来说,常规做法是用_msgSender()替换所有直接使用的msg.sender,以确保与meta交易的兼容性。同样,_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;
}
(注意:这里讨论的bug在OpenZeppelin Multicall的后续版本中已修复。)
不兼容性:ERC-2771和Multicall冲突
ThirdWeb事件智能合约漏洞的核心在于ERC-2771和Multicall处理calldata的方式存在关键不一致。ERC-2771期望受信任的forwarder将消息数据和发送者信息打包在一起。接收方合约随后使用_msgData()和_msgSender()来正确解包这些信息。
然而,Multicall函数在其易受攻击的实现中,并未设计成与ERC-2771打包meta交易数据的方式兼容。具体来说,当Multicall处理一批调用时,它应该正确地从初始meta交易中提取_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执行。 这是利用的核心。攻击者调用了一个受信任的forwarder,并精心构造了用于利用ERC-2771/Multicall不兼容性的calldata。当
Multicall函数解析此calldata时,它导致调用TIME代币合约的burn函数。关键是,由于漏洞的存在,_msgSender()被错误地解释为Uniswap池地址。这使得攻击者能够有效地燃烧Uniswap池持有的相当一部分TIME代币,而无需实际授权。BlockSec Phalcon平台提供了详细的交易跟踪来可视化这一流程。
显示恶意multicall的交易跟踪 上图展示了攻击者的
Forwarder.execute调用是如何被处理的。multicall函数接收一个字节数组,然后调用burn函数并传入被操纵的_msgSender()。
Multicall解析和burn函数调用的详细视图 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的
ERC2771Context和MulticallUpgradeable这样被广泛使用、看似强大的组件,在集成处理不当时也可能产生关键的安全漏洞。 - 深入的技术审计至关重要: 这种类型的智能合约漏洞不易被表面检查捕获。它需要深厚的技术专业知识来分析不同模块如何处理和解释数据,尤其是calldata,并识别潜在的不一致性。彻底的智能合约审计,侧重于跨模块交互和边缘情况,是至关重要的。
- 持续监控和事件响应: 即使有强大的审计,新的攻击向量也可能出现。像BlockSec的Phalcon提供的持续区块链安全监控,对于实时检测可疑活动并实现快速事件响应以最小化损害至关重要。
- 超越单个模块的安全: 开发者必须超越对单个组件安全性的关注,并考虑其整个智能合约系统的整体安全态势。数据如何在不同模块之间流动、上下文如何保持或改变、外部调用如何处理,都是关键的考虑因素。
ThirdWeb事件凸显了采取积极主动和全面的区块链安全方法的重要性。仅仅依赖单个库的声誉是不足够的;它们之间的交互必须受到严格审查。
使用Phalcon调查链上事件
BlockSec的Phalcon是领先的Web3安全平台,提供实时监控、事件响应和深入的交易分析。以无与伦比的清晰度理解ThirdWeb事件等复杂漏洞。
阅读本系列的更多文章:
- 导语:2023年十大“惊人”安全事件
- #1:通过利用Flashbots Relay中的漏洞来收割MEV机器人
- #2:Euler Finance事件:2023年最大规模的黑客攻击
- #3:KyberSwap事件:通过极其微妙的计算,巧妙利用舍入错误
- #4:Curve事件:编译器错误导致无害源代码生成有缺陷的字节码
- #5:Platypus Finance:幸运地躲过了三次攻击
- #6:Hundred Finance事件:催化了易受攻击的分叉协议中与精度相关的攻击浪潮
- #7:ParaSpace事件:与时间赛跑,阻止行业迄今为止最关键的攻击
- #8:SushiSwap事件:笨拙的救援尝试导致一系列模仿攻击
- #9:MEV机器人0xd61492:在一次巧妙的利用中从捕食者沦为猎物



