Beosin:PLTD安全事件简析
据Beosin EagleEye Web3安全预警与监控平台检测显示,PLTD项目遭受黑客攻击,其交易池中的所有BUSD被全部兑空。
攻击交易:0x8385625e9d8011f4ad5d023d64dc7985f0315b6a4be37424c7212fe4c10dafe0,
攻击者地址:0x6ded5927f2408a8d115da389b3fe538990e93c5b
攻击者共获利24,497BUSD。
经过Beosin安全团队分析,本次攻击主要是利用了PLTD合约中的代码漏洞,通过闪电贷攻击将Cake-LP(0x4397c7)中的PLTD代币余额降为1,然后用手中的PLTD将所有的BUSD全部兑换到攻击合约中。具体细节如下:
第一步:攻击者通过DODO协议的闪电贷发起了2次闪电贷借贷,同借贷66.6万 BUSD,作为攻击准备金;
第二步:攻击者将66.6万的BUSD全部兑换为157万的PLTD代币,此时,攻击者手中已经持有的大量的PLTD代币,后续将利用这些代币达到操控Cake-LP中的PLTD代币余额的目的;
第三步:攻击者查询当前的bron值与Cake-LP的PLTD余额,这是在做攻击前的检查,注意这两个值很关键,关系到攻击的成败;
第四步:攻击者直接向Cake-LP(0x4397c7)发送了11.6万的PLTD代币,注意,这个数量刚刚是上一步中Cake-LP中的PLTD代币余额的两倍减去1
为什么是这个数字,我们结合代码就很明显的能够看出来:
(1) 直接转账,调用transfer函数
(2) 由于目标地址是uniswapV2Pair,进入344行的else if分支,并且由于from地址是攻击合约,takeFee为true,并调用内部函数_tokenTransferSell
(3) _tokenTransferSell函数内部代码如下,注意第423-426行,这部分代码将_bron设置为本次转账数量的一半,即Cake-LP的余额减去1,让我们记住这个_bron的值;
第五步:让我们继续回到攻击过程,这里攻击者使用skim将第四步多转入的PLTD取回,由于PLTD合约的transfer函数中,如果from地址是uniswapV2Pair,那么将会调用_tokenTransferBuy这个函数细节不重要,我们知道他不会影响_bron的值就行了。
第六步:图穷匕见,前面所有的操作都是为了这一步做准备。这一步,攻击者向0x16b9a82891338f9ba80e2d6970fdda79d1eb0dae这个地址转入1 PLTD,由于这个地址不是Cake-LP的地址,这次转账调用的内部函数是_tokenTransfer这个内部函数,其代码如下:
这里我们直接看问题代码,也就是第451行到456行,由于第四步中,我们将_bron设置为了Cake-LP的余额减去1,并且在第五步恢复了Cake-LP的余额,这一步直接将Cake-LP的余额减至1(这里略去了通缩分红型代币的tAmount与rAmount转换,这个转换在本次攻击中并不重要),然后再调用Cake-LP的sync函数,将余额同步为reserve,此时reserve如下:
第七步:攻击者将手中的所有PLTD代币,全部兑换为BUSD,几乎掏空了Cake-LP的全部BUSD余额,攻击者获得了69万的BUSD。并将其中的66.6万 BUSD归还闪电贷,剩余为本次攻击获利24,497 BUSD,并全部转入了0x083c057221e95D45655489Fb01b05C4806387C19地址,截止发文时,该资金未进行转移,Beosin Trace对被盗资金进行持续监控与追踪。
针对本次攻击事件,Beosin安全团队提出以下建议:
(1) 在合约上线之前,项目方应寻找第三方安全公司进行完整的安全审计;
(2) 在代币合约中,直接操作Pair的代币余额是非常危险的行为,建议项目方如非必要,千万不要进行此操作;