Skip to content

Poor4ever/Some-defivuln-exp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

KashiPairMediumRiskV1

漏洞原因

调用 borrow() 借款时,使用的是未从预言机获取新的值,而是过时 exchangeRate 值, 而调用 liquidate() 清算时会从预言机获取新的 exchangeRate 值, 计算产生巨大的价格差异,从中获利.

KashiPairMediumRiskV1_POC_RunResult

POC 复现漏洞

KashiPairMediumRiskV1-exp.sol

forge test --contracts "./src/KashiPairMediumRiskV1-exp.sol" -vvv

相关链接:

https://twitter.com/BlockSecTeam/status/1603633067876155393

anyswapRouterV4

anyswap 已更名为 Multichain

漏洞原因

anyswapRouterV4::anySwapOutUnderlyingWithPermit()

查看 anyswapRouterV4.sol 完整代码

首先对传入的 Token 地址没有校验, 攻击者恶意部署的返回受影响的 Token 核心利用点是 token 不存在 permit() 函数而被调用, 但是存在 fallback , 交给 fallback 处理, 随意传入的 v r s 无从校验,交易不会失败, 而受影响的是前端默认 approve 最大可用数量代币给合约,而不是按需授权数量的授权的用户.

    function anySwapOutUnderlyingWithPermit(
        address from,
        address token,
        address to,
        uint amount,
        uint deadline,
        uint8 v,
        bytes32 r,
        bytes32 s,
        uint toChainID
    ) external {
        address _underlying = AnyswapV1ERC20(token).underlying();
        IERC20(_underlying).permit(from, address(this), amount, deadline, v, r, s);
        TransferHelper.safeTransferFrom(_underlying, from, token, amount);
        AnyswapV1ERC20(token).depositVault(amount, from);
        _anySwapOut(from, token, to, amount, toChainID);
    }

因为授权过多代币数量给 anyswapRouterV4 而受影响的代币, 包括最近被利用的 NUM,以及 WETH, WBNB 等, 不存在 permit() 函数但是存在 fallback的代币.

POC 复现漏洞

以 WETH 为例子:

anyswapRouterV4-exp.sol

forge test --contracts "./src/anyswapRouterV4-exp.sol" -vvv

相关链接:

https://medium.com/zengo/without-permit-multichains-exploit-explained-8417e8c1639b

https://blog.neptunemutual.com/taking-a-closer-look-at-the-numbers-protocol-hack/

ULME

漏洞原因

ULME Token::buyMiner() public 函数, 可恶意用授权 USDT 的地址, 去兑换 ULME 代币.

攻击步骤:

(1)闪电贷借入 USDT

(2) USDT 兑换成 ULME

(3) 调用 ULME Token contract::buyMiner(), 传入事先收集的授权 USDT 给 ULME Token 合约的地址列表,去购买 ULME 代币,拉高币价

(4) 出售 ULME 获利

    function buyMiner(address user,uint256 usdt)public returns (bool){
        address[]memory token=new address[](2);
        token[0]=_usdt_token;
        token[1]=address(this);
        usdt=usdt.add(usdt.div(10));
        require(IERC20(_usdt_token).transferFrom(user,address(this),usdt), "buyUlm: transferFrom to ulm error");
        uint256 time=sale_date;
        sale_date=0;
        address k=0x25812c28CBC971F7079879a62AaCBC93936784A2;
        IUniswapV2Router01(_roter).swapExactTokensForTokens(usdt,1000000,token,k,block.timestamp+60);
        IUniswapV2Router01(k).transfer(address(this),address(this),IERC20(address(this)).balanceOf(k));
        sale_date=time;
        return true;
    }
}

POC 复现漏洞

ULME-exp.sol

forge test --contracts "./src/ULME-exp.sol" -vvv

攻击获利: ~ 50,646 BUSD

attack_tx: https://etherscan.io/tx/0xdb9a13bc970b97824e082782e838bdff0b76b30d268f1d66aac507f1d43ff4ed

相关链接:
https://twitter.com/blocksecteam/status/1584839309781135361
https://twitter.com/BeosinAlert/status/1584888021299916801

OlympusDAO

漏洞原因

BondFixedExpiryTeller::redeem() 函数对传入的 token_ 没有校验, 传入攻击者自己部署的地址, 函数内的 expiry()/burn() 函数都走攻击者恶意构造的逻辑保证正常执行,而 underlying() 返回 OHM 地址进行 transfer().

    function redeem(ERC20BondToken token_, uint256 amount_) external override nonReentrant {
        if (uint48(block.timestamp) < token_.expiry())
            revert Teller_TokenNotMatured(token_.expiry());
        token_.burn(msg.sender, amount_);
        token_.underlying().transfer(msg.sender, amount_);
    }

POC 复现漏洞

OlympusDAO-exp.sol

forge test --contracts "./src/OlympusDAO-exp.sol" -vvv

攻击获利: ~ 30,437 OHM

attack_tx: https://etherscan.io/tx/0x3ed75df83d907412af874b7998d911fdf990704da87c2b1a8cf95ca5d21504cf

相关链接:
https://twitter.com/Supremacy_CA/status/158342502609464115
https://twitter.com/peckshield/status/1583416829237526528

HEALTH

漏洞原因

每次 transfer() 转账都会燃烧池子里 0.1% 的 HEALTH Token,多次调用 transfer() 消耗池子里的 HEALTH Token,最后再交换消耗前闪电贷借入WBNB 换的 HEALTH Token,售出为 WBNB 获利.

    function _transfer(address from, address to, uint256 value) private {
        //..
        uint256 burnValue = _balances[uniswapV2Pair].mul(burnFee).div(1000);
        _balances[uniswapV2Pair] = _balances[uniswapV2Pair].sub(burnValue);
        _balances[_burnAddress] = _balances[_burnAddress].add(burnValue);
        //..
    }

POC 复现漏洞

HEALTH-exp.sol

forge test --contracts "./src/HEALTH-exp.sol" -vvv

攻击获利: ~ 16 WBNB

attack_tx: https://bscscan.com/tx/0xae8ca9dc8258ae32899fe641985739c3fa53ab1f603973ac74b424e165c66ccf

相关链接:

https://twitter.com/BlockSecTeam/status/1583073442433495040

Temple DAO

漏洞原因

StaxLPStaking 合约 migrateStake() 函数 (1)没有访问控制,任意 EOA 账户或合约可以随意调用,(2) 函数 oldStaking 可以任意传参,传入自己恶意部署的合约地址,凭空获得 LP Token.

    function migrateStake(address oldStaking, uint256 amount) external {
        StaxLPStaking(oldStaking).migrateWithdraw(msg.sender, amount);
        _applyStake(msg.sender, amount);
    }

POC 复现漏洞

templedao-exp.sol

forge test --contracts "./src/templedao-exp.sol -vvv

攻击获利: ~ 2 M USDC

attack_tx: https://etherscan.io/tx/0x8c3f442fc6d640a6ff3ea0b12be64f1d4609ea94edd2966f42c01cd9bdcf04b5

Remove liquidity and sale_tx: https://etherscan.io/tx/0x4b119a4f4ba1ad483e9851973719f310527b43f3fcc827b6d52db9f4c1ddb6a2

Arbitrage contract

漏洞原因

套利合约闪电贷回调函数 pancakeCall 没有限制仅 Pair 合约可调用.

POC 复现漏洞

arbitrage_contract-exp.sol

forge test --contracts "./src/arbitrage_contract-exp.sol" -vvv

攻击获利: ~ 25912 USDT / ~ 327 WBNB / ~ 5160 BUSD / ~ 0.014 BTCB / ~ 0.097 ETH

attack_tx: https://bscscan.com/tx/0xd48758ef48d113b78a09f7b8c7cd663ad79e9965852e872fdfc92234c3e598d2

ShadowFi

漏洞原因

burn() 函数允许任何人调用燃烧任意地址的代币,导致 LP Pair 合约 $SDT代币被恶意消耗完,用小部分 $SDT 代币就可以掏空池子里的 WBNB.

    function burn(address account, uint256 _amount) public {
        _transferFrom(account, DEAD, _amount);

        emit burnTokens(account, _amount);
    }

POC 复现漏洞

shadowfi-exp.sol

forge test --contracts "./src/shadowfi.sol" -vvv

攻击获利: ~ 1078 WBNB

attack_tx:https://bscscan.com/tx/0xe30dc75253eecec3377e03c532aa41bae1c26909bc8618f21fb83d4330a01018

luckytiger

漏洞原因

糟糕的随机源取自链上, 遇到不想要的结果让交易回滚

    function publicMint() public payable {
        uint256 supply = totalSupply();
        require(!pauseMint, "Pause mint");
        require(msg.value >= price, "Ether sent is not correct");
        require(supply + 1 <= maxTotal, "Exceeds maximum supply");
        _safeMint(msg.sender, 1);
        bool randLucky = _getRandom();
        uint256 tokenId = _totalMinted();
        emit NEWLucky(tokenId, randLucky);
        tokenId_luckys[tokenId] = lucky;
        if(tokenId_luckys[tokenId] == true){
        require(payable(msg.sender).send((price * 190) / 100));
        require(payable(withdrawAddress).send((price * 10) / 100));}
    }
    
    function _getRandom() private returns(bool) {
        uint256 random = uint256(keccak256(abi.encodePacked(block.difficulty, block.timestamp)));
        uint256 rand = random%2;
        if(rand == 0){return lucky = false;}
        else         {return lucky = true;}
    }

POC 复现漏洞

luckytiger-exp.sol

forge test --contracts "./src/luckytiger-exp.sol.sol" -vvv

攻击获利: 忽略不计

attack_tx: https://etherscan.io/tx/0x804ff3801542bff435a5d733f4d8a93a535d73d0de0f843fd979756a7eab26af

QIXI

漏洞原因

Solidity 0.8 版本以下没有溢出检测,从 QIXI -BNB LP 池子闪电贷借空池子里 BNB,QIXI Token 存在溢出, _Transfer 没有对转账的发送钱包余额检查,任意调用转账时在 _basicTransfer 里下溢获得大量 QIXI Token,闪电贷回调里转 QIXI Token 到 LP 池子,满足 K 值检查,不用偿还 BNB.

     function _basicTransfer(address sender, address recipient, uint256 value) internal returns (bool) {
        balanceOf[sender] -= value;
        balanceOf[recipient] += value;
        emit Transfer(sender, recipient, value);
        return true;
    }

POC 复现漏洞

QIXI-exp.sol

forge test --contracts "./src/QIXI-exp.sol" -vvv

攻击获利: ~ 6 WBNB

attack_tx: https://bscscan.com/tx/0x16be4fe1c8fcab578fcb999cbc40885ba0d4ba9f3782a67bd215fb56dc579062

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages