两个简单区块链漏洞复现

发布于 2024-03-06  119 次阅读






两个区块链漏洞复现

[TOC]

20210622 Eleven Finance 分析

Contract

function emergencyBurn() public {  //vulnerable point
        uint balan = balanceOf(msg.sender);
        uint avai = available();
        if(avai<balan) IMasterMind(mastermind).withdraw(nrvPid, (balan.sub(avai)));
        token.safeTransfer(msg.sender, balan);
        emit Withdrawn(msg.sender, balan, block.number);
    }

调用者在合约中的余额赋值给balan变量,并给调用者进行了转账,但并未对调用者余额balanceOf(msg.sender)数量进行销毁,所以攻击者第一次取走代币后,emergencyBurn方法并未销毁攻击者原本的余额,导致攻击者余额并没有减少,之后攻击者又利用本身余额进行了第二次取款。

Testing

forge test --contracts ./src/test/Eleven.sol -vv

e21f88716d1066d2b48e3ef657e833eb

 

20221021 OlympusDAO分析

Contract

/// @inheritdoc IBondFixedExpiryTeller
    function redeem(ERC20BondToken token_, uint256 amount_) external override nonReentrant {//vulnerable point, insufficient validation
        if (uint48(block.timestamp) < token_.expiry())
            revert Teller_TokenNotMatured(token_.expiry());
        token_.burn(msg.sender, amount_);
        token_.underlying().transfer(msg.sender, amount_); //vulnerable point, custom contract return OHM.
    }

public和private

  • public修饰的变量和函数,任何用户或者合约都能调用和访问。
  • private修饰的变量和函数,只能在其所在的合约中调用和访问,即使是其子合约也没有权限访问。

external和internal

除 public 和 private 属性之外,Solidity 还使用了另外两个描述函数可见性的修饰词:internal(内部) 和 external(外部)

  • internal 和 private 类似,不过, 如果某个合约继承自其父合约,这个合约即可以访问父合约中定义的“内部”函数。
  • external 与public 类似,只不过这些函数只能在合约之外调用 - 它们不能被合约内的其他函数调用。

internal、private、external、public这4种关键字都是可见性修饰符,互不共存

这个漏洞函数权限为 external ,攻击者只需要先部署合约设置函数 expiry()、burn()、underlying(),使得满足程序运行条件。而token_.underlying() 返回的值是可控的,攻击者直接将其设置为自己的OHM 合约的地址,直接将代币转移。

Testing

forge test --contracts ./src/test/OlympusDao.exp.sol -vvv

31cf6ef3c8e4c552faeaa19e02d58046

 

 


最后更新于 2024-03-06