2022年5月15日,欧洲中部夏令时间(UTC)晚上8:20左右,我们的监控系统发现FEGtoken项目中的FEGexPRO合约被黑客攻击。
攻击者在ETH和BSC主网上发起了一系列攻击,涉及的总价值累计约130万美元(根据项目在链上发送的消息)。
检查您FEGexPRO合约(0x818E2013dD7D9bf4547AaabF6B617c1262578bc7)中的参数`path`!我们的监控系统刚刚报告了一起针对FEGexPRO合约的攻击,该合约损失了fBNB和FEG。pic.twitter.com/A4obANAMhW
— BlockSec (@BlockSecTeam) 2022年5月16日
有关此事件的更多信息,请访问该项目的官方Twitter。 在本报告中,我们将深入探讨细节,揭示此次事件的根本原因。
0x1 漏洞分析:初步审视
易受攻击的FEGexPRO合约部署在ETH和BSC上,
合约中的易受攻击函数是swapToSwap,如下所示:

正如社交媒体上指出的那样,swapToSwap函数的第一个参数path可以由函数调用者指定。因此,攻击者可以利用它进行任意批准(参见swapToSwap函数第682行)。
到目前为止,这没有什么新意,因为这又是又一个未经验证参数的案例。然而,攻击轨迹表明,仅仅归因于任意批准无法清楚地说明这次攻击。事实上,存在一个微妙的技巧,这也是事情变得有趣的地方。
0x2 攻击分析
0x2.1 初步攻击分析
我们以BSC上的一次攻击交易为例来说明攻击过程,目标资产fBNB的相应攻击轨迹简要总结如下:

- 步骤1:准备资金和伪造的
path。攻击者从DVM借入约915 BNB的闪电贷,并将部分BNB兑换成116 fBNB。然后,攻击者创建了一堆将用作伪造path的合约。 - 步骤2:存入初始资金。通过将115 fBNB存入FEGexPRO合约,攻击者增加了其在受害者合约中的
balances2。 - 步骤3:执行任意批准。攻击者随后调用
swapToSwap函数,并将一个伪造的path作为第一个参数传递,这导致FEGexPRO合约批准path花费114 fBNB。 - 步骤4:通过调用
depositInternal函数和swapToSwap函数进行另一次批准。FEGexPRO合约又批准了另一个path花费114 fBNB。
攻击者反复执行步骤4以进行更多批准。最后,攻击者利用已批准的伪造path耗尽FEGexPRO中的所有fBNB,并将部分资金兑换成BNB以偿还闪电贷。
显然,我们可以轻易地发现合约绝对应该检查path参数。
然而,要完全理解这次攻击,还有另一个问题需要解决:即使FEGexPRO合约批准了伪造的path,approve操作是基于用户balances2会立即减少的事实(swapToSwap函数第684行),也就是说,已批准的资金来自第3步中存入的确切金额。换句话说,攻击者只是将他/她自己的存款批准给伪造的path。之后,由于balances2的减少,攻击者不应该再为其他伪造的path进行批准。
因此,这里就提出了一个问题:攻击者究竟使用了什么技巧来进行其他批准以获取额外利润?
0x2.2 高级攻击分析
为了回答这个问题,我们回到swapToSwap函数。
仔细检查代码后,我们发现这里使用的技巧不仅是伪造path,还包括伪造swap,这导致受害者合约余额的实际值和记录值之间不一致。结果,这种不一致性可以被用来通过调用depositInternal函数来恢复攻击者的存款金额,从而重复进行批准。
具体来说,depositInternal函数主要根据合约的Main.balanceOf与_totalSupply2之间的差值来修改用户的balances2(depositInternal函数第651行)。

由于传递给swapToSwap的path地址是由攻击者控制的伪造path,因此实际上并没有发生任何转账。结果,Main.balanceOf的返回值保持与步骤3相同。请注意,_totalSupply2已在swapToSwap函数中减少。只要攻击者进行存款,增加的balance2将不可避免地大于实际存款金额。
因此,在步骤4中,攻击者首先通过调用depositInternal函数恢复存款金额,然后通过调用swapToSwap函数执行批准和伪造的swap。
请注意,攻击者使用的存款金额仅为几乎为零(即1 / 1e18)fBNB,因此,如上所述,depositInternal函数会将攻击者的balances2恢复到与步骤3几乎相同的金额(这也通过下一次批准的跟踪得到证明)。

通过重复执行步骤4,攻击者可以扩大收益。
最后,值得注意的是,我们上面描述的攻击只是攻击者利用的攻击路径之一。在同一次攻击交易中,攻击者还针对FEG资产:

0x3 根本原因
在此,我们总结了此次攻击的根本原因:
- 首先,
swapToSwap函数中未经验证的参数导致了任意批准。 - 其次,由于
swapToSwap函数中的伪造swap,导致受害者合约余额的实际值和记录值之间不一致。这被用来通过恢复攻击者的存款金额来重复进行批准。
通过将这两者结合起来,攻击者成功地耗尽了受害者合约中的所有资金。
0x4 其他相关攻击
截至本文撰写之时,我们还观察到另一名攻击者发起的更多相关攻击。
ROX(https://t.co/NWvSy5faY3)并未开源,但有些事情不对劲。
— BlockSec (@BlockSecTeam) 2022年5月17日
请看以下交易:https://t.co/chPxcDoFOD@Mudit__Gupta
同样,部署在以太坊和BSC上的合约都遭到了攻击。 有趣的是,攻击轨迹与我们刚刚讨论的不同。尽管受害者合约未开源,但我们强烈怀疑攻击者利用了相同的漏洞,采用了类似的攻击方法。
0x5 经验教训
确保DeFi项目的安全并非易事。除了代码审计,我们认为社区应该采取主动的方式来监控项目状态,并在攻击发生之前阻止它(https://blocksec.com/phalcon)。
关于BlockSec
BlockSec是一家开创性的区块链安全公司,由一群全球知名的安全专家于2021年创立。公司致力于提升新兴Web3世界的安全性和可用性,以促进其大规模采用。为此,BlockSec提供智能合约和EVM链安全审计服务,用于安全开发和主动阻止威胁的Phalcon平台,用于资金追踪和调查的MetaSleuth平台,以及供Web3构建者高效浏览加密世界的MetaDock扩展。 迄今为止,该公司已为MetaMask、Uniswap Foundation、Compound、Forta和PancakeSwap等300多家尊贵客户提供服务,并获得了Matrix Partners、Vitalbridge Capital和Fenbushi Capital等知名投资者两轮融资,总计数千万美元。
官方网站:https://blocksec.com/ 官方Twitter账号:https://twitter.com/BlockSecTeam



