本文介绍了跨函数重入漏洞,它指的是攻击者利用一个函数打开后门,然后在第一个函数完成之前,通过另一个函数进入。
智能合约应该是符合逻辑的。一个函数执行它的工作,另一个处理其他事情,它们和平共处。但是,如果两个函数秘密共享同一个金库,并且攻击者利用了它们的交互呢?
我的朋友,这就是 跨函数重入(Cross-Function Reentrancy)。
嗨,我是 0x00Auditor,你在 Solidity 黑暗小巷中的导游。在今天的剧集中,我们将研究当两个看起来无辜的函数以错误的方式组合时,如何变成武器。
这不是理论。真实的 DeFi 漏洞利用已经使用这种确切的技巧来耗尽数百万美元。所以让我们一步一步地分解它。
在你可能见过的经典重入中,一个函数重新进入自身(例如 withdraw()
在完成之前调用自身)。
但是跨函数重入更加隐蔽。攻击者不是让单个函数循环回到自身,而是使用 函数 A 打开大门,然后在第一个函数完成之前溜进 函数 B。
这就像魔术师用一只手分散你的注意力,而另一只手却在掏你的口袋。
想象一下这种情况:
deposit()
存储余额。withdraw()
偿还它们。balances[msg.sender]
)。如果一个函数更新状态太晚,攻击者可以_通过另一个函数_重新进入,该函数会触及相同的状态——导致双重支付或更糟。
这是造成混乱的秘诀:
跨函数的共享状态
两个函数都依赖于相同的变量(例如余额或 totalSupply)。
延迟更新
在外部调用之前未更新状态——留下一个“漏洞窗口”。
外部调用 = 攻击者控制
就像单函数重入一样,使用 .call()
或任何外部交互都会移交控制权。
函数不希望被混合
开发人员通常会想,“这个函数不能调用那个函数!” 但攻击者不按规则行事。他们将它们_链接_起来。
这是一个简单(且危险)的合约:
看起来还可以?不。withdraw()
和 emergencyWithdraw()
都会触及相同的余额状态——并且两者都会在更新之前发送 ETH。
以下是攻击者如何滥用它:
receive()
。receive()
内部,攻击者快速调用 emergencyWithdraw()
。基本上,一个函数设置舞台,另一个函数完成盗窃。
阻止这种情况不是靠记忆黑客行为,而是靠编码的纪律。
在进行任何外部调用之前更新你的状态。
withdraw()
(已修复):现在,即使攻击者重新进入,他们的余额也已经减少了。
ReentrancyGuard
在敏感函数上添加 nonReentrant
以防止任何嵌套调用。
那是 Solidity 的互斥锁——在其中一个函数运行时,没有函数可以偷偷溜回来。
如果两个函数依赖于相同的状态,请问自己:是否可以滥用其中一个来欺骗另一个?
有时候最简单的修复方法是合并函数或重构逻辑,以便它们不共享可利用的状态。
这不是假设。跨函数重入的变体已经出现在:
教训:如果你有多个通往同一个金库的门,攻击者会尝试所有这些门。
因为你可能想要作弊表:
1. 使用 Checks-Effects-Interactions。
2. 添加 ReentrancyGuard。
3. 不要让多个函数不安全地操作相同的状态。
如果跨函数重入是同一栋房子里的两扇门,那么 跨合约重入 则是两栋房子之间有一条秘密隧道。
为什么要在同一个合约中的 withdraw()
和 claimRewards()
之间来回跳转……当你可以完全在不同的合约之间进行乒乓球式的调用时?这正是攻击者在跨合约重入中所做的——通过受信任的邻居、流动性池或协议模块编织调用,直到他们解开整个系统。
在下一篇文章中,我们将探讨:
将其视为多人模式下的重入。🎮
敬请关注——因为如果你正在 DeFi 中构建,那么你的合约很可能不仅仅是在与自身对话。接下来是什么?
你现在已经遇到了单函数重入的更狡猾的表亲。
在下一章中,我们将再次升级:跨合约重入——当攻击者像弹球机一样在合约之间弹跳时。
在那之前,请保持你的锁紧,并比你的咖啡☕更早地更新你的状态。
保持安全,fren。👋
这就是 跨函数重入 的总结。
我们已经看到两个看起来无辜的函数如何成为犯罪伙伴,攻击者如何实际链接它们,以及使你的金库紧锁的防御措施。
寓意是什么?Solidity 不会原谅假设。始终在打开门之前更新你的状态,有纪律地保护你的函数,并像有人要破坏你一样进行测试——因为实际上,他们就是这样做的。
感谢你的一路阅读,fren。我希望这种分解能让你更加偏执(以好的、审计员的方式 😉)。
如果你想联系、交流笔记,或者只是讨论智能合约错误:
我总是乐于剖析漏洞利用、交流安全提示,或者谈论为什么 delegatecall
仍然让我夜不能寐。
保持好奇心,保持安全——我们将在下一集中再见,关于 跨合约重入。
- 原文链接: 0x00auditor.medium.com/c...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!