SwapNet与Aperture Finance的1700万美元闭源智能合约漏洞:任意调用漏洞

SwapNet与Aperture Finance的1700万美元闭源智能合约漏洞:任意调用漏洞

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()函数,并提供了恶意输入。此调用包含两个主要步骤。

  1. 一个关键的内部变量(例如v51)被设置为USDC,绕过了预期的路由逻辑。
  1. 使用攻击者控制的calldata执行了低级调用,导致调用USDC.transferFrom()并窃取了所有已批准的USDC。

损失摘要、交易和受影响的合约

SwapNet事件在多个链上造成了约1341万美元的估计损失。下表总结了关键的利用交易和涉及的受害者合约地址。


Aperture Finance事件

背景

Aperture Finance [6]是一个DeFi协议,代表用户管理集中流动性头寸,例如Uniswap V3 LP。其闭源合约(例如0xD83d960deBEC397fB149b51F8F37DD3B5CFA8913)允许用户使用原生代币铸造和管理Uniswap V3头寸。

铸造UniswapV3头寸的预期工作流程

当通过0x67b34120()函数铸造Uniswap V3头寸时,合约遵循预期的三步工作流程:

  1. 包装原生代币
  2. 通过内部函数0x1d33()兑换原生代币
  3. 铸造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为例。

  1. 攻击者创建了一个攻击合约0x5c92884dFE0795db5ee095E68414d6aaBf398130
  2. 攻击合约调用了0x67b34120()函数,并提供了恶意输入和100 wei ETH(即msg.value == 100)。 a) 原生ETH通过WETH.deposit()函数被包装成WETH。
b) 调用了内部函数`0x1d33()`以执行低级调用。在此步骤中,在受害者合约的上下文中调用了`WBTC.transferFrom(victim, attacker, amount)`,允许攻击者窃取已批准的代币。值得注意的是,在`0x1d33()`函数结束时通过了余额检查。具体来说,函数`0x1d33()`还将余额变化与攻击者指定的兑换输出值(即`varg2.word2`)进行了比较。因此,交易成功执行,但攻击者一无所获。
3. 最后,调用了`NonfungiblePositionManager.mint()`函数,使用100 wei WETH为攻击者铸造了一个头寸。

有趣的发现

通过比较正常异常的铸造交易,我们发现它们将批准的代币发送给同一授权方(例如OKX DEX: TokenApprove),但指定了不同的路由器地址(即DexRouterWBTC)。这表明合约可能强制验证批准方,但未能验证实际的执行目标,留下了一个可通过任意调用利用的关键漏洞。

正常交易:https://app.blocksec.com/phalcon/explorer/tx/eth/0xc823b703c716fa9078e1d71714b734557bd540ddd1e41590dd73da7c5aba0200

异常交易:https://app.blocksec.com/phalcon/explorer/tx/eth/0x8f28a7f604f1b3890c2275eec54cd7deb40935183a856074c0a06e4b5f72f25a

损失摘要、交易和受影响的合约

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

[5] https://x.com/0xswapnet

[6] https://x.com/ApertureFinance

关于BlockSec

BlockSec是一家全栈区块链安全和加密合规提供商。我们构建产品和服务,帮助客户在协议和平台的整个生命周期内进行代码审计(包括智能合约、区块链和钱包)、实时拦截攻击、分析事件、追踪非法资金,并满足AML/CFT要求。

BlockSec已在知名会议上发表多篇区块链安全论文,报告了多起DeFi应用的零日攻击,阻止了多次黑客攻击挽回了超过2000万美元的损失,并保护了数十亿美元的加密货币。

Sign up for the latest updates