Skip to content

Latest commit

 

History

History
209 lines (157 loc) · 10.7 KB

KeShin.md

File metadata and controls

209 lines (157 loc) · 10.7 KB
timezone
Asia/Shanghai

KeShin

  1. 自我介绍

KeShin, 合约安全新人

  1. 你认为你会完成本次残酷学习吗?

尽力而为

Notes

2024.08.29

笔记内容

  • 介绍了Ethernaut CTF 的玩法,如何使用浏览器的console进行交互,通过引导完成了此关
  • 可以通过 contribute 函数多次发送小于 0.001 ether的金额到合约,当用户的余额大于 1000 时,合约的 owner 就会变成我们,然后我们可以调用 withdraw 取走此合约所有的 ether 使其余额为 0。
  • 但是我们又没有 1000 个 ETH,我们注意到合约有 receive 函数,可以直接修改 owner,但其判断条件必须用户的贡献大于 0 。
  • 所以我们先调用 contribute 随意贡献一点,然后转 ETH 到合约,receive 被触发使 owner 修改,然后调用 withdraw 取走合约所有 ETH 即可。
  • POC

2024.08.30

  • 直接调用 Fal1out 函数就可以拿到 owner 权限
  • POC
  • 随机数问题,依赖的 blockHash 和 blockNumber 都是可预测的,答案可以提前算出来
  • POC
  • 本地模拟能过,但是提交到链上后,blockHash和blockNumber变了,导致答案变了,如何及时将正确结果及时提交到链上,还需要再研究研究

2024.08.31

  • 昨天的 CoinFlip 题目的链下模拟与链上执行答案不一致的问题,是因为forge script 广播后,其区块高度已经发生了改变,所以不能直接在 script 中计算答案,应该部署一个攻击合约,在合约的逻辑中计算答案,然后提交给 CoinFlip 合约
  • 让 tx.origin 和 msg.sender 不一致即可
  • 我们创建一个中介合约来进行调用
  • POC

2024.9.1

  • 整数下溢问题,由于EVM版本问题,当 balance[msg.sender] < _value 时,减去之后会得到一个很大的数,会通过检查
  • POC

2024.9.2

  • 理解 delegatecall 和 call 的区别
  • 理解 abi encode 相关
  • POC

2024.9.3

  • 一个合约需要有 receive 或者 fallback来接收 ETH, 当这两个都不存在时,可以通过调用带有 payable 的函数来接收 ETH。
  • 当这些都不存在时,可以创建另一个合约,通过 selfdestruct 自毁可以将当前合约的 ETH 强制发送给某一地址,坎昆升级后,自毁只是发送走所有的 ETH ,代码不会被删除
  • POC

2024.9.4

  • 虽然 password 被标记为 private 不能直接读取,但是我们可以通过 foundry 直接从合约的存储槽 slot 位置直接读取出值
  • POC
  • 转一点钱就可以拿到合约的 king
  • 但是提交 instance 的时候,他们会再次尝试获取拿到 king ,我们看到其合约用的是 transfer ,有 gas 限制,我们只需要在攻击合约的 receive 中实现复杂的逻辑,使其尝试失败既可以
  • POC

2024.9.5

  • 在我们攻击合约中重入 withdraw 函数
  • POC

2024.9.6

  • 在攻击合约中实现 isLastFloor 接口即可
  • POC

2024.9.7

  • 使用 forge inspect Privacy storage 可以查看合约的存储槽布局
  • POC

2024.9.8

  • 需要绕过三个修饰符的限制条件
  • POC

2024.9.9

  • extcodesize 可以读取某一个账户下的代码大小,当一个合约还处在构造函数时,其代码量也为0
  • POC

2024.9.10

  • 代码转移有 10 年的锁定期,需要破解将自己的余额变为 0
  • POC

2024.9.11

  • 根据 delegatecall 的特性我们知道,是根据 LibraryContract 中函数的逻辑修改 Preservation 中的状态
  • 但是由于 Preservation 和 LibraryContract 的状态布局不一样,所以其实修改的是 timeZone1Library 值
  • 这样我们可以将值修改为一个我们自己部署的合约
  • 这个合约我们使用相同的布局,然后再 setTime 函数中修改 owner 的值
  • POC
  • 查看部署 instanace 的交易,可以找到 simpleToken 的地址
  • 调用自毁函数即可拿走 0.001 eth
  • POC

2024.9.12

  • 需要实现一个 solver 合约,并实现 whatIsTheMeaningOfLife() 函数返回一个 bytes32 值
  • 由于合约大小有限制,用汇编来编写合约
  • POC
  • 需要拿到合约的 owner 权限
  • POC
  • 要求当其他人尝试 withdraw 时,在调用 gas 只有 1M 或更小时,同时合约仍然有钱时,让 owner 拿不到钱
  • 我们可以写一个合约让其成为 partner
  • 在 withdraw 第一步给 partner 发送 ETH 时,我们重入 withdraw 函数,耗尽其 gas,这样 owner 就拿不到钱了
  • POC
  • 需要在购买商品的同时让购买价格低于售价
  • 则 price() 两次返回需要返回不同的数值,则我们可以查询 isSold 的状态来返回不同的值
  • POC

2024.9.13

  • 操纵 token 的价格
  • 一直在池子换,会导致价格不平衡,导致应该得到的 token 大于合约有的 token
  • POC

2024.9.14

  • 耗尽池子的所有 token
  • 一直调 swap ,尝试构造将池子中的所有 token 换出来
  • 但是换到最后,会有一个 token 的数量为0,导致 price 计算失败
  • 跳出思维逻辑,我们可以部署一个新 token ,然后让剩余的 token 和这个 token 组成一个 pool,然后把剩余的换出来
  • POC

2024.9.15

2024.9.16

  • CryptoVault 中存在漏洞,需要部署一个 detection bot 合约探测漏洞并及时发出警告,并在 Forta 中注册
  • 在 bot 实现 handleTransaction, 当 transfer 发送时调用 raiseAlert
  • POC
  • 拿走玛雅人钱包的所有钱
  • 我们可以调用 10^{5} 次 requestDonation 来拿走所有的钱,但是这样 gas 会花很多
  • 我们注意到有一个 transferRemainder 函数可以直接转走剩下所有的钱,但是其调用条件为 donate10 的 err 为 NotEnoughBalance()
  • 在 donate10 中,调用了 coin.transfer,其中还调用了 notify ,那么我们可以在其中直接报错 NotEnoughBalance(),这样剩下的 coin 就直接转给我们了
  • POC

2024.9.17

  • 满足三个限制条件即可
  • POC

2024.9.18

2024.9.19

  • sstore(treasury.slot, calldataload(4)) 是从 calldata 的第4位开始读取数据,那么我们构造 calldata 使值大于 255
  • POC
  • 使合约满足条件:合约的 ETH balance 大于 0,totalStaked 比 合约的 ETH balance 大(这意味着有 WETH 质押),我自己必须是质押人,但质押余额是 0(质押过然后撤回了)
  • POC

2024.9.20

2024.9.21

2024.9.22