背景
ZetaChain 是一条内置跨链托管与消息传递的 Layer 1,其 PoS 验证者通过运行多链节点、以 TSS 联合签名的方式在 ZetaChain 与其他链之间传递消息并执行交易。
20260428,ZetaChain 遭受了跨链调用攻击,由于对跨链信息缺乏校验与限制,黑客通过构造恶意的跨链信息,将目标链上曾经对 Gateway 合约授权的用户的资金进行转移。
从 ZetaChain → Ethereum 的跨链流程:
- 用户在 ZetaChain 上调用 GatewayZEVM 的
withdrawAndCall(带资产)或call(纯消息),指定 Ethereum 目标地址、Gas Token(ZRC-20)与 calldata。 - GatewayZEVM 将请求写入 ZetaChain 的 CrossChain 模块,生成一条状态为
PendingOutbound的跨链交易(CCTX),明确 Ethereum 端需执行的交易参数。 - 验证者读取 CCTX,通过 TSS 密钥分片进行 MPC 式联合签名。达到阈值后,生成标准 ECDSA 签名,并由 ZetaClient 向 Ethereum 网络广播交易。
- Ethereum 执行
- 若提取资产:TSS 交易触发 ERC20Custody 释放锁定的 ERC-20,或由 TSS 地址转账原生 ETH。
- 若合约调用:TSS 交易直接调用 Ethereum 目标合约。
- ZetaClient 监听 Ethereum 结果:
- 成功 → CCTX 标记为
OutboundMined,流程结束。 - 失败 → 生成
PendingRevert,TSS 重新签名一笔回滚交易,经 GatewayEVM 将资产/消息退回 ZetaChain,最终触发 App 的onRevert兜底。
- 成功 → CCTX 标记为
- ZetaChain Tx:https://zetascan.com/tx/0xdaa19f9952b8d171ae3481a0b31b6c63d8ee4da03c5821663be5cdb29ddc4521
- ZetaChain GatewayZEVM:https://zetascan.com/address/0xd9dbEec028C12D2dA09a05C9d26709c0Ec722BC1
- Ethereum Tx:https://app.blocksec.com/phalcon/explorer/tx/eth/0x81fc9b2457b3ea66e2cefe2afe65d083ce358a11520e0f4aa5faad0bfea18a56
- Ethereum GatewayEVM:https://etherscan.io/address/0x48b9aacc350b20147001f88821d31731ba4c30ed
这里参考了 SlowMist 推文中提到的两笔 tx,Ethereum 上发生的攻击交易好找,就是不知道 ZetaChain 上的交易是通过什么信息检索出来的,了解的读者可以指点一下小弟,十分感谢。
Trace 分析
在 ZetaChain Tx 中,攻击者调用 GatewayZEVM.call() 函数,传入以下参数:
- receiver:设为 Ethereum 上的 USDT 地址
- message:设为 USDT.transferFrom() 的 calldate

随后该笔跨链调用被验证者捕获,经过 TSS 的签名后,在 Ethereum 上被执行。
在 Ethereum Tx 中,执行了跨链信息,从 0x8f1a 中转移了 USDT。

代码分析
ZetaChain GatewayZEVM
由于 ZetaChain GatewayZEVM 在区块链浏览器上没有开源,所以通过 Github 的代码进行分析:https://github.com/zeta-chain/protocol-contracts-evm/blob/f8f4aef0ddc47a4de0734271db6063f459967c7f/contracts/zevm/GatewayZEVM.sol
可以看到 call() 函数没权限管理,任何人都可以调用。其次在参数校验方面,在打印 Called event 之前,进行了 validateCallAndRevertOptions 和 validateReceiver 两个校验。

validateCallAndRevertOptions 只检查了 gas limit 和 message size 两个方面。

validateReceiver 只检查了 receiver 地址为合约地址。

所以,由以上的代码可以得知,在 ZetaChain 上调用 GatewayZEVM.call() 函数所进行的参数检查是很宽松的。这也就导致了攻击者可以利用这个特点,构造恶意的跨链信息。
Ethereum GatewayEVM
跨链信息在被验证者捕获后,交由 TSS 签名,并在 Ethereum GatewayEVM 中通过 execute() 执行。权限控制:仅为 TSS_ROLE 调用。

进入到 _executeArbitraryCall() 函数,直接对跨链的目标合约与 calldata 进行调用。

基于上面的两个链上的 Gateway 合约代码,可以确认这个漏洞的影响范围是所有给 Ethereum GatewayEVM 进行过授权的用户。(按理来说其他 EVM 链也是一样的情况)攻击者可以跨链传入恶意的 message,利用 GatewayEVM 将已授权用户的资金转移。
后记
最近跨链桥多事之秋啊,前段时间 HyperBridge 才出了事情,今天又轮到 ZetaChain 了。写得比较匆忙,如果有不对的地方可以多多指教。最后,感谢你的阅读。