2021 年 8 月 10 日,Poly Network 遭受黑客攻击,损失超过 6 亿美元。此次黑客攻击横跨多个区块链,包括 以太坊 , 币安智能链 和 Polygon 。这是迄今为止涉事金额最大的一次 DeFi 攻击。
Poly Network 是一个区块链互操作性项目,允许人们跨区块链发送交易。他们的关键用例之一是跨链桥,它允许你通过在一个区块链上锁定代币并在另一个区块链上解锁,将资产从一个区块链转移到另一个区块链。攻击者成功解锁了各个区块链上的代币,而在其他区块链上却没有锁定相应数量的代币。
事件细节
Poly Network 允许通用信息在多个区块链间自由传递。它利用"keeper"来促进跨链交易。用户最初在源区块链上发起跨链交易,然后通过 Poly Network 在目标区块链上交易。keeper 在包含原始交易的源区块链的区块上签名。然后,用户将此签名区块提交给目标区块链上的智能合约(EthCrossChainManager),该合约会检查签名的有效性。如果签名有效,该合约在目标区块链上就会执行类似的交易。
这可以是任何交易,没有具体限制。由于该交易是由目标区块链上的 EthCrossChainManager 而不是用户执行的,所以用户可以冒充 EthCrossChainManager,也就意味着他们几乎可以做任何交易。。由于该交易是由目标区块链上的 EthCrossChainManager 而不是用户执行的,所以用户可以冒充 EthCrossChainManager 并做几乎任何交易。这种设计使得必须确保 EthCrossChainManager 不具有任何用户可以通过模拟它来展开攻击的特殊权限。然而,EthCrossChainManager 智能合约有权限改变存储在 EthCrossChainData 合约中的 keepers。这使得攻击者可以将原来的 keepers 换成由攻击者控制的恶意 keepers。
一旦 keeper 处于攻击者的控制之下,攻击者就可以在目标区块链上进行任意的跨链交易,即使源区块链上没有发生这样的交易。攻击者通过签署源区块链的假区块(非源区块链的有效区块)来做到这点,这其中包含攻击者随意提交的交易。
然而,由于 EthCrossChainManager 只确保区块由 keepers 签名,而不是验证整个区块,因此它接受它们为有效区块,并执行攻击者插入的任意跨链交易。
攻击者创建了虚假交易,允许他们解锁目标区块链上的代币,而不锁定源区块链上的代币。LockProxy 合约管理代币的锁定和解锁。当源区块链的 EthCrossChainManager 通过跨链调用时,它解锁目标区块链上的代币。只有当用户在源区块链上锁定了他们的代币时,EthCrossChainManager 合约才会创建这样的调用。攻击者通过使用恶意的 keeper 创建一个从 EthCrossChainManager 到 LockProxy 的虚假调用来绕过锁,目标链上的 LockProxy 合约接受跨链调用并解锁代币。LockProxy 假设用户已经锁定了源区块链上相应数量的代币。
现在,源区块链上有一些本应被锁定的代币,但实际上却被解锁。这些代币不再有任何抵押品的支持。攻击者基本上已经成功地在两个网络中复制了代币。原来有价值的代币,在目标区块链上,被攻击者所控制。其他用户在源区块链上只能得到无担保的、重复的代币。因此,以任何形式拥有这些代币的人(在他们的钱包里持有,提供流动性,等等)都是遭受损失的人。这些跨桥代币的价格预计会大幅下跌。
这个漏洞的根本原因是 EthCrossChainManager 合约能够改变 Keepers。如果 Keepers 被破坏,整个协议就会被破坏,这是预期的行为/风险。在这种情况下,攻击者设法直接改变 Keepers,而不是破坏现有的 Keepers。想象一下,有人有能力改变你的密码,即使他们不知道你的密码,他们也会把它改成他们知道的密码,然后用它来登录。
技术细节
-
EthCrossChainManager 合约有一个
verifyHeaderAndExecuteTx
函数,允许用户执行任意的跨链交易。 -
EthCrossChainManager 在执行该交易之前,会验证包含该交易的区块是否已经被三分之二以上的可信的 keepers 签署。
-
keepers 应该只对源区块链上真实存在的块进行签名。
-
一旦用户在源区块链上执行了交易,他们就可以从源区块链获取真正的区块,让 keepers 签名,然后使用 keepers 的签名在目标区块链上进行跨链交易。
-
任意交易应该只调用以
(bytes,bytes,uint64)
为参数的函数。合约试图通过使用abi.encodePacked(_method, "(bytes,bytes,uint64)")
来生成目标函数签名来确保这一点。 -
这是一个不正确的安全假设,很容易被绕过。在 solidity 中,函数签名长度只有 4 字节。它们是由函数名和参数的哈希值生成的,但 EVM 并没有强制执行这一点,这就很容易发现碰撞。例如,
putCurEpochConPubKeyBytes(bytes)
和f1121318093(bytes,bytes,uint64)
生成相同的函数签名。 -
可信 keepers 列表存储在 EthCrossChainData 合约中,只能由合约的所有者通过调用
putCurEpochConPubKeyBytes(bytes)
来更改。 -
由于 EthCrossChainManager 允许用户执行任意交易,所以它不应该是所有东西的所有者,而是成为 EthCrossChainData 合约的所有者。攻击者利用这一事实和不正确的函数签名安全假设的组合,使 EthCrossChainManager 调用 EthCrossChainData 的
putCurEpochConPubKeyBytes(bytes)
函数,并将 keepers 更改为他们控制的单个 keeper。 -
攻击者通过在源区块链(据说是本体 Ontology)上正常调用一个类似
f1121318093(bytes,bytes,uint64)
的函数,触发了函数签名碰撞。该交易很可能被退回(Reverted),因为在 EthCrossChainData 合约中不存在这样一个函数。然而,即使被退回的交易也是区块的一部分。 -
keepers 在包含攻击者交易的块上签名,因为它是合法的交易(尽管它可能已经被退回)。
-
然后,攻击者使用该签名在目标区块链( 以太坊,币安智能链 和 Polygon )上进行跨链交易。由于这些交易是通过 EthCrossChainManager 分派的,因此完成了 EthCrossChainData 中的
onlyOwner
检查,可信的 keepers 被置换为一个恶意的 keeper。 -
拥有对 keeper 的控制意味着攻击者可以欺骗 EthCrossChainManager 合约来执行在源区块链上根本不存在的跨链交易。
-
LockProxy 合同有一个解锁函数,接受来自源区块链的 EthCrossChainManager 的跨链调用。
-
攻击者通过调用 LockProxy 的
unlock
函数,创建了包含来自源区块链 EthCrossChainManager 交易的假区块。 -
可信的 keepers 不会对这些伪造的块进行签名,但是由于攻击者控制了恶意的 keeper,他们对块进行了签名。
-
EthCrossChainManager 验证区块已被管理员签名,然后执行交易。这导致 LockProxy 解锁并将代币发送给攻击者。
-
攻击者在多个区块链上对各种代币重复此操作。
-
同样值得注意的是,EthCrossChainManager 合约用
_fromContractAddr
和_fromChainId
参数强制填充任意交易的最后两个参数,这意味着编码的 keepers 数据不是理想的类型。EthCrossChainManager 合约在从编码数据中提取 keepers 地址时使用自定义解码和反序列化方案。只有线型解码和反序列化方案才能使这种攻击成为可能。如果对编码的数据进行更严格的类型检查,交易应该失败。
附录
攻击早在 UTC 时间 2021 年 8 月 10 日上午 09:33:07 就开始了,资金窃取至少持续到 UTC 时间 2021 年 8 月10 日上午 10:29:21 。如果有更严格的监控和警报机制,损失有可能缩小,因为 EthCrossChainManager 是一个可暂停的合约。
我最初在 Twitter 上发布了我的早期发现。我声称只有一个 keeper 被使用,而这个 keeper 因为签署了无效的区块而受到影响。这个分析只是基于一个触发跨链解锁的交易,我没有看以前的交易,错过了攻击者用恶意 keeper 置换可信 keeper 的关键部分。
我最初的想法是,这是一个无聊的、传统的黑客。由于这个原因,我没有去分析更多的交易。在了解到攻击者置换了 keeper,而不是泄露了 keeper 的私钥之后,这就成了一个令人着迷的攻击分析了。
目前,似乎攻击者正在通过以太坊网络发送消息,协商向 Poly Network 返还部分资金。你可以通过社区成员创建的 谷歌表单 跟踪对话。
攻击者显然已经跟在中心化交易所使用的钱包关联起来了,人们正试图从交易所收集关于攻击者的真实信息。攻击者有可能使用了偷来的账户,但也有可能这种调查方向会显示出攻击者的真实身份。早些时候,攻击者通过他们的以太坊地址发布了一些魔性评论,还打赏了一个以太坊用户。这是一个有点不寻常的行为,因为更多的互动意味着有更多的机会出现纰漏。有可能攻击者已经失误了,现在正处于损害控制模式,也有可能他们只是在耍花招。在这一点上,所有这些都是猜测,但还是相当有趣。
最近更新
攻击者现在声称自己是白帽,正在协商退还所有资金。他们目前已经退还了超过 2.5 亿美元的资金。
本文作者 Mudit Gupta 是 Sushi 核心团队成员。在加入 Sushi 之前,他是 Polymath Network 区块链工程师、以太坊开发者、安全研究员。过去,他从事过 Web 开发、系统编程、2D 游戏开发。他的专长是使用 Solidity 进行智能合约开发以及使用 Rust 进行核心区块链开发。日常热爱黑客与游戏。