如何远程崩溃Filecoin节点:Trail of Bits披露关键漏洞

Trail of Bits团队发现Filecoin网络Lotus和Venus客户端存在远程崩溃漏洞,攻击者可触发拒绝服务。本文详细分析该整数溢出漏洞的成因、修复方案,并提供预防此类问题的编码实践建议。

杀死Filecoin节点 - Trail of Bits技术分析

2024年1月,我们在Filecoin网络的Lotus和Venus客户端中发现并报告了一个可导致节点远程崩溃的漏洞。该漏洞源于索引验证错误,会引发数组越界异常,最终造成服务拒绝。

Filecoin工作原理

Filecoin是基于IPFS协议构建的分布式存储网络,其区块链由"tipsets"(相同高度和父tipset的区块集合)组成。主要客户端包括:

  • Lotus:官方Go语言实现
  • Venus:共享部分代码库的Go实现
  • Forest:实验性Rust实现

漏洞技术细节

问题核心在于CompactedMessages数据结构:

1
2
3
4
5
6
type CompactedMessages struct {
    Bls         []*types.Message
    BlsIncludes [][]uint64
    Secpk       []*types.SignedMessage
    SecpkIncludes [][]uint64
}

当处理包含tipset消息的peer响应时,BlsIncludes的索引值未正确验证是否在Bls切片范围内。

错误验证过程

validateCompressedIndices函数中,消息索引(本应为无符号整数)被转换为有符号整数后进行验证:

1
2
3
if int(mi) >= len(msgs.Bls) {
    return xerrors.Errorf("index exceeds messages count")
}

攻击者可通过设置大于有符号整数最大值的索引,使转换后变为负数从而绕过验证。

越界访问场景

在同步阶段的checkMsgMeta函数中,未经验证的索引直接用于访问数组:

1
2
3
for _, m := range bmi[bi] {
    bmsgCids = append(bmsgCids, allbmsgs[m].Cid()) // 可能触发panic
}

修复方案

解决方案是将长度比较改为无符号整数运算:

  1. Lotus在v1.25.2版本中修复(PR #11565)
  2. Venus在v1.14.3版本中修复(PR #6258)

预防措施

  1. 优先使用无符号整数
  2. 类型转换时注意值域检查
  3. 使用Semgrep静态检测规则:
1
2
3
4
5
6
7
8
rules:
  - id: check-int-comparison
    patterns:
      - pattern: |
          if int($X) >= len($Y) { ... }
    message: 避免将转换后的整数与切片长度比较
    severity: WARNING
    languages: [go]

区块链节点安全建议

构建区块链节点需要平衡共识、网络、虚拟机等多方面风险。Trail of Bits在Go/Rust实现的L1/L2、rollups和跨链桥审计方面具有丰富经验。如需安全支持,欢迎联系我们。

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