paint-brush
How to Solve the Ethernaut Game's Level 4: Telephoneby@kamilpolak
2,291 reads
2,291 reads

How to Solve the Ethernaut Game's Level 4: Telephone

by Kamil PolakJanuary 24th, 2022
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

In level 4 of the Ethernaut Game our goal is to claim ownership of the `Telephone` contract. In this game we use a simple contract with only one function and constructor that assigns the ownership to the address that deployed the contract. To claim the ownership we need to first understand what is the difference between `tx.origin` and `msg.sender` and why contracts that use the `txorigin` to authorize users are vulnerable to phishing attacks. We need to create a new malicious contract and encourage the owner to call a specific function that under the hood will change the ownership.

Coin Mentioned

Mention Thumbnail
featured image - How to Solve the Ethernaut Game's Level 4: Telephone
Kamil Polak HackerNoon profile picture


In level 4 of the Ethernaut Game our goal is to claim ownership of the Telephone contract.


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

contract Telephone {

  address public owner;

  constructor() public {
    owner = msg.sender;
  }

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


This is a simple contract with only one function and constructor that assigns the ownership to the address that deployed the contract.


Considering that we have only one function it is fairly easy to guess that need to focus on it if we want to win the game.


The changeOwner function takes as argument an address and verifies if (tx.origin != msg.sender).


To claim the ownership we need to first understand what is the difference between tx.origin and msg.sender and why contracts that use the tx.origin to authorize users are vulnerable to phishing attacks.


tx.origin:

  • the original user wallet that initiated the transaction
  • the origin address of potentially an entire chain of transactions and calls
  • only user wallet addresses can be the tx.origin, not contract address


msg.sender:

  • both user wallets and smart contracts can be the msg.sender
  • checks where the external function call directly came from

For more details, I encourage you to read my post about tx.origin Hack Solidity: Tx Origin Attacks


To hack the contract and claim ownership all we need to do is to create a new malicious contract and encourage the owner to call a specific function that under the hood will change the ownership. Let's think about that like a phishing attack.


Go to Remix IDE and paste a Telephone smart contract. Next, a open new file and create the following contract. Do not forget to import the Telephone contract.


Here we have a constructor that takes the Telephone's contract address. Next, we have a malicious function changeOwner that takes the address of the attacker and uses it to change the ownership of the Telephone contract.


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


import "./Telephone.sol";


contract Attack {

    Telephone telephone;


    constructor(address _address) public {
        telephone = Telephone(_address);
    }

    function changeOwner(address _address) public {
        telephone.changeOwner(_address);


    }


}


Before we deploy the contract let's first check the current Telephone's owner address.


Before you deploy the contract in Remix you need to change the environment to Injected Web3. Next, in the Deploy field put a Telephone contract address.



To check the address run the following command in the browser console.


Once you deploy the contract in the next step you can call the changeOwner function. As an argument put your MetaMask address.


When you call the function you should claim the ownership of the Telephone smart contract. To check that run the following command in the browser console.



As you can see the owner's address has changed, i.e. I claimed the ownership. Note, your wallet address is different, thus your output will differ from mine.


Also Published Here