合约安全之Mike&Sid事件分析

admin 2025年6月25日00:40:32评论2 views字数 2415阅读8分3秒阅读模式

01
事件背景
2023年7月4日,ChainAegis发布预警,Mike和SId代币的项目方通过后门捐款跑路,攻击者获利87.9eth,约为17.1万美元:
合约安全之Mike&Sid事件分析
攻击者地址为:0xF7E0d99511eab452bCBBdC34285E25F10E28F79D。查看这个地址的所有ERC20交易:
合约安全之Mike&Sid事件分析
02
分析
这两笔交易都是使用大量代币去uinswap池子。
换取weth:
合约安全之Mike&Sid事件分析
以Mike代币合约为例,这个合约符合ERC20的标准,但是里面的逻辑都是自己实现的,构造函数的参数也做了很多的修改。攻击者向uniswap pair合约发送了1,262,000,000,000,000的Mike代币,查看Mike代币的转移记录,来找出攻击者是怎么拥有这么多代币的。
在众多的授权交易中,我们发现了一个可疑的increaseAllowance交易:
合约安全之Mike&Sid事件分析
这个交易的调用地址就是攻击地址,调用函数为increaseAllowance,参数spender为攻击者地址,amount与发送到pair合约的代币数量相同:
合约安全之Mike&Sid事件分析
查看这个函数的具体实现:
合约安全之Mike&Sid事件分析
这个函数的目的增加指定地址的授权,这个函数首先调用_decode,参数是spender和 _guest.guest。而 _decode函数的作用是判断输入的两个参数是否相等:
合约安全之Mike&Sid事件分析
这个_guest.guset是构造合约时的参数:
合约安全之Mike&Sid事件分析
_guest时私有变量,无法直接访问,但我们可以通过getStorageAt方法获取相应slot上的值:
合约安全之Mike&Sid事件分析
合约安全之Mike&Sid事件分析

这个变量在Mike合约的4号slot上,可以发现这里储存的值就是攻击者地址。是合约部署者设置的后门地址。

回到increaseAllowance函数,当spender等于攻击者地址时,就会执行if-true中的逻辑。_minus会减少account的余额:
合约安全之Mike&Sid事件分析
但是total一直是0,所以实际上余额并没有减少。
之后调用_somma重新计算total:
合约安全之Mike&Sid事件分析
这个函数的作用是将输入的两个数相加,这里的total就变成了amount。最后再向spender增加amount数量的余额。
可以发现,当输入的spender是攻击者地址时,就能凭空给攻击者增加任意数量的代币。

more

实际上这两个项目都是为这一个人所有,都是貔貅盘,在7月2日开始,就有用户发现买入后无法卖出:
合约安全之Mike&Sid事件分析
合约安全之Mike&Sid事件分析
它是怎么做到的呢,重看合约源码,竟有意外收获!
在合约中有两个approve函数,一个首字母小写,一个首字母大写:
function approve(address spender, uint256 amount)function Approve(address spender, uint256 amount)
查看这个可疑的大写Approve:
合约安全之Mike&Sid事件分析

当调用者为后门地址时,会将spender加入到_dex表中。其他地方需要用到 _dex的在内部函数 _requireBalance中:

合约安全之Mike&Sid事件分析
当sender在 _dex表中的时候,会调用 _minus函数,会将sender的余额减去总供应量,所以这个函数一定会revert。 _transfer函数在一开始就调用了这个函数:
合约安全之Mike&Sid事件分析
而transfer、transferFrom函数都会使用这个函数来转账。所以只要被添加到黑名单中,就无法进行转账。
找一个调用Approve的交易https://etherscan.io/tx/0x9727f0e7cbfac6af493cacc9bfb8781b06fa0d45cba8927de7fef0438b1972b8
合约安全之Mike&Sid事件分析
调用者为后门地址,spender应该为受害者地址:
合约安全之Mike&Sid事件分析
该地址确实通过uinswap交易对购买过Mike代币:
合约安全之Mike&Sid事件分析
03
复现
https://github.com/wangbar0133/Mike-SId_poc
pragma solidity ^0.8.0;import "forge-std/Test.sol";import "forge-std/console.sol";import "./Mike.sol";contract ContractTest is Test {    address public victim = 0xeF7aA5930b2E92e7EF59BACfE18A0A3cb2105747;    address public backDoor = 0xF7E0d99511eab452bCBBdC34285E25F10E28F79D;    Mike public mike = Mike(0x8B99Bb8ddD8103CbEccC3b20C4B0038cA65A51AE);    function setUp() public {        uint256 forkId = vm.createFork("mainnet", 17608449);        vm.selectFork(forkId);    }    function testFail_Approve() public {        vm.prank(backDoor);        mike.Approve(victim, 1);        vm.prank(victim);        mike.transfer(address(0), 1);    }    function testFreeMint() public {        vm.prank(backDoor);        mike.increaseAllowance(backDoor, 1262000000000000000000000000000000);        assertEq(mike.balanceOf(backDoor), 1262000000000000000000000000000000);    }}
合约安全之Mike&Sid事件分析

在加入黑名单之后,只要进行转账操作就会发生revert。调用increaseAllowance后,后门地址获取到了足够的token。       

原文始发于微信公众号(SAINTSEC):合约安全之Mike&Sid事件分析

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年6月25日00:40:32
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   合约安全之Mike&Sid事件分析https://cn-sec.com/archives/4171963.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息