以太坊ABI解析器中的十亿次空值攻击:内存耗尽漏洞深度剖析

本文深入分析了以太坊ABI解析器中新发现的零大小类型(ZST)漏洞,该漏洞可导致内存耗尽型拒绝服务攻击,影响eth_abi(Python)、ethabi(Rust)等多个主流库,并详细披露了漏洞原理、PoC示例及协调披露时间线。

十亿次空值 - Trail of Bits博客

以太坊ABI解析器的隐藏挑战

在以太坊强大的区块链技术背后,隐藏着一个区块链开发者面临的较少人知的挑战:编写健壮的以太坊ABI(应用二进制接口)解析器的复杂性。以太坊ABI对区块链基础设施至关重要,它实现了智能合约与外部应用间的无缝交互。数据类型的复杂性以及精确编码解码的需求使得ABI解析充满挑战。规范或实现中的模糊性可能导致危及用户的漏洞。

漏洞发现:零大小类型(ZST)的威胁

零大小类型(ZST)是在磁盘上存储占用零(或最小)字节,但在内存中表示时需要显著更多空间的数据类型。以太坊ABI允许ZST存在,这可能导致拒绝服务(DoS)攻击:通过迫使应用程序分配大量内存来处理极小的磁盘或网络表示。

考虑以下示例:当解析器遇到ZST数组时会发生什么?它应该尝试解析数组声称包含的尽可能多的ZST。由于每个数组元素占用零字节,定义极大的ZST数组变得轻而易举。

具体示例如下:一个20字节的有效载荷将反序列化为包含数字2、1和3的数组;而另一个8字节的有效载荷将反序列化为2^32个ZST元素(如空元组或空数组)。如果每个ZST在解析后占用零字节内存,这不会成为问题。但实际上,每个元素通常需要少量但非零的内存来存储,导致表示整个数组时需要巨大内存分配,从而引发拒绝服务攻击。

漏洞影响范围

我们发现在多个主流库中存在此漏洞:

  • eth_abi (Python): v4.2.0之前版本存在漏洞
  • ethabi (Rust): v18.0.0版本
  • ethers-rs (Rust): v2.0.10版本
  • alloy-rs: 0.4.2版本
  • ethereumjs-abi: 0.6.8版本

概念验证(PoC)

我们定义有效载荷为:

1
2
0000000000000000000000000000000000000000000000000000000000000020
00000000000000000000000000000000000000000000000000000000FFFFFFFF

该有效载荷包含两个32字节块,描述了一个序列化的ZST数组。第一个块定义数组元素的偏移量,第二个块定义数组长度。

各库PoC示例

Python (eth_abi):

1
2
3
from eth_abi import decode
data = bytearray.fromhex(payload)
decode(['()[]'], data)

Rust (ethabi):

1
cargo run -- decode params -t "uint32[0][]" $payload

ethers-rs:

1
2
3
use ethers::abi::AbiEncode;
let data = hex::decode(payload);
let _ = Vec::<[u32; 0]>::decode(&hex_output.unwrap()).unwrap();

漏洞发现过程

这个漏洞类型的测试想法来源于在borsh-rs库中发现的问题。该Rust库尝试在恒定时间内解析ZST数组,这导致了未定义行为。在另一次审计中,自定义ABI解析器在解析ZST时也存在DoS向量。鉴于这两个问题不太可能是巧合,我们调查了其他ABI解析库中的此类漏洞。

利用可能性

该漏洞是否可利用取决于受影响库的使用方式。在上述示例中,演示目标是CLI工具。目前尚未找到在主网部署触发此漏洞的智能合约的方法,主要是因为Solidity和Vyper的最新版本禁止ZST。

然而,使用上述任何库的应用程序都可能存在漏洞。例如Etherscan(解析不受信任的ABI声明)以及任何从合约获取和解码数据的链下软件,如果允许用户指定ABI类型,都可能受到此漏洞影响。

协调披露时间线

  • 2023年6月30日: 首次联系各库维护者
  • 2023年8月2日: 为eth_abi(Python)创建GitHub私有安全公告
  • 2023年8月31日: eth_abi(Python)发布修复,未公开提及DoS向量

防护建议

建议开发者对解码器进行模糊测试,因为解码器中的漏洞通常很容易通过模糊测试发现。在Trail of Bits的审计中,我们采用模糊测试来识别漏洞,并教育客户如何进行自己的模糊测试。


本文详细披露了以太坊ABI解析器中的关键漏洞,强调了规范设计和实现加固的重要性,为区块链开发者提供了重要的安全警示。

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