警惕隐蔽的 Rug Pull 合约存储引起的跑路盘

    背景从DeFi之夏到现在,我们在遭受各种漏洞、后门、跑路等层出不穷的手段洗礼后,总算学会了在DEX上参与新项目前,应先检查代币合约的权限、代币的持仓分布及合约的代码以保护自己的资产安全。但相对的,坏人们的作恶手段也更加高明与隐蔽。近期,慢雾安全团队收到来自PancakeSwap社区用户的求助,其参与项目时观察到,在项目代币没有任何增发记录的情况下,恶意用户使用未被记录的大量增发代币卷走了池子中的资金。慢雾安全团队跟进分析此事件并将结果分享如下:攻击细节恶意代币IEGT在BSC上的部署地址是0x8D07f605926837Ea0F9E1e24DbA0Fb348cb3E97D[1]。我们通过区块浏览器观察其Holders,发现在dead与pair地址持有大量IEGT代币的情况下,合约记录的totalSupply仍为5,000,000。通过进一步查看这些代币的来源可以发现,这些代币在0x00002b9b0748d575CB21De3caE868Ed19a7B5B56中只有转出记录而没有转入记录。我们都知道,EIP20标准[2]规定了代币转移时必须实现Transfer事件,包括在代币铸造时,从0x0地址进行转移也必须进行事件记录。区块浏览器依赖这些标准的事件记录进行数据统计。

    因此,当在区块浏览器中发现其代币总额与实际数量不匹配时,则表明代币在进行增发时并未进行事件记录,导致区块浏览器只统计了转账后相关地址的余额变化,而没有任何代币增发记录。据此,我们可以确定代币合约中必然存在增发代币的恶意代码。此代币合约的代码是开源的,想来是项目方为了增加项目的可信度。接下来我们对其源码进行分析。一般来说,进行代币增发最简单的方式就是实现一个直接增加指定地址余额的方法。在当前合约中是通过定义一个_balances映射,对用户的代币余额进行记录。但经过检查,合约中并未实现对指定地址的_balances进行修改的代码。既然没有发现直接增加余额的代码,那么项目方又是如何进行增发的呢?

    我们回顾下智能合约的基础知识,可以知道用户代币余额的变化本质上就是修改了合约在链上存储的数据状态。因此,只要修改特定地址的_balances在合约中对应存储的插槽数据,即可修改其代币余额。我们先简单回顾下EVM中计算合约数据存储位置的基础知识,对于映射类型_balances来说,其会根据其键值k与其所占据位置p进行keccak256后得到偏移量,作为其存储的插槽位置,即keccak256(k,p)。通过分析IEGT合约的数据存储位置,我们可以发现其_balances参数所在位置为slot0,那么用户的余额存储位置即为keccak256(address,0)。带入恶意地址进行计算,可以得到其余额存储位置为0x9d1f25384689385576b577f0f3bf1fa04b6829457a3e65965ad8e59bd165a716。随后查找此插槽数据变化,可以发现其在合约部署时已被修改为一个巨大的值。因此,我们可以确定在IEGT合约部署初始化时,项目方就隐蔽地增发了大量的代币,为Rug做好准备。接下来我们跟进其初始化函数,分析发现其在进行_pathSet操作时,通过内联汇编对合约存储进行了修改,并且未对代码进行格式化处理,以降低其可读性。

    跟进计算发现y值为2b9b0748d575cb21de3cae868ed19a7b5b56,通过两次mstore将内存0~64字节的位置填充为00000000000000000000000000002b9b0748d575cb21de3cae868ed19a7b5b56,而恶意增加代币余额的地址为0x00002b9b0748d575CB21De3caE868Ed19a7B5B56。可以发现恶意用户通过构造一连串的数据,计算使得正好可以得到其控制的目标地址。因此,我们也可以从编译后的字节码中发现此计算后未进行填充的“地址”。紧接着通过keccak256对内存0~64字节的数据进行哈希后,正好得到恶意用户的余额存储插槽位置0x9d1f25384689385576b577f0f3bf1fa04b6829457a3e65965ad8e59bd165a716,这也正是合约中将_balances置于slot0位置的原因,这极大方便了在内联汇编中计算余额实际的存储位置。然后使用sstore将合约中此存储位置的值修改为当前时间的6次方,此时即完成了对指定地址的余额修改。随后的内联汇编操作类似,在此不做赘述。至此,我们知道了项目方是在合约初始化时,通过内联汇编的方式修改了指定地址余额,隐蔽地增发了大量未被其他用户获悉的代币,导致用户在参与项目时被Rug。追踪分析通过MistTrack[3]分析此次事件获利地址为BSC链上0x000000481F40f88742399A627Cbc2Afb6Ec34FeD与0x00002b9b0748d575CB21De3caE868Ed19a7B5B56,共计获利114万USDT,获利地址转移USDT的手续费来源为Binance交易所提款。

    目前资金转移情况如下图:此外,恶意合约创建者的手续费地址0xb795ad917DAF9A1c98eE18E03E81FBBfb6D54355同样存在大量痕迹。总结此次事件中,项目方开源合约代码以增加用户信任度,通过未格式化的代码降低代码可读性,并且使用内联汇编来编写直接修改用户余额存储插槽数据的代码,提高了代码分析门槛。其使用种种手段隐藏作恶痕迹,最后将池子席卷一空。可以发现,在用户的安全意识越来越强的情况下,作恶者的手段也越发隐蔽与高明。据SlowMistHacked[4]统计,截止目前,由于RugPull导致的损失金额接近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/

Pixel Artist Pixel Artist
Happy Kittens Puzzle Happy Kittens Puzzle
Penguin Cafe Penguin Cafe
Animal Connection Animal Connection
Snakes N Ladders Snakes N Ladders
Pixel Skate Pixel Skate
BeeLine BeeLine
Draw Parking Draw Parking
Draw Racing Draw Racing
Soccer Balls Soccer Balls
Happy Fishing Happy Fishing
Crashy Cat Crashy Cat

FREE GAMES FOR KIDS ONLINE