合约DOS
Excavation initiation!
今日讲讲入门漏洞– DOS
DOS概念就不多赘述了,大伙儿都熟得很
以一个游戏 KingOfEther 合约为例子,通过“王位争夺战”机制运作——每个用户需要支付比现任国王更多的以太币才能成为新的国王。但由于合约设计不当,攻击者可以利用这种机制将自己永远固定在 国王 位置,导致其他人无法挑战成功
示例合约
KingOfEther合约:
1 | contract KingOfEther { |
流程:
- 用户通过调用
claimThrone()并支付以太币,挑战成为新的国王 - 若支付的以太币大于当前国王支付的以太币,挑战成功,成为新国王
- 旧国王会被退还之前支付的金额
这里的设计是“push”模式,即新国王支付的以太币会直接推送给前任国王
问题来了:
如果上一任国王是个合约,而且没有收款功能呢
攻击合约
1 | contract Attack { |
攻击流程:
- 攻击者部署
Attack合约并传入KingOfEther合约的地址 - 攻击者调用
attack(),支付一定数量的以太币,成功成为新国王 - 由于
KingOfEther的设计问题——当新国王被设定时,系统会试图退还旧国王的以太币,但由于Attack合约没有fallback()函数来接收退款,退款会失败 - 结果,攻击者成为了国王,且没有
fallback()函数接收退款,其他任何人都无法成为新的国王,造成DOS
如何防御
我们可以将设计模式从 Push 改为 Pull,做一个账单记录每一任国王的balance,让国王自己“拉取”退款,而不是推送。这样可以避免攻击者通过拒绝接收以太币来造成 DOS
1 | contract KingOfEther { |
- Title: 合约DOS
- Author: Chiu
- Created at : 2025-04-21 21:50:52
- Updated at : 2025-07-15 13:01:46
- Link: https://github.com/Idealist17/github.io/2025/04/21/DOS/
- License: This work is licensed under CC BY-NC-SA 4.0.
Comments