5 月份,一系列攻击破坏了几个币安智能链 (BSC) 项目。继 PancakeBunny 之后,其三个分叉项目——AutoShark、Merlin Labs 和 PancakeHunny——也被使用类似的技术攻击。 PancakeBunny 遭受了四次攻击中代价最高的一次,总损失接近 4500 万美元。在本文中,Amber Group 区块链安全团队负责人 Chiachih Wu 博士详细阐述了针对三个山寨者的攻击背后的细节。
AutoShark 在 PancakeBunny 后五天遭到攻击,其次是 Merlin Labs 和 PancakeHunny。下面对这三个分叉项目存在的问题和可能的攻击技术进行分析。
在 SharkMinter.mintFor() 函数中,要铸造的奖励 SHARK 代币(即 mintShark)的数量来自于第 1494 行中由 tokenToSharkBNB() 计算的sharkBNBAmount。然而,tokenToSharkBNB() 引用了当前的翻转余额,这使它成为一个脆弱点。人们可以假设在第 1492 行收到的代币数量等于翻转余额的数量。尽管如此,坏人可以通过在 getReward() 调用之前发送一些翻转令牌并间接破坏 tokenToSharkBNB() 的逻辑来简单地操纵翻转余额。
在 tokenToSharkBNB() 的底层实现中,还有另一个攻击面。如上面的代码片段所示,_flipToSharkBNBFlip() 从 ApeSwap(第 1243 行)或 PantherSwap(第 1262 行)中移除流动性,并将 LP 代币转换为 SHARK+WBNB。稍后,调用 generateFlipToken() 将 SHARK+WBNB 转换为 SHARK-BNB LP 令牌。
在 generateFlipToken() 内部,SharkMinter 当前的 SHARK 和 WBNB 余额(amountADesired,amountBDesired)用于生成 LP 代币,并将 LP 代币的数量作为sharkBNBAmount 返回给 mintFor()。在此基础上,不良行为者可以将 SHARK+WBNB 转移到 SharkMinter 以操纵要铸造的 SHARK 代币数量。
PancakeHunny 中的漏洞与 AutoShark 中发现的漏洞相同,即不良行为者可以使用 HUNNY 和 WBNB 代币操纵 HUNNY 奖励铸造。
与 AutoShark 和 PancakeHunny 相比,Merlin Labs 的 _getReward() 存在更明显的漏洞。
上面的代码片段表明,performanceFee 可以通过 CAKE 的余额来操纵,这间接影响了 MERL 奖励的铸造。然而,nonContract 修饰符摆脱了闪贷。
即使没有漏洞利用合同,坏人仍然可以通过多次调用获利。
要重现 AutoShark hack,我们首先需要从 PantherSwap 获取一些 SHARK-BNB-LP 令牌。具体来说,我们将 0.5 WBNB 交换到 SHARK(第 58 行),并将剩余的 WBNB 与这些 SHARK 代币一起转移到 PantherSwap 中以铸造 SHARK-BNB-LP 代币(第 64 行)。稍后,我们将这些 LP 代币存入 AutoShark 的 StrategyCompoundFLIP 合约(第 69 行)以获得奖励。请注意,我们故意只在第 69 行存入一半的 LP 代币。
第二步是让 getReward() 进入 SharkMinter 合约。在上面的代码片段中,我们知道奖励可以通过 Earn() 函数(第 1658 行)检索。此外,30% 的奖励(即 performanceFee)应大于 1,000(即 DUST)以触发第 1668 行中的 SharkMinter.mintFor()。
因此,在我们的漏洞利用代码中,我们在第 76 行将一些 LP 代币转移到 StrategyCompoundFLIP 合约以绕过 performanceFee > DUST 检查并触发 mintFor() 调用。由于我们需要大量的 WBNB+SHARK 来操作 SharkMinter,因此我们通过第 81 行的 flash-swap 调用来利用 PantherSwap 的 100k WBNB。
在 flash-swap 回调 pancakeCall() 中,我们将一半的 WBNB 交换为 SHARK,并将剩余 50,000 WBNB 的 SHARK 发送到 SharkMinter 合约以操纵奖励铸造。
下一步是在 SharkMinter 收到 WBNB+SHARK 令牌时触发 getReward() 向调用者铸造大量 SHARK。
最后一步是将 SHARK 转换为 WBNB,支付闪贷,然后带走剩余的 WBNB 代币。
在我们的实验中,坏人从 1 WBNB 开始。在闪贷的帮助下,他从一笔交易中退回了 1,000 多个 WBNB 中获利。
PancakeHunny 攻击背后的理论与 AutoShark 攻击相似。简而言之,在触发 getReward() 之前,我们需要向 HunnyMinter 发送大量 HUNNY+WBNB。但是,HUNNY 代币合约有一个称为 antiWhale 的保护机制,可以防止大量转移。因此,闪贷在这里不起作用。
为了绕过 antiWhale,我们创建了多个子合约并通过这些合约启动了多个 CakeFlipVault.deposit() 调用。
在上面的漏洞利用代码片段中,在第 116 行收集的 LP 代币被分成 10 个部分,并在第 122 行转移到 10 个 Lib 合约,然后为每个合约调用 Lib.prepare()。
在 Lib.prepare() 中,我们批准 () CakeFlipVault 使用 LP 代币并调用 CakeFlipVault.deposit() 以启用稍后的 getReward() 调用来铸造奖励 HUNNY 代币。
准备好10个Lib合约后,主合约对每个合约进行迭代:1)将WBNB换成HUNNY的最大允许数量; 2) 将WBNB+HUNNY转给HunnyMinter; 3) 通过 lib.trigger() 触发 getReward();和 4) 将 HUNNY 交换回 WBNB。
最终,拥有 10 个 WBNB 的坏人从 10 次运行 10 个 Lib 合约操作中赚取了大约 200 个 WBNB。
如前所述,Merlin Labs 拥有 noContract 修饰符来摆脱闪贷攻击。但是,我们可以使用脚本来触发从 EOA(外部拥有账户)地址发起的多个交易的攻击。唯一的区别是有人可能会抢先进行不良行为者的交易以窃取利润。
类似于 AutoShark 攻击,我们需要准备足够的 LINK 和 WBNB(第 23 行),用它们铸造 WBNB-LINK-LP 代币(第 34 行),并将 LP 代币存入 VaultFlipCake 合约(第 38 行)。
剩下的动作是:
如前所述,如果有人在第 2 步之后立即执行第 3 步,则该人可能会删除大量的 MERL。
在我们的实验中,坏人从 10 WBNB 开始,然后通过重复 10 次四个步骤,以大约 165 WBNB 离开。
Amber Group 是全球领先的加密金融服务提供商,在全球范围内全天候运营,在香港、台北、首尔和温哥华设有办事处。 Amber Group 成立于 2017 年,为 500 多家机构客户提供服务,在 100 多个电子交易所累计交易额超过 5000 亿美元,管理的资产超过 15 亿美元。 2021年,Amber Group在B轮融资1亿美元,成为最新一家估值超10亿美元的金融科技独角兽。如需了解更多信息,请访问 www.ambergroup.io。