请警惕那些隐藏的Rug Pull,以及由合约存储引起的跑路盘。

请注意隐藏的Rug Pull和合约存储引起的跑路盘。

解析一起代币增发事件:案例分析与安全建议

背景

在DeFi 之夏后,人们学会了在参与新项目之前仔细检查代币合约的权限、持仓分布和代码。然而,坏人们的作恶手段也变得更加高明和隐蔽。最近,慢雾安全团队收到了LianGuaincakeSwap 社区用户的求助,他们注意到在一个项目中,没有增发任何代币的情况下,恶意用户通过未被记录的大量增发代币来取走了池子中的资金。慢雾安全团队跟进分析了这起事件,并分享了以下结果:

攻击细节

恶意代币IEGT在BSC上的部署地址是0x8D07f605926837Ea0F9E1e24DbA0Fb348cb3E97D。通过区块浏览器观察代币的持有者,我们发现尽管存在大量的IEGT代币持有者是死亡地址(dead)和LianGuaiir地址,合约中记录的totalSupply仍保持在500万。

进一步观察这些代币的来源,发现这些代币在地址0x00002b9b0748d575CB21De3caE868Ed19a7B5B56中只有转出记录,没有转入记录。

根据EIP20标准,代币转移需要实现Transfer事件,包括从0x0地址转移代币,也必须进行事件记录。区块浏览器依赖这些标准的事件记录进行数据统计。因此,当在区块浏览器中发现代币总额与实际数量不匹配时,则表明代币在增发时未进行事件记录,导致区块浏览器只统计转账后相关地址的余额变化,而没有记录任何代币增发。根据这个情况,我们可以确定代币合约中存在恶意代码来进行代币的增发。

这个代币合约是开源的,这可能是为了增加项目的可信度。我们对源代码进行了分析。一般来说,最简单的代币增发方法就是实现一个直接增加指定地址余额的函数。但经过检查,合约中并没有发现直接增加余额的代码。

既然没有发现直接增加余额的代码,那么项目方又是如何进行增发的呢?我们回顾一下智能合约的基础知识,可以知道用户代币余额的变化实质上就是修改了合约在链上存储的数据状态。因此,只要修改特定地址的_balances在合约中对应存储的位置,就可以修改其代币余额。

我们先简单回顾一下EVM中计算合约数据存储位置的基础知识。对于映射类型_balances来说,根据键值k和占据位置p,需要通过keccak256计算其存储的插槽位置,即keccak256(k,p)。通过分析IEGT合约的数据存储位置,我们发现_balances参数的存储位置在slot0,因此用户的余额存储位置是keccak256(address,0)。

带入恶意地址进行计算,可以得到其余额存储位置为0x9d1f25384689385576b577f0f3bf1fa04b6829457a3e65965ad8e59bd165a716。进一步查找这个插槽数据的变化,可以发现在合约部署时已被修改为一个巨大的值。

因此,我们可以确定在IEGT合约的初始化过程中,项目方通过内联汇编的方式隐蔽地增发了大量的代币,为Rug(欺诈行为)做好准备。在初始化函数中,项目方通过内联汇编操作修改了合约存储,并且没有对代码进行格式化处理,以降低可读性。

通过计算,我们可以得到y值为2b9b0748d575cb21de3cae868ed19a7b5b56。通过两次mstore将内存0~64 字节的位置填充为00000000000000000000000000002b9b0748d575cb21de3cae868ed19a7b5b56,而恶意增加代币余额的地址是0x00002b9b0748d575CB21De3caE868Ed19a7B5B56。我们可以发现恶意用户通过构造一连串的数据,计算后得到其控制的目标地址。因此,我们也可以从编译后的字节码中看到这个计算后未进行填充的”地址”。

紧接着,通过对内存0~64字节的数据进行keccak256哈希,恰好得到恶意用户的余额存储插槽位置0x9d1f25384689385576b577f0f3bf1fa04b6829457a3e65965ad8e59bd165a716,这也正是合约中将_balances置于slot0位置的原因,这极大地方便了在内联汇编中计算余额实际存储位置。然后,使用sstore将合约中此存储位置的值修改为当前时间的6次方,从而完成了对指定地址的余额修改。随后的内联汇编操作类似,不再赘述。

追踪分析

通过MistTrack分析,这起事件中获利的地址是BSC链上的0x000000481F40f88742399A627Cbc2Afb6Ec34FeD和0x00002b9b0748d575CB21De3caE868Ed19a7B5B56,共获利114万USDT。获利地址转移USDT的手续费来源是Binance交易所提款。

目前资金的转移情况如下图所示:

资金转移情况

此外,恶意合约创建者的手续费地址0xb795ad917DAF9A1c98eE18E03E81FBBfb6D54355同样有大量痕迹。

恶意合约创建者地址痕迹

总结

在这起事件中,项目方开源了合约代码以增加用户的信任度,通过未格式化的代码降低了代码的可读性,并使用内联汇编来编写直接修改用户余额存储插槽数据的代码,提高了代码分析的门槛。他们使用各种手段隐藏作恶痕迹,最终将池子中的资金一并席卷走。据SlowMist Hacked统计,截至目前,由于Rug Pull导致的损失金额接近5亿美元。因此,用户在参与新项目时应重点分析其合约中是否存在可疑的代码,并尽量避免参与未开源且未经审计的项目。MistTrack团队将继续跟进并监控此类事件。

参考链接:

[1] https://bscscan.com/address/0x8d07f605926837ea0f9e1e24dba0fb348cb3e97d

[2] https://eips.ethereum.org/EIPS/eip-20

[3] https://misttrack.io/

[4] https://hacked.slowmist.io/