Gatekeeper Three 题目描述 原题 in Sepolia Gatekeeper Three,我是你的破壁人。 运行 根据Foundry 官方文档配置好运行环境后,于本项目下执行下列命令: 功能简述 对于gateOne,需要使用攻击合约调用 合约,并且这个攻击合约地址还要是 合约的 。 合约在设置 时,将构造函数 错误地写为了 。所以攻击合约需要调用一次 函数,成为 。 对于gateTwo,需要将 合约的 变量从 转为 。 变量只能在 函数中调用 合约的 函数成功返回 时,才能修改为 。而 合约的 函数需要判断传入的 是否与合约存储的私有变量 相同。可链上没有私有数据。 通过读取 合约内存插槽 中存储的值,即可知道 。
Gatekeeper Three,我是你的破壁人。
根据Foundry 官方文档配置好运行环境后,于本项目下执行下列命令:
$ cd WTF-CTF $ forge test -C src/Ethernaut/Gatekeeper_Three -vvvvv
对于gateOne,需要使用攻击合约调用GatekeeperThree合约,并且这个攻击合约地址还要是GatekeeperThree合约的owner。
GatekeeperThree合约在设置owner时,将构造函数constructor错误地写为了construct0r。所以攻击合约需要调用一次construct0r函数,成为owner。
GatekeeperThree(payable(gatekeeperThree)).construct0r();
对于gateTwo,需要将GatekeeperThree合约的allow_enterance变量从false转为true。
allow_enterance变量只能在getAllowance函数中调用trick合约的checkPassword函数成功返回true时,才能修改为true。而trick合约的checkPassword函数需要判断传入的_password是否与合约存储的私有变量password相同。可链上没有私有数据。
通过读取trick合约内存插槽slot2中存储的值,即可知道password。
uint256 _password = uint256(vm.load(address(GatekeeperThree(payable(gatekeeperThree)).trick()), bytes32(uint256(2))));
对于gateThree,需要给GatekeeperThree合约转大于0.001 ether,并且我们的攻击合约在接收ETH时需要失败。
在调用GatekeeperThree合约的同时转移大于0.001 ether,并且在攻击合约的receive 函数中无脑revert就好。
receive() external payable { revert(); }