作者:Bitcoin Core
本文汇集了已经披露的影响 25.1 以前版本 Bitcoin Core 软件的漏洞。
自 2024 年 7 月以来,Bitcoin Core 项目改变了影响旧版本的漏洞的披露策略。如今,已披露的漏洞在此页面集中呈现。
影响 0.21.0 以前版本的 Bitcoin Core 软件的漏洞可见此处。
为便于读者检查自己所用软件的安全性,将漏洞按照修复它们的版本号排列。
CVE-2024-52922:因对等节点拖延导致区块传播停滞
在 Bitcoin Core v25.1 版本以前,攻击者可以导致一个节点不下载最新区块。该问题被认为具有中等严重性。
详情
在通过一条【区块头】消息或者【致密区块】消息接收一个新区块的宣告时,收到宣告消息的节点会向发布宣告的节点重新请求数据,要么是完整的区块,要么是缺失的交易。如果宣告节点不按照点对点协议的要求响应收信节点,那么受影响的 Bitcoin Core 收信节点会等待最多 10 分钟,然后断开连接、发起另一次区块下载尝试。如果攻击者可以跟受害者节点建立多条入站环出站连接,就可以重复上述拖延过程。
推迟区块交付可能导致网络恶化,因为它拖慢了网络共识收敛的速度;这让挖矿支付更不公平,而且会导致网络活性问题。
最近披露的其他问题(比如说 inventory 列表构造问题),在交易池差异相对较大时,将不允许城市节点择机重组构造致密区块,会加重此处提到的问题。
一项缓解措施在 #27626 引入;该 PR 进入了 Bitcoin Core v26.0,并被反向移植到 v25.1 。它保证了最多可以向 3 个高带宽的致密区块对等节点并发请求区块,并且其中一个要求是出站连接。
致谢
该漏洞由 Greg Sanders 报告并修复。
CVE-2024-35202:通过触发 blocktxn 消息处理逻辑中的断言导致远端节点崩溃
在 Bitcoin Core v25.0 以前,攻击者可以通过触发 blocktxn 消息处理逻辑中的一个断言、远程导致 Bitcoin Core 节点崩溃。
详情
在通过 cmpcblock(致密区块)消息收取一个区块宣告时,Bitcoin Core会尝试使用本地交易池中的交易以及其它可用的交易数据、重新构造该消息宣告的区块。如果重构因为缺失了交易而失败,该节点就会向宣告区块的对等节点请求,通过 getblocktxn 消息。按照预期,在响应 blocktxn 消息时,对等节点会提供所请求的交易。
“致密区块” 协议使用了缩短的交易标识符,以节约带宽。这些短 id 的长度是 6 个字节,所以会有一个较小的碰撞概率(即,交易 A 与交易 B 具有相同的短 id)。在使用重新构造的交易集合来计算默克尔根时,这样的碰撞会被检测出来:计算出来的默克尔根与区块宣告消息中的并不一致。也不应该因为碰撞可能是虚假的而惩罚这个对等节点,因此,这是通过回退到请求完整的区块来处理的。
无论什么时候,收到一个新的致密区块时,Bitcoin Core 就创建一个 PartiallyDownloadedBlock 实例。如果请求到了缺失的交易,这个实例就持久化,直到相应的 blocktxn 消息处理完成。在收到 blocktxn 消息的时候,就调用 PartiallyDownloadedBlock::FillBlock 函数,尝试构造完整的区块。在上述碰撞情形中,节点会转而请求完整的区块,但这个 PartiallyDownloadedBlock 实例以及其它跟底层区块请求相关的状态就会搁置在一边。这就留下了空间,让同一个区块的第二条 blocktxn 消息能够得到处理,以及再次触发 FillBlock 调用。这违反了软件的运行的假设:FillBlock 只能被调用一次(作为一个 assert 断言语句有明确说明);并导致这个节点崩溃。
攻击者无需真的找出这样的碰撞,因为这个碰撞处理逻辑很容易可以通过直接在 blocktxn 消息中包含该区块的默克尔根并不承诺的交易来触发。
致谢
感谢 Niklak Gögge 发现并披露了这个漏洞,同时在 https://github.com/bitcoin/bitcoin/pull/26898 中修复了它。
inv-to-send 集合过大而导致的 DoS
在 Bitcoin Core v25.0 以前,按对等节点逐个分立的 m_tx_inventory_to_send 可能会变得过大,大到在构造 inventory 消息时为这些集合排序会影响节点与其它对等节点通信的能力。2023 年 5 月上旬的网络条件触发了这种 DoS 攻击,影响了区块和交易的传播。
这个问题被认为具有中等危险性。
详情
作为交易转发动作的一部分,Bitcoin Core 管理着一个按对等节点分立的 m_tx_inventory_to_send 集合,保存着应该向这些对等节点宣告的交易。在为一个对等节点构造一条 inventory 消息时,这个集合会按照交易的依赖性和手续费率先行排序,从而将高手续费率的交易排在前面,以及避免泄漏本节点收到这些交易的顺序。在 Bitcoin Core v25.0 以前,在构造 inventory 消息时,相关的(依然在交易池中、对等节点还没有向本地节点宣告、超过了费率门槛的)交易会被按照每秒 7 笔交易的速度提取出来。
在 2023 年 5 月上旬,增加的网络活动导致这些集合迅速膨胀,膨胀速度比抽取速度还要快,导致在 P2P 通信线程中给这些集合排序要消耗大量的时间。此外,有一些对等节点只会监听交易宣告、从来不会宣告交易(通常被称为 “间谍节点”),因为形成了巨大的集合而加剧了这个问题。有观察表明,排序几乎占用了 P2P 通信线程全部花费的时间,这显著影响了区块和交易传播,以及保持对等连接活性的难度。
该问题在 #27610 中修复,办法是:(1)更早移除已不在交易池中的交易;(2)根据集合的体积,动态地提高抽取交易的速度。
致谢
感谢 Anthony Towns 开发这一修复措施,以及 b10c 最初报告了这个问题,并将根源追溯到 inv-to-send 的排序。
CVE-2024-52921:变异区块所导致的区块传播停滞
在 Bitcoin Core v25.0 以前,一个对等节点发送变异的区块,可以导致本地节点对其他同样宣告了该区块的对等节点的下载状态清空,使区块传播停滞。
该问题被认为具有中等严重性。
详情
Bitcoin Core 会在(比如说)区块头中的默克尔根或者 coinbase 交易中的见证承诺(witness commitment)与该区块所包含的交易不匹配时,将该区块当成 “变异区块”。
在 Bitcoin Core v25.0 以前,一个对等节点可以通过发送未被请求的变异区块,使本地节点对其他对等节点的下载状态清空。这在(比如说)致密区块转发中就成了一个问题。在收到一个致密区块、发送了一条 getblocktxn 消息、等待响应(以重新构造完整区块)期间,收到一个变异区块会让 Bitcoin Core 忘记这个致密区块的重构状态。也就是说,在变异区块到达之后到来的 blocktxn 响应消息,将无法用来重构这个区块。这就阻碍了区块传播。
该问题在 #27608 中修复,办法是通过确保一个对等节点只能影响它自己的区块下载状态、不能影响其它节点的区块下载状态。
致谢
感谢 Suhas Daftuar 注意到这个问题并开发了修复措施。
CVE-2019-25220:区块头轰炸所导致的内存 DoS
在 Bitcoin Core v24.0.1 以前,攻击者可以使用低难度的区块头链来轰炸一个节点,这可以用来远程使一个节点崩溃。
该问题被认为具有高等严重性。
详情
Bitcoin Core 在内存中存储区块链的区块头。这使它很容易被 DoS 攻击:可以让它下载和存储非常长的区块头链,即使这些区块头都是低工作量证明难度的。重要的是,这样的区块头链一旦构造完成,就可以重复使用,导致网络中的任一节点崩溃。
使用这种方式来攻击节点的可能性一直为人所知,也是依然使用 “检查点(checkpoint)” 系统的首要理由:让攻击者只能从最新一个检查点开始,这比从创世区块开始要昂贵得多。但是,随着时间推移、哈希率的成本下降,即使这种缓解措施也会逐渐失效。
该攻击由 David Jaeson 在 2019 年 1 月独立发现并报告给 Bitcoin Core 项目;他也建议加入一种更新的检查点作为一种实用的缓解措施。然而:
- 执行初始化区块同步的节点,在收到检查点区块以前,依然是缺乏保护的。
- 检查点系统依赖于整个生态 准-定期 采用带有新检查点的更新版本软件,Bitcoin Core 的贡献者一直对这种做法感到不太舒服。
后来,这个问题因为 Braydon Fuller 与 2019 年 10 月在 bitcoin-dev 邮件组发出题为 “Chain width expansion(链宽度膨胀)” 的帖子而引起更多关注。此前,他曾经向 Bitcoin Core 安全邮件组尽责披露过这个问题。该文所建议的方法没有被 Bitcoin Core 采用,因为担心限制并行链条的数量会影响网络的收敛性。
那时候,创建一条巨大的低难度区块头链的计算成本,等价于挖出链顶端一个区块的 32.28% 。因此,成本大概是 4.12 BTC(因为那时候的区块奖励大概是 12.77 BTC )。
在 2022 年 2 月,攻击的成本进一步下降到挖出一个链顶端区块的 14.73% 。如不解决,今天(2024 年 9 月),这个成本将下降到区块挖掘成本的 4.44% 。这两个数字,根据这些日期的区块奖励,换算过来分别是 1.07 BTC 和 0.14 BTC .
Bitcoin Core PR #25717 实现了对抗这种 DoS 攻击的一种保护措施,节点会先验证一条链具有足够的工作量证明,然后才存储它。有了这种保护措施,Bitcoin Core 也不再依赖于检查点来对抗任何移植的攻击。
致谢
感谢 David Jaenson 和 Braydon Fuller 独立重新发现了这种攻击、评估了其成本以及提出了修改建议。
感谢 Suhas Daftuar 和 Pieter Wuille 研究出了一种令人满意的修复措施并实现了它。
CVE-2024-52919:addr 消息轰炸可引发远端节点崩溃
一种整数向上溢出 bug 会导致一个断言语句崩溃,修复措施已进入 2021 年 9 月 14 日发布的 Bitcoin Core v22.0 。
本问题被认为具有高等严重性。
详情
CAddMan 具有一个 32 比特长的 nIdCount 字段,每次向 addrman 数据库插入时,该字段的数值就递增,并且该值也成为新条目的标识符。通过让受害者节点插入 232 个条目(比如说,通过 addr 消息轰炸),这个标识符的数值就会向上溢出,导致一条断言语句崩溃。
致谢
感谢 Eugene Siegel 发现并披露这个漏洞,Pieter Wuille 在 https://github.com/bitcoin/bitcoin/pull/22387 中修复这个漏洞。
CVE-2024-52917:miniupnp 依赖库中的无限循环 bug
披露 Bitcoin Core 的 miniupnp 依赖库中的一个无限循环 bug 所造成的影响,修复措施已进入 2021 年 9 月 14 日发布的 Bitcoin Core v22.0 。
本问题被认为具有低等严重性。
详情
Miniupnp 是 Bitcoin Core 为 UPnP 网络协议而使用的代码库;只要它从网络中的一个设备处收到了随机数据,就会一直等待发现。此外,它还会为每一个新的设备信息分配一段内存。本地网络中的一个攻击者可以伪装成一个 UPnP 设备、不断向 Bitcoin Core 发送臃肿的 M-SEARCH 汇入,直至该节点的内存耗尽。
只有使用了 -miniupnp 运行选项的用户会受该漏洞影响;否则的话,Miniupnp 默认是关闭的。
致谢
感谢 Ronald Huveneers 向 miniupnp 项目报告这个无限循环 bug,以及 Michael Ford (Fanquake) 向 Bitcoin Core 项目报告这个漏洞,还提供了触发一次内存溢出(OOM)的验证验证(PoC),并发起代码合并请求来取消依赖关系(包含修复措施)。
Bitcoin Core 2025-11-24
https://www.btcstudy.org/2025/11/24/disclosure-of-vulnerabilities-affecting-bitcoin-core-versions-before-25-0-bitcoin-core/