2026年1月25日,我们检测到了一系列针对SwapNet和Aperture Finance在Ethereum、Arbitrum、Base和BSC上部署的受害者合约的可疑交易,总损失超过1700万美元。总的来说,这两起事件的根本原因很简单,并且已经在我们的初步警报中进行了概述[1, 2]:受害者合约由于输入验证不足而暴露了任意调用能力,允许攻击者滥用现有的代币批准并通过调用transferFrom来提取资产。
然而,两组受害者合约都是闭源的,一旦反编译,会扩展到数千行代码,具有深度嵌套和复杂的逻辑分支,大大增加了分析难度。此外,受影响项目发布的后续事后报告[3, 4]主要关注修复和恢复,对底层技术细节的讨论有限。因此,一些重要的问题仍未得到解答,包括易受攻击的调用路径是如何构建的,以及为什么现有的检查未能阻止利用。
在本报告中,我们将基于反编译的字节码和链上执行跟踪提供更详细的技术分析。虽然缺乏源代码限制了可见性,但字节码级别的分析足以重建易受攻击的逻辑,并揭示了一些关于合约设计的有趣观察,这些观察在高级警报中并不显而易见。
我们将首先深入分析SwapNet事件,然后详细分析Aperture Finance事件。
SwapNet事件
背景
SwapNet [5]是一个DEX聚合器,旨在通过聚合来自多个链上来源(包括AMM和私有做市商)的流动性来查找最优的交易路径。该协议还允许用户在执行交易时指定自定义路由器或池,提供额外的灵活性。
根本原因分析
此事件源于用户提供的输入的验证不足,这使得攻击者能够触发带有任意参数的transferFrom()调用。因此,先前已批准给受害者合约(例如0x616000e384Ef1C2B52f5f3A88D57a3B64F23757e)的资产可以被转移给攻击者。
根据反编译的字节码,0x87395540()函数似乎缺乏对关键输入的适当验证。通过将预期的路由器或池地址替换为代币地址(例如USDC),合约会错误地将该代币视为有效的执行目标。这会导致以攻击者控制的calldata执行低级调用。
因此,受害者合约会执行类似approvedAsset.transferFrom(victim, attacker, amount)的调用,允许攻击者窃取所有已批准的资产。
攻击流程
观察到多起针对SwapNet的攻击。这里我们以Base交易0xc15df1d131e98d24aa0f107a67e33e66cf2ea27903338cc437a3665b6404dd57为例。
攻击者简单地调用了受害者合约的0x87395540()函数,并提供了恶意输入。此调用包含两个主要步骤。
- 一个关键的内部变量(例如
v51)被设置为USDC,绕过了预期的路由逻辑。
- 使用攻击者控制的calldata执行了低级调用,导致调用
USDC.transferFrom()并窃取了所有已批准的USDC。
损失摘要、交易和受影响的合约
SwapNet事件在多个链上造成了约1341万美元的估计损失。下表总结了关键的利用交易和涉及的受害者合约地址。
| 链 | 合约地址 |
|---|---|
| Base | 0x616000e384Ef1C2B52f5f3A88D57a3B64F23757e |
| BSC | 0xc7C6d9154CB1f2c3eCA469D410bD757486798C96 |
| Arbitrum | 0xc3b93F41fC85405B1bD9d135eE822Bdd90e54ef4 |
Aperture Finance事件
背景
Aperture Finance [6]是一个DeFi协议,代表用户管理集中流动性头寸,例如Uniswap V3 LP。其闭源合约(例如0xD83d960deBEC397fB149b51F8F37DD3B5CFA8913)允许用户使用原生代币铸造和管理Uniswap V3头寸。
铸造UniswapV3头寸的预期工作流程
当通过0x67b34120()函数铸造Uniswap V3头寸时,合约遵循预期的三步工作流程:
- 包装原生代币
- 通过内部函数
0x1d33()兑换原生代币 - 铸造UniswapV3头寸
问题出现在第2步:0x1d33()通过低级调用执行自定义兑换,其中关键参数(例如调用目标和calldata)似乎由用户控制且验证不足,导致了非预期的外部调用。更多细节将在以下部分提供。
根本原因分析
与SwapNet案例类似,Aperture Finance事件是由低级调用上的输入验证不足引起的。当调用0x67b34120()时,内部函数0x1d33()使用用户提供的calldata执行低级调用,而没有强制执行对调用目标或函数选择器的严格限制。
如下图所示,用于触发低级调用的calldata完全基于攻击者的输入。
这使得攻击者能够构造恶意的calldata,导致在受害者合约的上下文中执行approvedToken.transferFrom(victim, attacker, amount)。因此,不仅ERC20代币,甚至已批准的Uniswap V3头寸NFT也可以被窃取。
攻击流程
观察到多起针对Aperture Finance的攻击。在本节中,我们以Ethereum交易0x8f28a7f604f1b3890c2275eec54cd7deb40935183a856074c0a06e4b5f72f25a为例。
- 攻击者创建了一个攻击合约
0x5c92884dFE0795db5ee095E68414d6aaBf398130。 - 攻击合约调用了
0x67b34120()函数,并提供了恶意输入和100 wei ETH(即msg.value==100)。 a) 原生ETH通过WETH.deposit()函数被包装成WETH。
有趣的发现
通过比较正常和异常的铸造交易,我们发现它们将批准的代币发送给同一授权方(例如OKX DEX: TokenApprove),但指定了不同的路由器地址(即DexRouter和WBTC)。这表明合约可能强制验证批准方,但未能验证实际的执行目标,留下了一个可通过任意调用利用的关键漏洞。
损失摘要、交易和受影响的合约
Aperture Finance事件在多个链上造成了约367万美元的总估计损失。下表总结了关键的利用交易和相关的受害者合约地址。
结论
尽管SwapNet和Aperture Finance事件影响了不同的协议和链,但两者根本性的问题并不复杂:用户控制的低级调用与合约中持有代币批准的输入验证不足相结合。这些事件提醒我们,在合约设计中的灵活性必须与严格的调用约束仔细权衡,尤其是在外部审查受限的闭源系统中。
参考
[1] https://x.com/Phalcon_xyz/status/2015614087443697738
[2] https://x.com/Phalcon_xyz/status/2015624519898234997
[3] https://meta.matcha.xyz/SwapNet-Incident-Post-Mortem
[4] https://x.com/ApertureFinance/status/2015938720453820752
[6] https://x.com/ApertureFinance
关于BlockSec
BlockSec是一家全栈区块链安全和加密合规提供商。我们构建产品和服务,帮助客户在协议和平台的整个生命周期内进行代码审计(包括智能合约、区块链和钱包)、实时拦截攻击、分析事件、追踪非法资金,并满足AML/CFT要求。
BlockSec已在知名会议上发表多篇区块链安全论文,报告了多起DeFi应用的零日攻击,阻止了多次黑客攻击挽回了超过2000万美元的损失,并保护了数十亿美元的加密货币。
-
官方Twitter账号:https://twitter.com/BlockSecTeam
-
🔗 BlockSec审计服务 : 提交请求



