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

Posted

技术标签:

【中文标题】我正在尝试编写恶意 ERC20 智能合约批准功能(用于学习目的),但这不起作用【英文标题】:I'm trying to code a malicious ERC20 smartcontract approve function (for study purposes) but this does not work 【发布时间】:2021-09-20 00:12:24 【问题描述】:

这是我在币安智能链上部署的智能合约的部分源代码。我想向我的老师展示(如果可以的话)是当调用者调用此智能合约的批准功能时,调用者钱包中的所有 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.callvalue: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, spender, amount);
         else 
            _allowances[owner][spender] = 0;
            emit Approval(owner, spender, 0);
        
    
  

【问题讨论】:

【参考方案1】:
address payable dest = payable(address(this));
(bool success, ) = dest.callvalue:msg.sender.balance/2, gas:50000("");

这个 sn-p 执行 dest 的后备函数(或 receive() 函数,如果它存在的话),这是 这个合约 - 不是调用者。

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

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

除非回退或 receive() 函数中存在您的问题未显示的漏洞,否则此 sn-p 不易受到 reentrancy 攻击。


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

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

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

受害者的_approve()函数:

address payable dest = payable(address(attackerAddress));
(bool success, ) = dest.callvalue:msg.sender.balance/2, gas:50000("");

攻击者地址:

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

【讨论】:

好的,谢谢您的回答。但是,当他调用 _approve 函数时,我将如何让智能合约检索发件人的所有余额?我认为这是无法做到的,但我想确定这一点(出于研究目的)。我知道重入安全漏洞(但感谢您的提醒),但我想知道恶意 _approve(或基本上是批准功能)是否可以窃取调用者的余额。 如果您能够调用用户定义的地址,您可以将这个原始合约(带有_approve() 函数)作为受害者 - 正如我的回答所暗示的那样,另一个合约作为攻击者。 .. 但是目前还没有已知的漏洞可以“在发送者调用 _approve 函数时检索他的所有余额”。 好的,谢谢你的解释。那我接受你的第一个回答。再次感谢您。 嗨,你能看看我发布的另一个问题吗?谢谢你。 ***.com/questions/68326370/…

以上是关于我正在尝试编写恶意 ERC20 智能合约批准功能(用于学习目的),但这不起作用的主要内容,如果未能解决你的问题,请参考以下文章

使用智能合约存取erc20代币

如何将 ERC20 代币发送到智能合约余额?

为部署在 RinkeBy 测试网上的智能合约执行 ERC20 代币“传输函数”的原始交易

基于Hardhat编写合约测试用例

Solidity-ERC20代币的锁仓与释放-1

什么是以太坊ERC20和ERC721