BEVO操作预言机攻击

  • KEN
  • 发布于 1天前
  • 阅读 34

案例介绍:2023年1月,BEVO项目被攻击,造成144个BNB,约为45000美元的资产丢失,如果是按照今天的币价,这个数字还会更大,并且直接导致了BEVO代币的价格下跌了99%。项目被攻击的原因是由于该项目使用了价格预言机来作为当前代币价格,而价格预言机的模型在设计时却存在缺陷,导致该缺陷被攻

案例介绍:

2023年1月,BEVO项目被攻击,造成144个BNB,约为45000美元的资产丢失,如果是按照今天的币价,这个数字还会更大,并且直接导致了BEVO代币的价格下跌了99%。项目被攻击的原因是由于该项目使用了价格预言机来作为当前代币价格,而价格预言机的模型在设计时却存在缺陷,导致该缺陷被攻击者利用,进行了价格操控。 Total lost: 144 BNB 抢跑者: 0xd3455773c44bf0809e2aeff140e029c632985c50 初始攻击者: 0x68fa774685154d3d22dec195bc77d53f0261f9fd 抢跑合约: 0xbec576e2e3552f9a1751db6a4f02e224ce216ac1 初始攻击合约:0xbf7fc9e12bcd08ec7ef48377f2d20939e3b4845d 被攻击合约: 0xc6cb12df4520b7bf83f64c79c585b8462e18b6aa Attackhash:0xb97502d3976322714c828a890857e776f25c79f187a32e2d548dda1c315d2a7d

攻击前的准备:

该项目是一个利用反射机理的通缩代币项目,一般来说在该种类型的项目中往往存在一个特性,即当某个通缩代币持有者销毁其通缩代币时,项目为了奖励该种类型代币的持有者,会自动的增加代币持有者的余额,但不会触发转账,只是修改一个系数。在这个机制中,用户持有的代币数量有两种,分别为tAmount和rAmount。tAmount为实际持有的代币数量,rAmount为体现的代币数量,比例为tTotal/rTotal。反射机制的token一般都有一个叫deliver的函数,这个函数会销毁调用者的token,降低rTotal的值,所以比例会增加,其他用户反射的token数量也会增加,攻击者注意到了该功能,并利用该功能对相应的Uniswap流动性池进行攻击,在Uniswap中,reserve就是储备资金,和token.balanceOf(address(this))有区别。攻击者首先调用 deliver 函数销毁自己的 token,导致 rTotal 的值减小,比例增大,因此反射出来的 token 的值也会增大,token.balanceOf(address(this)) 也会随之增大,导致和储备值出现差距。因此攻击者可以通过调用skim函数转移两个token之间的差额来获利。 值得一提是的本次攻击中,原始攻击者的攻击被链上抢跑机器人抢跑了,所以我们只分析抢跑的这笔交易,因为本质上抢跑交易使用的就是原始攻击交易的逻辑。首先,攻击者部署攻击合约: 0xbec576e2e3552f9a1751db6a4f02e224ce216ac1,该合约在浏览器上只能看到字节码,故对其进行反编译:

image.png

image.png

在反编译之后,我们仍无法直接通过分析伪代码去判断整个攻击的流程,唯一能发现的就是这个合约与很多攻击合约一样,有非常多的require判断条件,这些条件的设立目的,有两个,第一是确保只有自己能够成功调用该合约中的函数,成为攻击中的唯一受益方,第二确保其他人无法在短时间内分析出整个攻击的逻辑,从而仿照其攻击逻辑进行抢跑。所以如果这是一笔正在发生的攻击交易,我们承认我们确实无法分析出其攻击逻辑,但是我们可以肯定,目前绝大部分web3从业者肯定同样做到,所以我们只好将其作为一个笔已发生的交易,利用tracer通过该合约与其他合约已经发生了的关系,推断整个攻击逻辑,下面是tracer显示攻击的整个流程,并且我们使用红色方框圈出了整个攻击中最关机键的步骤:

image.png

攻击流程:

Step1.攻击者通过闪电贷从交易所中借出192.5 BNB,将这些BNB作为整个攻击的全部本金。 Step2.攻击者在交易所中将换取来的192.5BNB换成BEVO代币,该代币为通缩代币。 Step3.攻击者调用被攻击合约中的deliver函数,销毁自己BEVO代币,由于BEVO是通缩代币,除白名单之外的全部BEVO代币持有者的代币持有量都会增加。由于Pancake pair中同样持有BEVO代币,所以代币持有量也会增加。 Step4.攻击者调用pair中的skim函数,该函数会将pair中代币余额与代币储备量的差值转到任意地址,而由于攻击者上一步骤的deliver操作,导致pair中的余额大于存储量,所以该函数会将代币数量差值全部转移到攻击者设计的地址0xd3455773c44bf0809e2aeff140e029c632985c50上。 (注意:这个过程中攻击者利用从pair中获取的代币数量与自己deliver销毁的代币数量的差值获利,其关键是保证这样一个不等式:y / rate > x,其中y是pair中的bevo代币数量,rate是被攻击合约中的rSupply/tSupply,x是攻击者销毁的代币数量,试想y和rate都是公开的,所以攻击者只要使得x满足不等式,就能一直获利。) Step5.攻击者再次调用被攻击合约中的deliver函数,故技重施,同样这次deliver的调用也导致了pair中的BEVO代币持有量增加。 Step6.攻击者调用swap函数,将pair中增加的全部BEVO全部换算成BNB,最终换取334BNB。 Step7.攻击者归还闪电贷借款。最终获利144BNB。 以下是攻击的整个流程:

image.png

攻击案例复现

复现流程: Step1.foundry环境准备: Step2.代码复现:我们在本地复现了Discover攻击的整个流程,在攻击过程中我们模拟攻击者原地址为整个交易的发起者,这样可以使得攻击合约中某些条件检测得以通过,我们编写了自己的攻击合约来复现整个交易流程:

image.png (1)上图为配置实验环境,并且我们将本地的合约作为我们自己的攻击合约,用于浮现整个攻击流程。

image.png (2)我们将上述函数作为整个攻击交易的入口, 首先攻击合约授权router合约,让其可以使用攻击合约的wbnb代币并且调用wbnb_usdc pair中的swap函数,从该pair对中借钱192.5 WBNB。 (3)在wbnb_usdc pair合约转钱给攻击合约之后,立刻会以闪电贷的方式回调攻击合约,在本地攻击合约收到回调之后迅速调用router合约中的函数将这些借来的WBNB换成BEVO代币,具体实现如下图所示:

image.png (4)紧接攻击合约调用漏洞项目BEVO代币合约中的deliver函数销毁从bevo_wbnb pair中换出来的bevo代币,由于BEVO代币是通缩代币,该操作会使得所有bevo代币的持有者中的代币数量增加,包括bevo_wbnb pair。

image.png

image.png (5)攻击合约迅速通过skim函数获取bevo_wbnb pair中增加的bevo代币数量,以此获利。

image.png (6)最后攻击合约重复上述过程,使得bevo_wbnb pair中代币数量增加,只不过最后并不是直接将bevo代币提取传来,而是换成了通过swap函数将pair增加的bevo代币换成wbnb,以WBNB的代币形式获利:

image.png (7)最后归还闪电贷欠款,实现获利:

image.png 攻击复现整体业务逻辑为:

image.png

点赞 3
收藏 1
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
KEN
KEN
0x4e16...2573
江湖只有他的大名,没有他的介绍。