Back to Blog

~$8800万损失:COLDCARD与LULA漏洞利用事件 | BlockSec周报

Code Auditing
August 5, 2026
11 min read
Key Insights

在过去一周(2026/07/27 - 2026/08/02),以下 2 起重大安全事件受到关注,合计造成约 $88M 的损失。

日期 事件 类型 预估损失
2026/07/29 LULA 业务逻辑缺陷 ~$578K
2026/07/30 COLDCARD 熵生成缺陷 ~1,370 BTC (~$88M)*

* COLDCARD 的损失因确认方式不同而有所差异:所示的 ~1,370 BTC (~$88M) 为可公开验证的链上最低值(coldcardwatch.com);通过私下渠道核实(Galaxy Research,来自与 73 名受害者的通信)的数字更高,约为 1,596 BTC,若将疑似但未经确认的转移纳入统计,则高达 ~2,055 BTC (~$130M)。

入选原因

  • LULA:一个可操控 AMM 交易对余额并强制重新同步储备金的特权代币函数,通过价格操控成为可反复利用的流动性耗尽原语。
  • COLDCARD:钱包固件中的构建与集成错误,导致种子生成过程静默地路由至确定性软件回退路径,破坏了熵保证,使种子恢复变成一个可离线搜索的问题,并最终演变为大规模资金损失。

Web3 领域最佳安全审计机构

在上线前验证设计、代码和业务逻辑

每周重点:COLDCARD

我们选择 COLDCARD 作为本周重点,因为一个钱包熵缺陷造成了本期最大损失。根本原因——一个构建守卫检查的是配置宏是否存在,而非是否已启用——是功能测试无法捕捉到的静默集成错误,这一教训适用于任何链上安全依赖于链下随机性的系统。

COLDCARD 是一款比特币硬件钱包,其于 2021 年发布的固件在生成钱包种子时,使用的是确定性软件来源,而非预期的硬件随机数生成器(RNG)[1][2]。该缺陷直至 2026 年 7 月下旬才被大规模利用,受影响的钱包于 7 月 30 日开始遭到链上批量清空:公开确认的损失至少为 1,370 BTC(约 $88M,以 8 月 5 日 $64,099 的价格计算)[3],而私下确认的报告将这一数字提高至约 1,596 BTC [4]。根本原因是一个构建与配置错误,将种子生成路由到了软件回退路径,而非预期的硬件 RNG。对于受影响的设备,这使得种子恢复从密码学上不可行的问题变成了一个离线搜索问题。

背景

COLDCARD 是一款比特币硬件钱包。钱包的私钥和地址均派生自一个单一的秘密值——种子,因此任何自托管钱包的安全性取决于该种子的两个属性:保密性以及生成时的不可预测性。硬件钱包的存在主要是为了保护前者;而本次事件是后者的失败。BIP-39 助记词对人类可读,但不可预测性要求背后的安全属性,仍然是用于创建它的随机字节的熵。如果这些字节可以被复现,种子就可以被复现。直觉上,这就像一个保险箱,其密码是通过掷骰子来选择的:如果骰子被做了手脚,那么任何知道偏差的人都可以打开保险箱,无论锁有多坚固。

对于钱包来说,"做了手脚的骰子"意味着弱随机数生成器。硬件钱包预期从其安全微控制器上的硬件真随机数生成器(TRNG)获取种子熵,因为软件伪随机数生成器(PRNG)是确定性的:给定其内部状态和调用历史,其输出可以被精确重放。如果生成器的输出是可预测的,其候选范围就可以被枚举,并与公开钱包数据(如地址、xpub 或公钥)进行匹配,从而将种子恢复从密码学上不可行的问题降格为离线搜索。

COLDCARD 的固件暴露了两个独立的 RNG 接口。MicroPython 附带了一个 STM32 平台层,该层暴露了钱包加密库所需的全局 rng_get() 符号,而 COLDCARD 也维护着自己的板级本地硬件 RNG 封装。两个接口均旨在提供硬件熵,钱包的加密库通过固件构建时解析的单一全局 RNG 符号访问其中之一。

漏洞分析

根本原因是围绕 MICROPY_HW_ENABLE_RNG 配置宏的构建与集成错误。COLDCARD 的生产板配置将此宏设置为 0,因为固件本意是使用其自己的板级本地硬件 RNG 封装,而非 MicroPython 的硬件 RNG 实现。然而,钱包生成路径已迁移至 ngu.random.bytes(32),而加密库的 STM32 路径最终依赖于由 MicroPython 解析的全局 rng_get() 符号。

问题链如下:

generate_seed()
  -> ngu.random.bytes(32)
  -> libngu CHIP_TRNG_32()
  -> rng_get()
  -> MicroPython STM32 RNG 模块
  -> 由于 MICROPY_HW_ENABLE_RNG == 0,回退至 Yasmarang 软件实现

板级配置禁用了 MicroPython 的硬件 RNG 分支:

// We have our own version of this code.
#define MICROPY_HW_ENABLE_RNG (0)

加密库仍将该宏视为存在硬件 RNG 的充分证明 [5],因为它在调用 rng_get() 之前仅检查宏是否存在:

extern uint32_t rng_get(void);
#define CHIP_TRNG_32() rng_get()

#ifndef MICROPY_HW_ENABLE_RNG
#error "get a HW TRNG plz"
#endif

该守卫遗漏了危险情况:一个被定义为 0 的宏仍然是已定义的,因此 #ifndef 检查通过,构建成功。由于 MicroPython 根据宏的而非其存在性来选择 RNG 实现,MICROPY_HW_ENABLE_RNG == 0rng_get() 路由到了软件回退分支,而非 COLDCARD 的板级本地封装 [6]

#if MICROPY_HW_ENABLE_RNG
    // STM32 硬件 RNG
#else
    // Yasmarang 软件回退
#endif

不同设备代次的影响有所不同。对于搭载 v4.0.0-v4.1.9 固件的 Mk2/Mk3,Block 的分析 [7] 指出,没有任何密码学熵被添加到 ngu.random,因此一旦回退状态和调用历史已知,钱包生成就可能变得确定性(Coinkite 的公告 [2] 将 Mk2/Mk3 的范围略微收窄,定为 v4.0.1-v4.1.9)。对于 Mk4/Q/Mk5,安全元件材料被哈希处理,但仅有四个字节被传入 ngu.random.reseed(),将安全重播种限制在单个 32 位状态字,远少于用户所期望的钱包熵搜索空间。对最终 32 个随机字节进行哈希处理无法增加结果的熵;它只是对一个已经受限的候选集进行变换。

攻击分析

与智能合约漏洞利用不同,本次事件没有单一的链上攻击交易可供追踪。这是一个离线种子恢复问题,随后在链上进行了批量清空。前提条件是,受影响用户已通过存在漏洞的 ngu.random.bytes(32) 路径生成了他们的钱包种子,因此其种子材料依赖于可复现的软件回退状态,而非完整的硬件熵。第二个推断出的前提条件是,受影响的钱包仅凭种子即可派生:强大且唯一的 BIP-39 密语通过 PBKDF2 混入了独立的、由用户提供的熵,这部分熵从未被 RNG 缺陷触及,使得此类钱包超出了纯种子枚举的范围;而大规模清空的规模表明,大多数受影响用户没有设置此类密语。在此基础上,恢复过程可能经历了三个步骤:

  1. 攻击者利用设备元数据、启动时序、RTC/SysTick 假设以及合理的 RNG 调用历史,对候选 RNG 状态进行了约束或枚举。
  2. 对于每个候选状态,攻击者派生候选钱包种子,并将其与地址、xpub 或生成的公钥等公开钱包数据进行离线匹配。
  3. 一旦某个候选值与真实钱包匹配,攻击者便恢复种子、重建私钥,并清空相关 BTC。

在链上,盗窃表现为从 7 月 30 日开始的一波地址清空浪潮。独立的链上启发式追踪 [3] 识别出数波清空操作,从 4,580 个已验证地址中合计至少清空了 1,370 BTC(约 $88M,以 8 月 5 日 BTC 价格 $64,099 计值),这是已验证的最低值,而非总量。与此同时,一个私下渠道 [4](通过与 73 名受害者的通信确认)将这一数字提高至约 1,596 BTC,若纳入疑似但未经确认的转移,则升至 2,055 BTC(约 $130M)。

结论

COLDCARD 事件是一次熵生成失败:安全关键的种子生成 API 静默地解析为确定性软件 PRNG 回退,而非预期的硬件 RNG,原因在于构建守卫检查的是配置宏是否存在,而非是否已启用。对于受影响的设备,这使得种子恢复从密码学上不可行的问题变成了离线搜索,最终导致超过 1,370 BTC [3] 在多波操作中被清空(私下渠道的统计将其定为约 1,596 至 2,055 BTC [4])。

核心工程失误在于,已发布的固件从未证明其最关键的安全 API 实际上到达了预期的硬件 RNG。以下三种实践本可发现该问题:用于密码学熵的构建守卫必须同时检查宏的存在性和宏的值;熵回退必须以失败关闭(fail closed)的方式运作,而非静默替换为软件 PRNG;对最终固件镜像的验证应覆盖符号来源和端到端熵流,而不仅仅是代码能否编译通过。受影响的种子无法原地修复;其资金应转移至使用已修复固件创建的钱包,而设置强大且唯一的密语可在不修复种子的情况下降低即时风险 [2]

这种失败模式值得特别强调:此类随机性缺陷对功能测试是不可见的,因为每个生成的种子在个体上都是有效的。缺陷不在于任何单个输出,而在于产生它们的来源:由于该来源是可预测且可复现的,这些种子整体上落入了一个小的、可枚举的范围内。链下密钥生成组件理应受到一流的安全审查。

参考资料

开始使用 Phalcon Explorer

深入分析交易,做出明智决策

免费立即体验

本周更多事件

LULA

LULA 是 BNB Chain 上的一个 BEP-20 代币,于 2026 年 7 月 29 日因其代币合约中的业务逻辑缺陷损失约 $578K。攻击者可通过一条可访问的路径触发其特权函数 recycle(),使 Rental 合约将 LULA 直接从 PancakeSwap V2 交易对中转出,然后调用 sync() 将交易对的储备金更新为被操控后的余额。攻击者反复触发 recycle(),将交易对的 LULA 储备金压缩至接近零,随后用少量 LULA 换回了交易对中几乎全部的 USDT [1]

背景

LULA 是 BNB Chain 上的一个 BEP-20 代币,具有基于租赁的团队奖励机制。符合条件的地址在 Rental 合约中累积待领取的团队奖励,并通过 claimTeamReward() 进行领取。在领取流程中,Rental 合约调用代币的 recycle() 函数以获取用于奖励分发的 LULA。recycle() 不能被任意用户调用;仅有 Rental 合约被授权执行该函数。

claimTeamReward() 入口点包含一个"仅限 EOA"检查。它支持来自外部拥有账户的直接调用(其中 msg.sender == tx.origin),同时也通过检查委托代码前缀来支持 EIP-7702 委托调用。

在自动化做市商(AMM)中,交易对根据其存储的储备金对交换进行定价,这些储备金通过交易对的 sync() 函数进行更新,该函数将储备金设置为交易对的当前代币余额。储备金通常随真实交易而变动,因为它们会随着交换和流动性事件移动,但交易对的代币余额也可以通过直接转账来改变,而 sync() 会将当前余额——无论是否被操控——复制到存储的储备金中。

漏洞分析

根本原因在于 LULA.recycle() 允许 Rental 合约将 LULA 直接从 PancakeSwap V2 交易对中转出,然后调用 sync() 将交易对的储备金更新为被操控后的余额 [1]

由于 sync() 将储备金设置为交易对中剩余的 LULA 余额,这条特权路径可以将交易对的 LULA 储备金任意压低,同时保持 USDT 一侧不受影响。一旦 LULA 储备金接近零,交易对就会将少量 LULA 定价为几乎等同于其全部 USDT。

攻击分析

以下分析基于交易 0xa219ab9...411d7c

  • 步骤 1:攻击者通过积累约 1.9705 亿 USDT 为操控提供资金。资金来源于多个闪电贷和借贷来源,包括 Moolah/Lista、Aave V3、Venus、PancakeSwap V3、PancakeSwap Vault、Uniswap V4 PoolManager 和 Uniswap V3。
  • 步骤 2:攻击者使用约 1.9705 亿 USDT,通过 PancakeSwap V2 路由器执行了一笔大额 USDT -> LULA 兑换。这使交易对的 LULA 储备金从约 800 万 LULA 急剧减少至 24,022 LULA,同时将 USDT 一侧增加至约 1.9764 亿 USDT。
  • 步骤 3:攻击者通过多个 EIP-7702 钱包调用奖励路径。每个钱包在 Rental 合约上调用 claimTeamReward(),进而触发 LULA.recycle(),将交易对的 LULA 储备金从 24,022 LULA 压缩至 0.004 LULA,而此时交易对仍持有大量 USDT。
  • 步骤 4:攻击者通过路由器执行最后一笔 PancakeSwap V2 兑换,仅向交易对注入约 4,749 LULA,收到约 1.9764 亿 USDT。
  • 步骤 5:攻击者偿还所有闪电贷,获利约 $578K。

结论

BNB Chain 上的 LULA 代币因其代币合约中的业务逻辑缺陷被利用,损失约 $578K:攻击者可通过一条可访问的路径触发其特权函数 recycle(),使 Rental 合约将 LULA 直接从 PancakeSwap V2 交易对中转出,然后调用 sync() 将交易对的储备金重新同步为被操控后的余额。攻击者反复触发此操作以扭曲交易对价格,并用少量 LULA 换回了几乎全部 USDT。

代币合约绝不应暴露可以移动 AMM 交易对余额并强制储备金重新同步的特权路径,因为这样做会将价格控制权交给任何能够访问该路径的人。与 AMM 交易对集成的代币必须确保交易对的储备金仅随真实的、由市场驱动的余额变化而更新,任何读取流动池储备金进行定价的逻辑都应将其视为可被操控的,而非权威可信的。

参考资料

Sign up for the latest updates
通讯简报 - 2026年7月
Security Insights

通讯简报 - 2026年7月

2026年7月,三起最大DeFi事件共造成约6790万美元损失,涉及Arbitrum和Solana。AFX Trade因供应链攻击导致验证者签名权被盗,损失约2415万美元;Ostium的OLP金库因预言机基础设施被攻破,攻击者提交恶意价格,损失约2375万美元;BonkDAO攻击者花费440万美元获取足够投票权,通过恶意国库转账提案,损失约2000万美元。三起事件均表明协议安全边界远超智能合约代码本身。

~$3950万美元损失:Allbridge、Wanchain等项目 | BlockSec周报
Security Audits

~$3950万美元损失:Allbridge、Wanchain等项目 | BlockSec周报

2026年7月20-26日,Solana、以太坊、BNB Chain、Arbitrum、Zilliqa和Cardano共发生8起重大安全事件,总损失约3950万美元。其中Allbridge Core事件(约165万美元)暴露了Solana输入验证漏洞,同一Pool账户被同时接受为两种swap角色;Wanchain(约50万美元,Cardano桥验证器消息编码缺陷);Zilliqa(约40万美元,Ledger应用自2019年存在的随机数生成缺陷);Lien Finance(约54.2万美元,债券交易验证逻辑缺陷)。

~$135万损失:BarnBridge、DeFiTuna | BlockSec周报
Security Insights

~$135万损失:BarnBridge、DeFiTuna | BlockSec周报

本周报涵盖2026年7月13日至19日的2起安全事件,以太坊和Solana总损失约135万美元。Solana借贷协议DeFiTuna损失约57万美元,原因是仓位健康检查将零值仓位视为健康状态而忽略未偿债务,攻击者利用受控掉期路由和低流动性池触发此漏洞。BarnBridge损失约77.6万美元,攻击者利用以太坊上已弃用但仍活跃的治理系统通过恶意提案,盗取用户授权的USDC。

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit