该文章详细分析了LI.FI协议在2024年发生的910万美元的攻击事件。文章从LI.FI的多链流动性聚合原理开始,讲解了智能合约结构及攻击过程,指出了导致攻击的根本原因,即GasZipFacet合约未对交易呼叫进行有效验证,并提供了防止类似攻击的建议。
LI.FI 是一个多链流动性聚合协议,支持任何对任何的交换,通过聚合跨越20多个网络的桥和DEX聚合器。该协议不仅限于交换;它还提供了一个JavaScript/TypeScript SDK,便于前端和后端应用程序集成,使开发人员能够围绕其桥接和交换功能构建定制用户体验/用户界面。该协议还提供了一个REST API,以便进行更深入和定制的集成。此外, LI.FI 提供了一个小部件,以快速用户引导,而无需进行广泛的集成。
在本节中,你可以找到对多链流动性聚合的简要介绍及其在LI.FI中的工作原理。如果你对该主题已经熟悉,可以跳过此部分。多链流动性聚合是指从多个区块链网络组合和利用流动性,以促进无缝和高效的交易。这涉及到整合流动性池、去中心化交易所(DEX)以及其他金融工具,使用户能够在不同区块链间交易资产和访问流动性,而不被限制在单一网络内。多链流动性聚合的主要目标是提高流动性、改善交易效率、降低成本,并为用户提供更广泛的金融产品和服务。
理解LI.FI智能合约需要熟悉EIP-2535(多面代理标准),因为它们是使用这一标准构建的。合约逻辑驻留在单个合约中,然后利用DELEGATECALL调用包含核心业务逻辑的面合约。
LI.FI智能合约结构
一个基本的例子是,用户使用Hop协议将资产从一个链桥接到另一个链。用户与LiFiDiamond合约交互,该合约将具体传递到Hop的调用给HopFacet。HopFacet随后将所需的调用和参数转发到Hop协议的合约。
桥接资产示例
在让人不安的似曾相识中, LI.FI协议在2024年7月16日遭受到一次重大攻击,情况与2022年的类似攻击几乎完全相同。这次攻击导致了近900万美元从用户账户中被盗。此攻击涉及到以太坊主网上的10笔交易和Arbitrum上的1笔交易。
攻击的根本原因是缺乏对交易调用的验证,该数据是刚部署的GasZipFacet合约在攻击前仅5天内设计的,旨在为用户提供Gas补充桥接。
这允许任意交易被处理。攻击者利用这个漏洞,通过构造一个恶意交易来执行transferFrom
操作,而不是代币交换,导致用户余额被抽干。
这种类型的攻击在Web3领域是一种众所周知的漏洞,并在各种情况下被利用过,包括在2022年对LI.FI的第一次攻击。有关2022年LI.FI漏洞的更多信息,请查看这里。
让我们来看一下13笔交易中第三大和最大的交易,攻击者盗取了约460万美元:
攻击者构造了一个恶意智能合约,用于调用LiFiDiamond合约的回退函数。这启动了一个更广泛的交易,导致LiFiDiamond合约之后调用GasZipFacet合约。
LiFiDiamond的fallback()代码片段
关键的调用涉及到调用depositToGasZipERC20函数,该函数接受三个参数:_swapData
、_destinationChains
和_recipient
。
depositToGasZipERC20函数的目的是将ERC20代币交换为原生代币并将它们存入一个Gas补充路由器,利用LibSwap.swap。
GasZipFacet depositToGasZipERC20()代码片段
攻击者为depositToGasZipERC20函数调用提供了以下输入:
攻击者的depositToGasZipERC20()输入
callData
参数,其中包含外部合约的编码指令,对于理解漏洞至关重要。它对函数选择器和函数调用所需的参数进行了编码。在这种情况下,callData
用于编码transferFrom
的函数调用,而不是代币交换。
让我们分解所提供的callData
:
攻击者的 calldata 分解
函数选择器:0x23b872dd
:
0x23b872dd
)代表ERC-20代币标准中transferFrom
函数的选择器。transferFrom
函数具有如下签名:transferFrom(address from, address to, uint256 value)
。发送地址:0xa4fdabde3705fccf068bd1f164fcb30635b42b04
接收地址:0x8b3cb6bf982798fba233bca56749e22eec42dcf3
数量(金额):0x00000000000000000000000000000000000000000000000000000012a7dc4e736
理解这个漏洞的关键是LibSwap.swap函数,该函数由depositToGasZipERC20调用,并提供了_swapData
。这是swap
函数的相关代码以及它是如何被操纵的:
LibSwap swap()代码片段
在上述代码中,swap函数执行以下步骤:
callTo
地址是否为合约,以及fromAmount
是否大于零。sendingAssetId
余额以执行交换。approveTo
地址批准fromAmount
的sendingAssetId
。callData
对callTo
合约进行低级调用。AssetSwapped
事件。攻击者利用了swap
函数中的低级调用。通过构造包含恶意callData
的_swapData
,该callData
编码了transferFrom
函数。当swap
函数执行低级调用时,它触发了ERC20代币的transferFrom
函数,导致代币从受害者地址转移至攻击者地址。
Tenderly的transferFrom调用
这个过程在同一交易中总共重复了10次,最终在一笔交易中盗取了约460万美元。能够在一笔更广泛的交易中执行多个transferFrom
调用,允许攻击者在非常短的时间内最大化他们的漏洞。
Tenderly的回退调用
与其他12笔交易相加,总共导致约900万美元被盗。
攻击者随后开始在不同的钱包之间分配被盗资金。然而,强大的社区工作将地址标记并调查攻击,使得攻击者难以成功。
要防止类似的攻击,确保对所有输入参数进行强有力的验证非常关键,尤其是涉及财务交易的参数。GasZipFacet合约未能正确验证callData
,这使得攻击者能够构造恶意交易。
此外,GasZipFacet合约是在没有审计的情况下部署的。在将合约部署到主网上之前,由第三方专家进行全面的安全审计可以识别潜在的漏洞。同时,包括模糊测试和模拟潜在攻击向量的严格测试有助于发现可能在标准测试程序中忽略的漏洞。
这次攻击的直接后果是大约900万美元的用户资金损失,影响了用户信任以及协议的声誉。此外,这种攻击可能导致更广泛的市场不稳定,特别是如果用户对DeFi协议的安全性失去信心。
实施严格的检查以验证callData
符合预期结构并包含允许的操作,可以防止此类漏洞。
在官方确认后,LI.FI 宣布受影响的钱包仅为无限批准,仅涉及极少数用户。他们还表示,他们正在与相应的执法机构和相关第三方(包括行业的安全团队)合作,以追踪资金。
在上述公告几小时后,他们宣布协议已完全恢复正常,并继续与执法机构和行业参与者合作,追踪和恢复资金。
- 原文链接: threesigma.xyz/blog/lifi...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!