直白的后门——Mike&Sid事件分析

admin 2023年7月12日15:15:30评论91 views字数 2366阅读7分53秒阅读模式


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。


       

原文始发于微信公众号(山石网科安全技术研究院):直白的后门——Mike&Sid事件分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年7月12日15:15:30
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   直白的后门——Mike&Sid事件分析http://cn-sec.com/archives/1869345.html

发表评论

匿名网友 填写信息