目标是使我们的账户地址成为合约中的commander。
根据Foundry 官方文档配置好运行环境后,于本项目下执行下列命令:
$ cd WTF-CTF
$ forge test -C src/Ethernaut/HigherOrder -vvvvv
要想改变commander
变量,只能让treasury
变量大于255。而改变treasury
变量只能通过registerTreasury(uint8)
函数。
而registerTreasury函数
中在改变treasury
变量时,是直接读取了我们交易调用calldata的第4个字节后的32字节数据。然后将这32字节的数据写入了treasury
变量所在的插槽。(calldata的前4个字节为函数签名selector)
所以,我们只需调用registerTreasury函数
,并在calldata
的selector
后拼接treasury
变量的值(例如,修改为type(uint256).max
)
abi.encodeWithSignature("registerTreasury(uint8)", type(uint256).max)
虽然registerTreasury函数
接受的是uint8
的变量,但是,函数逻辑里却是使用calldataload
读取了32字节的数据。只需要calldata
前4个字节的selector正确 ,就可以调用registerTreasury函数
。