漏洞利用即是披露:为何链上攻击比补丁传播更快

hexens 发布于 2026-07-18 阅读 22

本文介绍了Web3安全的新范式:将链上攻击自动转化为漏洞检测器,实时扫描其他合约。作者展示了其工具Glider Monitor在两周内从12起攻击中发现了198个存在相同漏洞的合约部署,涵盖9种漏洞类型。文章强调Web2的持续防御模式对Web3的重要性,并批评了单次审计的不足。

目录

Web2 已经解决了这个问题

大多数链上攻击规模很小,以至于没人注意。从某个被遗忘的合约中流失的几千美元,没有标题,没有事后分析,没有人发帖讨论。市场耸耸肩,继续前进。

但那个悄无声息的小盗窃背后的漏洞并不会被局限住。同样的错误通常还存在于其他未修补的合约中,迟早会有一个合约持有真正的资金。没人注意的小型攻击,正是那个最终人尽皆知的大型攻击的蓝图。

你使用的几乎所有网站都运行在类似 Cloudflare 这样的服务后面,全天候过滤攻击,绝大多数人甚至从未注意到它的存在。Web2 已经处理这个问题二十年了。当一种新攻击出现时,你不仅修补被攻击的那个盒子。你编写一个签名,推送出去,然后扫描整个系统寻找同样的漏洞。这方面的工具已经很成熟,甚至有点无聊:威胁情报馈送和全系统变体扫描。它之所以有效,原因只有一个:攻击会重复。

Web3 跳过了这一步。大多数协议在发布时只经过一次审计,然后就在公开状态下运行多年,无人触碰,而它们的代码却被复制了一百次。当其中一个最终被攻击时,所有运行类似代码的人都只能通过惨痛的方式发现。

我们认为这是可以修复的,而且不需要 Web2 还未发明出来的任何东西。那些在 Web2 中成为标准的安全工具在 Web3 中还没有被构建出来,所以这就是我们正在做的事情。Glider 是其中之一:可以将其视为 CodeQL,但针对 Solidity。它将已部署的合约代码转化为可以针对特定漏洞进行查询的内容。Glider Monitor 是另一个,也是这篇文章的主题。它是一个针对链上协议的防火墙。它监视实时攻击,并几乎实时地将每一次攻击自动转化为一个检测器。

为什么 Web3 更需要它

在链上,几乎所有因素都对攻击者有利。

代码是公开的,任何人都可以准确阅读协议的工作原理。一次攻击之后,有能力的攻击者已经在扫描生态系统的其余部分,寻找同样的漏洞。代码也是不可变的,因此通常没有热补丁;存在漏洞的逻辑就那样活生生地待在那里,直到资金离开。而且几乎没有驻留时间可言。Web2 中的一个漏洞是你可以用几周时间开发的立足点。而 DeFi 中的一个漏洞则是一次闪电贷和一个区块的时间。

这完全颠覆了披露模型。在 Web2 中,公开一个漏洞会引发一场修补竞赛。在 Web3 中,“披露”本身就是利用交易,它引发的是一场复制竞赛,通常是在防御者甚至还没有注意到之前。

Web2 vs Web3:公开漏洞引发什么,修补竞赛 vs 复制竞赛

每一次攻击都是一个模板

整个系统基于一个假设:公开的利用是一个免费、可用的概念证明。

已经有人完成了最昂贵的部分。他们发现了漏洞,并在链上用实际行动和真实资金证明了它的有效性。我们的工作是解读他们做了什么,弄清楚为什么它能工作,然后去发现所有其他地方它也能工作。因此,我们不是事后撰写攻击分析报告,而是将其转化为一个查询并执行它。

它是如何工作的

从利用到完整答案的时间线:10-15 分钟内检查合约,30 分钟内扫描 200 万合约

以下是从一次攻击落地那一刻开始的循环。

信号是即时的。Glider Monitor 位于链上活动的实时馈送上,因此触发点就是利用交易本身,它确认的那一刻,远早于任何披露或分析文章。

然后一个 Agent 对其进行拆解。我们向它提供原始的链上证据:完整的调用追踪、存储和余额变化、代币流动以及周围的调用上下文。从中,Agent 会找出哪里出了故障,精确到被违反的特定不变量。这个重建结果会变成一个 Glider 查询,精确定位漏洞的确切形态。

在典型的运行中,十分钟到十五分钟内,该查询已经针对你自己的合约执行完毕,并告诉你结果:要么匹配,要么不匹配。如果有匹配项,你会收到一个警报,指明函数名称并解释为什么它可被利用。如果没有匹配项,你仍然会收到反馈:你是安全的。无论哪种情况,你都会收到关于它所检查内容的判决。

大约半小时左右,同样的查询已经扫描了链上的其余部分:以太坊和 BSC 上大约两百万个近期合约(即最近一个月左右至少部署或被调用过一次的合约)。由此得出一个排名列表,显示所有其他携带该漏洞的合约。

困难的部分在于精确性。一个“寻找与攻击类似的代码”的朴素搜索会让你淹没在误报中,而一个对所有情况都触发的工具在一周内就会被静音。因此,大部分真正的工作发生在我们丢弃的内容中。我们剔除那些共享形态但不具备可利用路径的候选,并且故意为你提高警报的门槛。我们宁愿什么都不说,也不愿让你去追逐一个根本不存在的漏洞。

几周内我们发现的东西

12 次攻击事件输入,198 个确认存在漏洞的部署输出,在以太坊和 BSC 上

我们运行了几周。输入了 12 次实时攻击事件。输出了 198 个确认存在漏洞的部署:真实的合约,活在以太坊和 BSC 上,每一个都携带一个我们已经看到在其他地方被利用过的漏洞。它们跨越 80 个不同的代码库和 9 个漏洞类别,因此平均每种易受攻击的模式同时存在于两三个地方。

关于“确认”一词需要说明一下,因为它承担了大量工作。这里的每一个都意味着系统读取了合约自身的代码,并从头到尾追踪了路径:入口点、攻击者控制的输入、转移价值的接收端、以及本应阻止它但实际不存在的防护。那些“疑似”项不包含在这个数字里。

按漏洞类别划分的 198 个确认存在漏洞的部署,主要由从交易对燃烧和收费转账导致

类别 如何抽走资金 什么使其可被利用 确认数量
从交易对燃烧 + sync() 单边燃烧交易对自己余额,然后 sync() 强制储备变为燃烧后余额,并移动现货价格,以便夹心买卖 燃烧触发是无许可的 116
收费转账,接收方扣款 从接收方或交易对本身扣除转账税,因此卖出到交易对会导致移除的比存入的多,使储备崩溃 税收路径是无许可的且击中交易对,而不是发送方 51
未认证的交换/闪电回调 交换或闪电回调将价值转移给任何调用者,不检查调用者是否是真正的池子,因此任何人都可以耗尽合约余额 调用者被隐式信任,或者调用者检查能被攻击者用他们部署的合约满足 14
现货价格预言机(杠杆) 基于原始 DEX 现货价格开杠杆头寸,然后自毁现货,以被操纵的价格结算 没有 TWAP 或外部预言机;头寸价值直接从可操纵的现货读取 6
现货价格预言机(奖励/铸造) 闪电膨胀一个实时储备读数,凭空铸造或贷记,然后倾销 现货读取没有 TWAP 或偏差保护 5
幽灵访问控制 声明了授权检查但从未在路径上执行,因此资金转移器(或 rollup 的提现路径)对任何人开放 白名单或提供者检查被编写但从未在价值移动前读取 3
单边加入/退出不守恒 单边加入和退出通过线性近似定价,因此一次往返返回的比投入的多 没有权重指数或适当的不变量;铸造和赎回价格不匹配 1
未受保护的初始化器 通过无守卫的初始化器夺取所有权,然后使用仅所有者的提现功能 价值接收端位于你刚刚夺取的角色后面 1
Gas 回扣超额支付 守护者向调用者支付 (gas + buffer) × gasprice 且无上限;循环直到储备耗尽 奖励超过调用者的实际成本 1

如果你部署合约,这与你有关

你不必分叉了一个被攻击的合约才处于暴露之中。你只需要犯下同样的错误,而达到这种地步的方式有很多种:复制粘贴、“受启发”的重写,或者两个团队独立编写了相同的漏洞。易受攻击的形态不在乎这些。

因此,当你从未听说过的协议被抽干时,“那是我的代码吗?”是错误的问题。真正的问题是“我的代码做了同样的事吗?”如果是,那么它现在就是活生生的、暴露的,而那些刚刚套现的人已经知道这个模式了。每一次公开攻击都应该悄然触发对每个运行同样形态的合约进行检查,在复制者到达之前。

我们没有告诉你的事情

一些说明,因为没有这些说明的安全文章就只是营销。

我们不会点名目标,也不会标注处于风险中的金额。这里的一切都是汇总的计数和类别,是有意为之。点名一个仍然存在漏洞的活合约,或者公布其中有多少资金,只是在给攻击者提供购物清单。种子攻击事件在发生时就已经是公开的;那些仍然持有资金的合约不会出现在页面上。

这些是早期数字:12 次事件,几周时间,我们监控的链的一部分。

还有一件让我们夜不能寐的事情:不浪费你的注意力。因此我们强烈地偏向另一个方向。一个发现必须经过真正的审查才能进入你的信息流,我们宁愿放弃一个边缘案例,也不愿拿你的注意力去赌博。

安全在成长

我们认为 Web3 正朝着与 Web2 相同的方式发展:从发布时的一次性审计转向持续防御。资金规模更大,代码被复制得比以往更多,而一年一次的检查永远跟不上。

这就是我们在 Hexens 所构建的。Glider Monitor 是这一理念的防火墙实现,而这篇文章只是它运行了几周的结果。

如果你也希望你的合约得到保护,在这里联系我们

  • 原文链接: hexens.io/blog/the-explo...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~

相关文章

0 条评论