图文攻略

Wormhole 跨链桥被盗:凭空铸出 3.25 亿美元

2022 年初,Solana 生态里最值钱的一行代码,藏在 Wormhole 跨链桥的签名校验里。2 月 2 日,它无声地失效了:攻击者让桥相信一笔从未发生的存款已经到账,凭空铸出 12 万枚 wETH——时值约 3.25 亿美元。本页用 15 张图讲完全程:桥的信任模型是怎么搭的、到底哪一步校验被绕过、攻击如何在代码里逐行复现,以及那笔让所有用户全身而退的兜底资金。

10 分钟 • 15 个图解步骤 • 签名校验剖析、链上证据与 Foundry 复现

编委会史料考证与链上复盘

本篇归档基于公开密码学文献、历史白皮书与链上交易数据进行独立交叉核实,遵循学术严谨性标准。

同行文献已核查

Wormhole 跨链桥被盗是怎么回事?

2022 年 2 月 2 日,攻击者在 Wormhole 的 Solana 合约上伪造了一份额存款的守护者签名批准,凭空铸出 12 万枚 wETH(约 3.25 亿美元)。Wormhole 是连接以太坊和 Solana 的跨链桥:真 ETH 锁在以太坊一侧,守护者中的 13 位(共 19 位)签署存款证明后,Solana 侧按 1:1 铸出 wETH。问题出在签名校验上——代码对照的是一份调用方可伪造的名单(经由一个已废弃的 Solana 系统函数),攻击者据此凭空捏造了存款证明,随后把其中 93,750 枚 wETH 跨回以太坊,从 Wormhole 金库里取走了真 ETH。约 24 小时内,Wormhole 背后的 Jump Trading 注入 12 万枚 ETH 重新做实全部 wETH,用户一分未损——这成了 DeFi 史上最大的一次自掏腰包救助。2023 年,经英国法院令,被盗 ETH 的大部分也从黑客手中被追回。

核心要点

  • Wormhole 是连接以太坊和 Solana 的跨链桥:一侧锁定真 ETH,另一侧按 1:1 铸出 wETH,随时可兑回。到 2022 年初,桥后面锁着超过 10 万枚以太坊(约 2.5 亿美元),而整个 Solana DeFi 都把 wETH 当成真以太坊在用。
  • 它的全部安全模型就是一次校验:19 个链下守护者(Guardian)为存款证明(VAA)签名,桥见到 13 个签名就铸币。正如本页复现视频所说:第 3 步的签名校验,就是这座桥全部的安全。
  • 2022 年 2 月 2 日,校验无声失效:Solana 侧代码对照的是调用方可伪造的输入——经由一个已废弃的 Solana 系统函数。攻击者用仅抵押 0.1 ETH 的伪造账户骗过校验,凭空铸出 12 万枚 wETH,时值约 3.25 亿美元。
  • 攻击者钱包 0x629e…796b 被 Etherscan 标注为「Wormhole Network: Exploiter」,初始资金来自 Tornado Cash;据 Elliptic 分析,其中 93,750 枚 wETH 被跨回以太坊,从 Wormhole 金库兑走真 ETH。失去抵押支撑的 wETH 引发连环清算恐慌,SOL 单日下跌约 13.5%。
  • Wormhole 链上喊话开出 1,000 万美元白帽赏金,无人回应;约 24 小时内,Jump Trading 注入 12 万枚 ETH,把所有 wETH 重新做实为 1:1——DeFi 史上最大的一次自掏腰包救助,救回了所有用户,也留下了一个不舒服的问题:下一座桥,还有 Jump 吗?
  • 2023 年 2 月,英国高等法院一纸命令允许 Oasis 协议修改自家合约,Jump 顺势反制了黑客的杠杆仓位,追回约 12 万枚被盗 ETH(因行情上涨时值约 1.4 亿美元)。而代码层面的修复只有一行:校验签名时,对照合约自己存储的守护者名单,永远不是调用方递进来的那份。

锁着 Solana 全部以太坊的那座桥

在钱被偷走之前,先弄清 Wormhole 承诺了什么——以及整个 Solana 经济为什么都压在一次签名校验上。

  1. 1

    Solana 的以太坊生命线

    Wormhole 是加密世界两大阵营之间的管道:把真 ETH 存进它在以太坊的合约,桥就在 Solana 上按 1:1 铸给你 wETH;把 wETH 烧掉,ETH 原路奉还。到 2022 年初,这个承诺让 Wormhole 成了 Solana 最重要的跨链桥:桥后锁着超过 10 万枚以太坊,约合 2.5 亿美元;Solana DeFi 的借贷市场和流动性池,全都拿 wETH 当真金白银来计价。每一笔用 wETH 做抵押的贷款,本质上都抵押在同一条承诺上:除非桥真正验证过一笔存款,否则一枚 wETH 也不会被铸出来。

    讲解幻灯片列出 Wormhole 跨链桥的原理:在以太坊锁定真实 ETH,在 Solana 一侧按 1:1 铸出 wETH
    整个产品就四条——出事的正是最后一条。
  2. 2

    19 个见证人,13 个签名,一条铁律

    另一条链怎么知道存款真的发生了?它信任守护者(Guardian)——19 个链下见证节点盯着每一笔以太坊存款,并签署一份证明消息,称为 VAA(Verified Action Approval)。把携带 19 个签名中任意 13 个的 VAA 递给 Solana 侧的桥,它就照单铸币,不再多问。视频里的示意图用一句话画出了全部信条:第 3 步的签名校验,就是这座桥全部的安全。没有签名就不铸币;签名凑够,无条件放行。后面的一切——盗案、修复、这一整页——都源自桥每次都必须答对的一个问题:谁来认定什么才算真签名?

    Wormhole 信任模型流程图:以太坊存款、19 个守护者为 VAA 签名(需 13 个)、桥据此铸出 wETH
    一张图一条警告:第 3 步的校验就是全部安全。

失效的那道校验

密码学本身没有失守。是桥问错了问题——还用攻击者递来的数据回答了它。

  1. 3

    漏洞:它校验的对象就是错的

    安全的做法只有一个:把每个签名对照自己那份固定的真守护者名单逐一核验——那份名单任何调用者都碰不到。而 Wormhole 的 Solana 程序信任了一个调用者可以操控的输入。现实中的漏洞藏在一个已废弃的 Solana 内置函数里:桥使用的 load_instruction_at 会读取另一个账户的指令数据,却不检查这个账户到底是谁的。Solana 在 Wormhole 部署前刚刚上线了带校验的替代版本,桥却带着旧函数上了生产。于是攻击者自己搭了一个冒充系统账户的账户,用它给校验程序喂进一份伪造的签名集,而桥以为自己在读 Solana 官方数据,照单全收。校验通过,12 万枚 wETH 铸出,背后没有任何抵押。

    标题为 The bug it checked the WRONG thing 的幻灯片,解释 Wormhole 的校验信任了可被伪造的输入,导致 12 万枚 wETH 在无抵押状态下被铸出
    四条要点一个习惯:调用方递来什么,就信什么。
  2. 4

    藏在校验代码里的那道陷阱

    视频的复现把漏洞拆成了几行看得懂的代码。守护者把提款要素——付给谁、付多少、一个随机数——哈希成摘要(digest),再用私钥签出 65 字节的签名;桥调用 recover(摘要, 签名),得到签出这个签名的地址。关键在于:recover 永远不会失败,它总会返回某个合法地址。所以真正的问题只有一个——这个地址是不是守护者?而有漏洞的代码是对照 claimedGuardians 回答这个问题的,那是一份由函数调用者随手递进来的名单。截图标出的正是那一行:require(_in(claimedGuardians, signer))——调用方的名单。签名是调用方给的,评判签名的名单也是调用方给的。

    有漏洞的 Wormhole 桥 Solidity 代码,receiveAndMint 函数中的 require(_in(claimedGuardians, signer)) 被标注为调用方的名单
    第 33 行注释说得明明白白:名单来自调用方,且从未对照真名单核验。

链上盗案全程

2022 年 2 月 2 日:一笔本不可能存在的铸币,一场搬空金库的兑付,以及 Solana 亲眼看清自己抵押品成色的一天。

  1. 5

    被 Etherscan 盖章的「Wormhole Network: Exploiter」

    2022 年 2 月 2 日,攻击者把把戏用在了真金白银上:一份伪造的存款证明——签名出自攻击者三小时前建好的账户,桥却把它当成了 Solana 系统账户,而这个账户的全部抵押是 0.1 ETH——合约照单铸出 12 万枚 wETH,按当时币价约 3.25 亿美元。如今 Etherscan 在红色警告横幅下把这个地址(0x629e…796b)直接标注为「Wormhole Network: Exploiter」,并显示钱包的初始资金来自 Tornado Cash。以太坊那边,一笔存款都没有发生过。桥只是被说服了它发生过——因为定义「什么算证据」的,是攻击者,不是守护者。

    Etherscan 上攻击者地址 0x629e 的页面,红色盗案警告横幅下标注 Wormhole Network Exploiter,下方是交易列表
    白纸黑字,就写在地址页上:红色横幅直接点名。
  2. 6

    整场骗局,一张 Recap 卡讲完

    假的欠条只值换得到多少真钱,而攻击者兑现得毫不犹豫。据链上分析机构 Elliptic,铸出的 12 万枚 wETH 中有 93,750 枚分三笔跨回以太坊,直接从 Wormhole 金库兑走真以太坊;其余大部分——约合 3.6 万枚——被换成了 USDC 和 SOL。伤害立刻向外辐射:躺在 Solana 借贷市场里的所有 wETH,一夜之间变成了对「不存在的以太坊」的欠条——Paradigm 研究员 Georgios Konstantopoulos 形容为「针对 Wormhole ETH 的无抵押贷款的多米诺效应被严重低估了」——SOL 单日跌去约 13.5%。截图里这张 Recap 卡把骗局压缩成三行:靠签名铸币,信调用方的名单,凭空铸出 12 万枚。

    总结幻灯片概括 Wormhole 盗案:桥按守护者签名铸币、信任了调用方提供的名单、攻击者凭空铸出 12 万枚 wETH
    三行讲完的盗案——第四行才是当年没被认真读的那条。

在 Foundry 里复现 3.25 亿美元的漏洞

想真正看懂这次攻击,只有亲眼看它跑一遍。一个极简桥、三幕剧,一台打印出整场犯罪的终端。

  1. 7

    一座极简桥,三幕剧

    想真正看懂这个漏洞,就得看它跑起来。视频用 Foundry——以太坊开发的标准工具链——重建了一个极简版的桥:一个「见到守护者签名就铸币」的小合约,然后把攻击排成三幕。第一幕,诚实情形:真守护者为真实存款签名,铸币正常。第二幕,攻击:攻击者用自己的密钥签名,自称守护者,凭空铸出一笔巨款。第三幕,修复:对照真正的守护者名单,攻击当场死亡。同样的三幕,2022 年 2 月在主网上真实上演过一遍——只不过站在测试网 ether 位置上的,是 3.25 亿美元的真钱。

    幻灯片列出用 Foundry 分三幕复现 Wormhole 桥漏洞的计划:诚实铸币、攻击者凭空铸 12 万枚、对照真实守护者名单的修复
    接下来五张图的剧本:诚实、攻击、修复。
  2. 8

    开跑之前,先读测试

    动手之前,视频先读了测试文件——因为整个故事早就写在注释和断言里。第一幕用真守护者名单部署桥,让三位守护者中的两位为一个合法的 10 枚代币存款签名,并断言用户真金白银收到这 10 枚。第二幕的注释一口气说穿了攻击:签名对照的是调用方的名单——攻击者把自己的密钥当「守护者」递进去,凭空铸出 12 万枚 wETH;没有存款,签名本身也没有任何问题——它们完全合法,只是不出自真正的守护者。第三幕把同一批伪造签名指向修复后的桥,期待一个 revert:『not a guardian』。

    Foundry 测试合约代码:ACT 1 诚实存款、ACT 2 攻击者递入自己密钥充当守护者、ACT 3 期待 not a guardian 回滚
    三幕剧,先写成注释,再跑上链。
  3. 9

    第一幕:诚实铸币,绿灯通过

    先证明没人作弊时桥是好的。测试构造一笔真实的 10 枚 wETH 提款,哈希成摘要,用真守护者的密钥签名,连同真守护者名单一起传入。桥逐一核对签名、清点法定数量,精确铸出 10 枚。终端打出结果:[PASS] test_1_honest——『user minted (honest): 10.000……』——一项通过,零失败。这盏绿灯正是下一张图刺眼的原因:攻击里,密码学的一切都没变。同一条曲线,同一个 recover,同一座桥。变的只有那份名单。

    forge test 终端输出 test_1_honest 通过,打印 user minted (honest): 10.000000000000000000,测试套件全绿
    绿灯,一切如设计。记住这个输出——攻击的结果会和它几乎一样。
  4. 10

    第二幕:凭空铸出 12 万枚 wETH

    攻击上演——注意它改动了多少:几乎为零。同一座桥,同一个摘要,同一个函数。唯一的区别:签名出自攻击者自己的两把密钥,而传入的守护者名单里装着同样这两个地址。所有校验照样全部通过,因为每个签名在密码学上都完全合法——recover 返回的就是攻击者的地址,而它们恰好匹配攻击者的名单。终端打出点睛之笔:[PASS] test_2_attack——『attacker MINTED (no deposit): 120000.000……』——套件全绿,12 万枚 wETH 凭空出现。这就是那个 3.25 亿美元的漏洞,几毫秒内复现完毕:桥根本无法分辨真守护者和调用者编造的守护者,因为它从来没问过。

    forge 终端输出 attacker MINTED (no deposit): 120000.000000000000000000,复现的 Wormhole 桥攻击通过 test_2_attack
    [PASS]。问题就在这——伪造的铸币,通过了这世上所有存在的校验。

第三幕:修复、兜底与清算

一行代码杀死攻击。然后是无人回应的 1,000 万美元悬赏、Jump 写下的 DeFi 史上最大支票——以及两年后账本的清账。

  1. 11

    第三幕:一个词的修复

    修复小到能塞进一条注释里,截图把它并排放好了。修复前(有漏洞):receiveAndMint 接收 claimedGuardians 参数——调用方递来的名单——只要求签名者在这份名单里。修复后:参数被整个删掉,函数改为核对 _in(guardians, signer),这里的 guardians 是合约部署时一次性写入、任何调用者都无法更改的名单。同样的签名,同样的 recover,同样的法定人数——唯一的区别是,签名所对照的名单归谁所有。正如视频所说:任何时候,一个合约把信任校验建立在调用者可以提供的数据上,那都不叫安全,那叫建议。

    BridgeFixed.sol 代码注释展示与有漏洞 Wormhole 桥的唯一区别:删除 claimedGuardians 参数,改用合约自身的守护者名单
    注释写着「唯一的改动」——四行字,本可以省下 3.25 亿美元。
  2. 12

    修复测试:期待「not a guardian」

    修复配了一个专属测试,它把攻击原样重做一遍:同一个攻击者,同一套自造密钥,同样索要 12 万枚 wETH——全部指向修复后的桥。不同的是预期。测试用 vm.expectRevert(bytes("not a guardian")) 包住调用,告诉 Foundry 正确的结果是拒绝,然后断言攻击者的余额仍然是零。只要签名校验钉死在真实、存储于合约内部的守护者名单上,一模一样的攻击连一个 wei 都铸不出来。挪动一个词——claimedGuardians 变成 guardians——一整类漏洞就从「印钞机」变成了「一行报错」。

    Wormhole 复现第三幕的 Solidity 测试代码:使用 vm.expectRevert bytes not a guardian,并断言攻击者余额保持为零
    同一场攻击,改写成对失败的期待。
  3. 13

    攻击重跑:回滚,余额归零

    跑一遍,看同一场劫案当场毙命。片刻之前还凭空铸出巨款的同一批伪造签名,如今在修复后的桥上撞墙,终端把一切打了出来:[PASS] test_3_fixed——『attacker minted (fixed): 0.000000000000000000』——一项通过,零失败。2022 年 2 月在主网上凭空变出 3.25 亿美元的攻击,被降格成一句回滚原因和一个零余额。整张截图就是全部防御:把信任名单钉死在合约内部,永远不接受调用方递来的那份,并且记住——出自错误签名的完美合法签名,仍然是攻击。

    修复后的 Wormhole 桥拒绝伪造铸币的终端证明:PASS test_3_fixed,attacker minted (fixed): 0.000000000000000000
    同一个攻击者,同一批签名——换来 0.000 的余额和一个绿勾。
  4. 14

    1,000 万美元悬赏,和一张抹平窟窿的支票

    代码坏了,结局却没坏——因为有人决定掏钱。Wormhole 先试了怀柔:在链上向攻击者公开喊话,开出 1,000 万美元白帽赏金,只求 wETH 物归原主。无人回应。约 24 小时内,窟窿还是被填上了:孵化了 Wormhole 的做市巨头 Jump Trading 注入 12 万枚 ETH,让每一枚 wETH 重新回到 1:1 全额抵押——DeFi 史上最大的一次自掏腰包救助。Bankless 在当周的节目录制里,一边为用户毫发无损叫好,一边担心开了坏先例:这种结局不该被指望,因为不是每座桥背后都站着一个 Jump。截图里这张教训卡是同一个故事的代码版:对照正确的名单做校验——否则,替错误名单买单的会是比你更有钱的人。

    Wormhole 盗案复盘的教训幻灯片:签名校验只和你校验的对象一样可靠,来自错误签名的合法签名仍然是攻击
    复现得出的教训卡——Wormhole 用最贵的方式学会了它,账单由 Jump 买单。
  5. 15

    七周之后:Ronin,镜像的另一面

    片尾卡写着「下一场盗案,继续拆」——下一场早就排上日程了。2022 年 3 月 23 日,Wormhole 之后七周,攻击者从 Ronin 桥搬走 6.15 亿美元,创下当时 DeFi 最大盗案纪录。两桩案子互为镜像:Wormhole 死于代码缺陷——没有任何人的密钥被偷,只是签名被对照了错误的名单;Ronin 死于社会工程——代码没有问题,攻击者靠「交朋友」拿下 9 把验证者密钥中的 5 把,剩下的交给阈值机制。两次都是同一处伤口——桥的信任假设,从不同的侧面碎掉。Wormhole 之后的时代带来了强制审计、巨额赏金、提款限额和重新设计的证明系统,而复现得出的那条铁律仍在筛选幸存者:把信任名单钉死,永远别让调用方告诉你谁可信。

    Wormhole 盗案拆解的片尾幻灯片,写着 Next: another hack, rebuilt,附标语 Real theft. Real code. Real on-chain.
    「下一场盗案。」六周后,它如约而至,署名 Ronin。

常见问题

Wormhole 跨链桥被盗是怎么回事?

2022 年 2 月 2 日的攻击事件:攻击者在 Wormhole 的 Solana 合约上伪造了一份额存款的守护者签名批准,凭空铸出 12 万枚 wETH(约 3.25 亿美元)。Wormhole 是以太坊和 Solana 之间的跨链桥:ETH 锁在以太坊一侧,19 个链下守护者中的 13 个为存款证明签名后,Solana 侧才铸出 wETH。由于签名校验可以被伪造,攻击者铸出假 wETH,随后把其中 93,750 枚跨回以太坊,从 Wormhole 金库兑走真 ETH。约 24 小时内,Jump Trading 重新做实了整座桥,wETH 用户一分未损。

攻击者利用的是什么漏洞?

是签名校验的漏洞,不是密码学被攻破。Solana 侧合约依赖一个已废弃的系统函数 load_instruction_at,它会读取另一个账户的指令数据、却不核实这个账户的来源——Solana 在 Wormhole 部署前刚发布了带来源校验的替代版本。攻击者自建了一个冒充系统账户的账户,用它给桥喂进一份伪造的签名集。用代码的话说:桥把签名对照「调用方提供的名单」核验,而不是对照自己固定的守护者名单——于是攻击者密钥签出的签名,被当成了 19 位真守护者中 13 位(每次批准所需的法定数量)的签名。

是谁黑掉了 Wormhole?

至今无人知晓。攻击者的以太坊钱包 0x629e7Da2…796b71A 被 Etherscan 标注为「Wormhole Network: Exploiter」,初始资金来自 Tornado Cash,但没有任何个人或组织被可信地指认,也没有宣布过任何逮捕。这种匿名性塑造了整个后续:Wormhole 链上开出的 1,000 万美元白帽悬赏无人应答,而被盗 ETH 在攻击者的钱包里基本趴着不动,在所有人的注视下躺了很多年。

Wormhole 的钱追回来了吗?

少见地,追回了——而且是两次。第一次:约 24 小时内,Jump Trading 注入 12 万枚 ETH,把所有 wETH 重新做实为 1:1,储户一分钱都没损失。第二次:2023 年 2 月,英国高等法院下令允许 Oasis 协议修改自家智能合约,Jump 借此反制了黑客的杠杆 stETH 仓位,追回约 12 万枚被盗 ETH——受 2023 年行情推动时值约 1.4 亿美元。据报道,追回的资金已移交英国有关部门。而原始攻击者至今没有公开身份。

Jump Trading 为什么替 Wormhole 兜底?

Jump 不是局外人——这家做市巨头孵化了 Wormhole(2020 年收购桥开发商 Certus One),桥的偿付能力实际上就是它自己的负债。放任 12 万枚无抵押 wETH 毒化 Solana 的 DeFi 市场,意味着协议死亡、信任它的用户受损、Jump 的仓位和声誉一个下午全部烧光——掏钱是摆脱清算连锁最便宜的出口。这一手成功了,但也成了圈内的警示故事:正如 Bankless 当周所说,由豪门母公司买单的大团圆结局,立了一个任何去中心化系统都不该承诺的先例——下一座桥背后,不一定有个 Jump。

Wormhole 之后,跨链桥还安全吗?

更好了,但谈不上安全。Wormhole 证明桥会死于代码(伪造的签名校验);七周后的 Ronin 证明桥也会死于密钥(9 位验证者中的 5 位被社会工程拿下)。2022 年以来,行业押注于强制审计、大额漏洞赏金、提款限额和更去中心化的守护者集合——Wormhole 本身也在持续运营,并成长为使用量最大的跨链协议之一。但桥仍然是一个「两条链就同一份真相达成一致」的承诺,而控制这份共识的总是某些人。复现留下的持久教训:对照合约自己存储的可信名单做校验,永远别用调用方提供的那份——并且把每一笔跨链存款,都当成对持钥者的一次下注。

继续看这段历史

参考资料

延伸多媒体文献参考

本专题时序与历史图示交叉参考了 0xUnstuck 出品的文献视频 “The $325M Wormhole Hack: What Went Wrong and How to Prevent It”,谨向原研究记录者致谢。

免责声明与学术边界

本图解指南仅供区块链技术史学术研讨与公众科普使用,不构成任何财务、证券、投资或法律建议。文中所载历史价格、黑客事件与安全漏洞分析均属于公开历史记录。加密货币市场具有极高风险,请审慎研判。