Bybit交易所遭遇了价值近15亿美元的加密货币盗窃事件,攻击者通过社会工程学攻击了Safe钱包开发者的开发机器,最终控制了Bybit的Safe账户并转移了所有资产。文章分析了事件经过,并探讨了如何利用Safe钱包的安全功能(如Safe Guards和时间锁)来预防此类攻击,强调了配置内置安全功能的重要性。
2025年2月,近15亿美元从 Bybit 交易所被盗,这被称为历史上最大的加密货币黑客攻击。矛盾的是,它并非由智能合约漏洞引起,而是由社会工程学引起的。鉴于我们在审计Bybit使用的Safe智能合约方面的经验,我们决定更详细地调查这次违规事件。
TLDR:使用 Safe 钱包的项目——尤其是那些管理大量资金的项目——需要主动配置内置的安全功能,如 Safe Guards 和时间锁。这些功能的存在是有原因的。
以下是事件的展开方式(时间线由 BlockThreat 提供):
delegatecall
执行了一个合约升级,替换成了一个恶意的实现。让我们仔细看看 Safe 提供的用于降低智能合约安全风险的安全功能。
这次黑客攻击最关键的问题是盲签,这是生态系统中一个长期存在的问题。冷钱包通常在审查交易方面有很差的用户体验,这使得签名者很容易在日常操作中批准恶意 payload,而没有验证他们实际签名的内容。
值得庆幸的是,有一些工具旨在解决这个问题。一个例子是 Safe script validator,最初由 @pcaversaccio 构建,现在由 OpenZeppelin 托管。该工具允许签名者在硬件钱包上确认之前,逐字节地针对预期的 Safe 脚本验证正在签名的 payload。
除了用户级别的工具之外,还有改进 multisig 阈值 并在 签名机器级别 引入自动 payload 验证的空间,从而降低人为错误的风险。
我们还应该超越 Web2 风格的防御。Safe 提供 Safe Guards,内置的链上安全协议,如果配置得当,可以完全防止 Bybit 资金的损失。尽管它们是可用的,但它们通常未被使用或被误解。这种情况需要改变。
Safe 钱包可以通过 Safe Module 或 Safe Guard 原生扩展。Module 允许从 Safe 执行的任意条件(基于 Module 逻辑),并且可以为一个钱包定义多个 Module。总是存在一个 Guard,并且它只能阻止交易。在 最近的博客文章 中,我们已经描述了围绕 Safe 的安全最佳实践,并且还在柏林的 SafeCon 2023 上讨论了它。让我们看看 Guards 如何帮助我们保护我们的钱包。
正如官方文档中 所述:“当在 n-out-of-m 方案之上存在限制时,使用 Safe Guards”,让我们限制链上的某些操作。Safe Guards 通过设计为我们提供预检查和后检查,并维护它们自己的状态。Safe Guard 的一个很好的例子是 ScopeGuard:
function checkTransaction(
address to,
uint256 value,
bytes memory data,
Enum.Operation operation,
uint256,
uint256,
uint256,
address,
// solhint-disallow-next-line no-unused-vars
address payable,
bytes memory,
address
) external view override {
require(
operation != Enum.Operation.DelegateCall ||
allowedTargets[to].delegateCallAllowed,
"Delegate call not allowed to this address"
);
require(allowedTargets[to].allowed, "Target address is not allowed");
if (value > 0) {
require(
allowedTargets[to].valueAllowed,
"Cannot send ETH to this target"
);
}
if (data.length >= 4) {
require(
!allowedTargets[to].scoped ||
allowedTargets[to].allowedFunctions[bytes4(data)],
"Target function is not allowed"
);
} else {
require(data.length == 0, "Function signature too short");
require(
!allowedTargets[to].scoped ||
allowedTargets[to].fallbackAllowed,
"Fallback not allowed for this address"
);
}
}
这个 guard 已经被广泛建立起来,并被 Immunefi 等项目使用,我们已经 审计了这个 guard。
然而,guards 可以更复杂。它们还可以实现 checkAfterExecution
函数,或者检查接口提供的签名和其他值。这使得构建 不仅检查传递的参数,还检查交易后的状态转换是否被允许和正确 的 不变性 成为可能。
另一个好的例子是 Mixin 协议 中的 Safe Guard,我们 也审计过。它访问聚合签名并恢复签名者。如果聚合签名中有一个特定的地址,并且它与保存在 guard 状态中的地址匹配,那么它允许你在某个时间锁之后执行交易。
当在 multisig 中管理大量投资组合时,这种方法可能至关重要。具有监控基础设施的交易延迟有助于对潜在的安全事件做出反应。但更重要的是,所讨论的目标范围可以完全防止不希望的执行。
“我不确定是否要放弃灵活性,但我肯定不会使用 multisig 调用 delegatecall。”
开始使用一个 guard 来防止 delegate call。确保 guard 经过审计。
“我有一个我需要调用的地址列表,否则,我不需要调用任何其他地址。”
开始使用 ScopeGuard。请注意,此 guard 是有权限的,因此也要对 guard 采取适当的安全措施(恶意的 guard 实现可能会阻止 Safe 交易)。当 guard 中的参数确定后,在某些情况下,可以放弃 guard 的所有权,以防止 guard 行为发生任何变化。
“我有特殊的要求,例如针对不同操作或不变性检查的不同 multisig 阈值。”
实现你自己的 Safe Guard 并对其进行审计。
仅仅依靠链下安全实践是不够的。将保护性约束直接嵌入到区块链协议中,可以提供更强大的防御,以抵御复杂的攻击。
Safe 的模块化和灵活的架构是有意为之的,它将配置安全的责任放在集成商身上,只允许绝对必要的操作。通过遵循最小权限原则并最小化不必要的功能,项目可以显著减少其攻击面并提高整体安全性。
如果能够正确理解可用的安全功能,并将其配置为与项目的特定需求相匹配,则可以防止这种特殊的漏洞利用。虽然 Safe Guards 是一种强大的原生解决方案,但它们并不是唯一的解决方案。Safe Modules 提供了更大的控制和自定义——而更大的权力带来了更大的复杂性。
- 原文链接: ackee.xyz/blog/a-safe-na...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!