Ethernaut - 18. Magic Number
18 Sep 2022ethernaut
solidity
Difficulty: 🌕🌕🌕🌑🌑
To solve this level, you only need to provide the Ethernaut with a
Solver
, a contract that responds towhatIsTheMeaningOfLife()
with the right number.
Easy right? Well… there’s a catch.
The solver’s code needs to be really tiny. Really reaaaaaallly tiny. Like freakin’ really really itty-bitty tiny: 10 opcodes at most.
Hint: Perhaps its time to leave the comfort of the Solidity compiler momentarily, and build this one by hand O_o. That’s right: Raw EVM bytecode.
Good luck!
Contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
contract MagicNum {
address public solver;
constructor() public {}
function setSolver(address _solver) public {
solver = _solver;
}
/*
____________/\\\_______/\\\\\\\\\_____
__________/\\\\\_____/\\\///////\\\___
________/\\\/\\\____\///______\//\\\__
______/\\\/\/\\\______________/\\\/___
____/\\\/__\/\\\___________/\\\//_____
__/\\\\\\\\\\\\\\\\_____/\\\//________
_\///////////\\\//____/\\\/___________
___________\/\\\_____/\\\\\\\\\\\\\\\_
___________\///_____\///////////////__
*/
}
Writeup
- Get new instance.
- Create a new contract
// SPDX-License-Identifier: MIT pragma solidity ^0.6.0; contract MagicNumberCracker{ constructor() public{ assembly{ mstore(0x00, 0x602a60005260206000f3) return(0x16, 0x0a) } } }
How
0x602a60005260206000f3
come from ?- PUSH(0x2a) –> 0x602a (Push 42 onto the stack)
- PUSH(0x00) –> 0x6000 (Push memory slot 00 to stack)
- MSTORE –> 0x52 (Store 42 to memory slot 00)
- PUSH(0x20) –> 0x6020 (Memory slot size is 32 bytes)
- PUSH(0x80) –> 0x6000 (Value is stored at moemory slot 00)
- RETURN –> 0xf3 (Return value which is stored at memory 00 with sizeof 32 bytes)
- Compile and Deploy.
- Set Solver :
await contract.setSolver('MAGICNUMBERCRACKER_CONTRACT_ADDRESS')
- Submit instance ξ( ✿>◡❛)