Skip to content

Latest commit

 

History

History
33 lines (18 loc) · 2.77 KB

README.md

File metadata and controls

33 lines (18 loc) · 2.77 KB

Puzzle Wallet

题目描述

原题 in Sepolia

获取PuzzleProxy的admin权限

运行

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

$ cd WTF-CTF

$ forge test -C src/Ethernaut/Puzzle_Wallet -vvvvv

功能简述

项目采用可升级架构,使用代理调整来实现附加的功能。PuzzleWallet合约中的函数调用,都通过PuzzleProxy合约fallbackreceive函数进行了代理调用。

因为是代理调用,每次调用函数(call)所使用的调用量变化量都是PuzzleProxy合约插槽中的数据。PuzzleProxy合约插槽0中有pendingAdmin(地址占20字节)变量。目标是让我们的账户地址成为PuzzleProxy合约的admin。也就是说要修改PuzzleProxy合约插槽1中的数据。

PuzzleProxy合约中可以修改插槽1中的数据的操作,有constructor构造函数和approveNewAdmin函数,构造函数不能重新使用。approveNewAdmin函数只能账户admin才能调整使用。

PuzzleWallet合约中有可以改变插槽1中的数据的操作(即改变maxBalance改变量(uint256占32位)的值)。有构造函数和setMaxBalance函数,构造参数不能重新使用。setMaxBalance两个限制,一个是合约地址的ETH余额为0,另外一个是调用地址是白名单用户。

  1. PuzzleProxy合约ETH余额变为0。初始状态下PuzzleProxy合约下有0.001个ETH。合约中可以转移ETH操作只有execute函数。而execute函数提取ETH时要求我们在合约中的余额大于等于本次提取的余额。但合约提供了函数multicall,允许我们可以一次笔交易调用多次,在多次调使用中的msg.value是不变的,从而可以达到只转一次钱,但合约中我们的余额增加多次。重入攻击。但multicall函数中不允许我们多次调用deposit函数,可multicall函数并没有限制多次使用multicall函数进行重入。多次调用multicall函数从达到多次调用deposit函数的效果。然后调用execute函数将合约中所有eth提走。
  2. 让我们的账号成为白名单用户。只能通过addToWhitelist函数,但这个函数只能由owner账号地址调用。owner变量存储在插槽0中,可以通过PuzzleProxy合约的proposeNewAdmin函数,让我们的账户地址存储在插槽0中,插槽0中的数据在PuzzleProxy合约中是pendingAdmin变量,在PuzzleWallet合约中是owner变量。从而我们的账户地址就变成了PuzzleWallet合约的owner。可以调用addToWhitelist函数。

使用代理合约时,必须注意不要引入存储冲突,如本关卡所示。