2021 年 5 月,我们目睹了针对 BSC DeFi 产品的多次黑客攻击。 特别是,收益聚合器 PancakeBunny 中与奖励铸造相关的漏洞被利用从无到有铸造了约 700 万个 BUNNY 代币,导致高达 4500 万美元的经济损失。 在血腥的黑客攻击之后,三个分叉项目——AutoShark、Merlin Labs 和 PancakeHunny——都受到了类似技术的攻击。 由 Chiachih Wu 博士领导的 Amber Group 的区块链安全团队详细说明了漏洞,并通过重现对 PancakeBunny 的攻击来逐步说明漏洞利用。 隐藏攻击面:balanceOf() 许多人认为可组合性对 DeFi 的成功至关重要。 代币合约(例如 ERC20s)在 DeFi 乐高积木的底层扮演着重要的角色。 但是,开发人员在将 ERC20 集成到他们的 DeFi 项目中时可能会忽略一些不可控和不可预测的情况。 例如,当您检索当前代币余额时,您无法预测您将在何时以及收到多少代币。 这种不确定性创造了一个隐藏的攻击面。 在很多情况下,智能合约在其业务逻辑中会参考 ERC20 的余额。 例如,当用户将一些 XYZ 代币存入智能合约时,会调用 XYZ.balanceOf() 来检查收到了多少钱。 如果您熟悉 Uniswap 代码库,您可能知道 UniswapV2Pair 合约有许多 balanceOf() 调用。 在代码片段中,UniswapV2Pair.mint() 使用当前余额 (balance0, balance1) 和簿记数据 (amount0, amount1) 得出用户存入的金额 (amount0, amount1)。 然而,如果坏人在 mint() 调用之前转移了一些资产(token1 或 token2),受害者将提供比预期更多的流动性,即铸造更多的 LP 代币。 如果奖励是根据 LP 代币的数量计算的,那么当奖励超过费用时,坏人就可以获利。 UniswapV2Pair.burn() 也有类似的风险。 mint() 函数调用者可能会在没有彻底了解所涉及的风险的情况下危及自己。 这就是 PancakeBunny 的情况。 在上面的代码片段中,第 140 行通过 balanceOf() 检索 LP 代币的余额并将其存储到流动性中。 在第 144-145 行中,UniswapV2Pair 拥有的总 LP 代币的部分(即 _totalSupply 中的流动性)用于通过两种资产(即 token0 和令牌1)。 稍后,这两个资产的 (amount0,amount1) 被转移到第 148-149 行中的地址。 在这里,坏人可以通过在调用 mint() 函数之前将一些 token0+token1 或 LP 令牌发送到 UniswapV2Pair 合约来操纵(balance0,balance1)和流动性,以使调用者获得更多的 token0+token1。 我们将引导您完成 PancakeBunny 源代码,并向您展示坏人如何从这样做中获利。 漏洞分析:BunnyMinterV2 在 PancakeBunny 源代码中,BunnyMinterV2.mintForV2() 函数负责铸造 BUNNY 代币作为奖励。 具体来说,要铸造的数量(即 mintBunny)来自输入参数 _withdrawalFees 和 _performanceFee。 计算与三个函数相关:_zapAssetsToBunnyBNB()(第 213 行)、priceCalculator.valueOfAsset()(第 219 行)和 amountBunnyToMint()(第 221 行)。 由于坏人可以铸造大量的BUNNY,问题出在上述三个功能之一。 让我们从 _zapAssetsToBunnyBNB() 函数开始。 当传入的资产为 Cake-LP 时(第 267 行),使用一定数量的 LP 代币去除流动性,并从流动性池中取出 (amountToken0, amountToken1) 的 (token0, token1)(第 278 行)。 在 zapBSC 合约的帮助下,这些资产被交换为 BUNNY-BNB LP 代币(第 287-288 行)。 然后将相应数量的 BUNNY-BNB LP 代币返回给调用者(第 298 行)。 在这里,我们有一个问题。数量是否与您假设要销毁的 LP 代币数量相匹配? 在 PancakeV2Router.removeLiquidity() 的实现中,LP 代币的流动性(在 zapAssetsToBunnyBNB() 中的金额)将被发送到 PancakePair 合约(第 500 行)并调用 PancakePair.burn()。 如果 PancakePair 当前的 LP 代币余额大于 0,则实际燃烧的数量会大于 amount,间接增加了 BUNNY 的铸造数量。 _zapAssetsToBunnyBNB() 中的另一个问题是 zapBSC.zapInToken() 调用。这背后的逻辑是将 removeLiquidity() 收集的两个资产交换为 BUNNY-BNB LP 代币。 由于 zapBSC 通过 PancakeSwap 交换资产,不良行为者可以使用闪电贷来操纵交换的 BUNNY-BNB 数量。 回到 BunnyMinterV2.mintForV2(),zapAssetsToBunnyBNB() 返回的 bunnyBNBAmount 将被传递到 priceCalculator.valueOfAsset() 以引用基于 BNB 的值(即 vauleInBNB),类似于预言机机制。 然而,priceCalculator.valueOfAsset() 参考 BUNNY_BNB PancakePair 中 BNB 和 BUNNY (reserve0,reserve1) 的数量作为价格馈送,这使不良行为者能够使用闪电贷来操纵铸造的 BUNNY 代币数量。 amountBunnyToMint() 函数是一个简单的数学计算。 输入贡献乘以五(bunnyPerProfitBNB = 5e18),它本身没有攻击面,但放大放大了上面提到的操纵。 准备战斗 由于攻击是由 getReward() 触发的,所以我们需要先获得奖励资格。 如上图 Etherscan 截图所示,PancakeBunny 黑客调用漏洞利用合约的 init() 函数将 1 个 WBNB 兑换成 WBNB-USDT-LP 代币并将其存入 () 到 VaultFlipToFlip 合约中,这样他就可以通过调用 getReward()。 如上所示,我们使用 Exp.prepare() 函数重现了 vaultFlipToFlip.deposit() 调用(第 62 行)。 我们还使用 ZapBSC 合约来简化获取 LP 代币的过程(第 54-57 行)。 但是,在 PancakeBunny 管理员触发下一次收获()调用之前,您无法获得奖励。 出于这个原因,PancakeBunny 黑客直到 init() 事务之后的第一个 Harvest() 事务才触发攻击。 在我们的模拟中,没有 keeper 可以触发收割()。 因此,我们利用 eth-brownie 的特性来模拟 keeper 并手动启动 Harvest() 事务(第 25 行)。 递归闪贷 为了利用资金,PancakeBunny 开发者利用了八个不同的资金池,包括七个 PancakePair 合约和 ForTube 银行。 在这里,Amber Group 的区块链安全团队仅使用以下 7 个 PancakePair 合约的 flash-swap 功能借出了 2.3M WBNB: 地址[7] 对 = [ 为了简化 flash-swap 调用,我们将两个参数打包到 PancakePair.swap() 调用(第 72 行或第 74 行)的第四个输入参数中:级别和资产。 level 变量表示我们在哪个级别的 swap() 调用; 资产变量是 0 或 1,这意味着我们需要借用 token0 或 token1。 使用回调函数 pancakeCall(),我们以 level+1 递归调用 PancakePair.swap(),直到到达第七级。 在顶层,我们调用 shellcode() 来执行第 98 行中的实际操作。当 shellcode() 返回时,资产变量返回每个相应级别(第 102-104 行)中借入的资产。 扣动扳机 pancakeCall() 第七层调用的 shellcode() 函数是实际的漏洞利用代码。 首先,我们将 WBNB 的当前余额保持在 wbnbAmount(第 108 行)中,将 15,000 WBNB 交换为 WBNB-USDT-LP 代币(第 112 行),并将它们发送到铸造这些 LP 代币的合约(即 PancakePair 合约)第 113 行。此步骤旨在操作上面分析的 _zapAssetsToBunnyBNB() 函数内的 removeLiquidity() 调用,使我们能够收到比预期更多的 WBNB+USDT。 第二步,操纵_zapAssetsToBunnyBNB()引用的USDT价格,将USDT换成WBNB。 由于 _zapAssetsToBunnyBNB() 使用 WBNB-USDT PancakePair 将 USDT 换成 WBNB,我们可以在 PancakeSwap 上将剩余的 Flash 借出的 WBNB 换成 USDT。这样做会使 WBNB 变得非常便宜,而 _zapAssetsToBunnyBNB() 从 USDT 交换时会收到不成比例的大量 WBNB。 请注意,此处的价格操纵发生在 Pancake V1 池上,而不是上一步中的 Pancake V2 的 PancakePair。 最后一步是 getReward() 调用。简单的合约调用可以铸造 690 万个 BUNNY 代币(第 125 行)。 然后可以在 PancakeSwap 上将 BUNNY 代币换成 WBNB 以偿还闪贷。 在我们的模拟中,坏人支付 1 WBNB 并带走 104k WBNB + 3.8M USDT(相当于约 4500 万美元)。 关于琥珀集团 Amber Group 是全球领先的加密金融服务提供商,在全球范围内全天候运营,在香港、台北、首尔和温哥华设有办事处。 Amber Group 成立于 2017 年,为 500 多家机构客户提供服务,在 100 多个电子交易所累计交易额超过 5000 亿美元,管理的资产超过 15 亿美元。 2021年,Amber Group在B轮融资1亿美元,成为最新一家估值超10亿美元的金融科技独角兽。 如需更多信息,请访问:www.ambergroup.io。 —- 原文链接:https://www.newsbtc.com/news/company/bsc-flash-loan-attack-pancakebunny/ 原文作者:NewsBTC 编译者/作者:wanbizu AI 玩币族申明:玩币族作为开放的资讯翻译/分享平台,所提供的所有资讯仅代表作者个人观点,与玩币族平台立场无关,且不构成任何投资理财建议。文章版权归原作者所有。 |
BSC 闪贷攻击:PancakeBunny
2021-07-23 wanbizu AI 来源:区块链网络
LOADING...
相关阅读:
- 安全月价格逆转下跌趋势但巩固,下一步是什么?2021-07-23
- 这个山寨币在市场不确定的情况下创造了一个新的 ATH 大跃进2021-07-23
- Dogira 希望通过 NFT 改变游戏世界2021-07-23
- 符文还是毁灭? THORChain 在一周内遭受第二次攻击2021-07-23
- 检查比特币衍生品市场 – 比特币杂志:比特币新闻、文章、图表2021-07-23