损失超8800万美元:Coldcard硬件钱包漏洞分析与被盗资金追踪

  • 安全漏洞:因MICROPY_HW_ENABLE_RNG设为0,钱包种子生成使用伪随机数,可被暴力破解。
  • 影响范围:涉及Coldcard Mk2至Mk5多代产品,被盗约594 BTC(3800万美元),损失已超8800万美元,攻击持续。
  • 资金追踪:攻击者已将资金归集至多个地址,如bc1qq85v2...3fcu9r (562 BTC)、bc1qx76cae2706qd5q576feh7xq8rfcsjpf2htfhe3 (398.47 BTC)等。
  • 用户建议:立即将资产转移至安全钱包,关注Coinkite安全公告。
总结

7月31日,约500个Coldcard硬件钱包共计594枚比特币被盗,价值约3800万美元。随后负责生产Coldcard钱包的公司Coinkite确认该产品在密钥生成环节存在安全漏洞,涉及Coldcard Mk2、Mk3、Mk4、Q和Mk5等多代产品。

目前,针对此漏洞攻击造成的损失金额已超过8800万美元,且攻击仍在持续,Coldcard钱包用户应尽快将资金转移至其它地址。Beosin对本次漏洞的分析及相关被盗资金的追踪情况如下。

一、漏洞分析

分析Coldcard firmware代码的提交记录,可以发现在此前的Commit 37e4af5451c260c1e7d429fe8972c4cb5e68ee59中,开发团队更新了多个关于MK4配置的代码,在mpconfigboard.h中包含:

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

在 MicroPython STM32 端,这个宏控制默认硬件随机数生成器 (RNG) 绑定和通用随机数实现的编译路径。将其设为 0 导致默认硬件 RNG 路径不会作为通用 rng_get() 的后端使用

其备注说明开发者会自行实现 RNG,检查其自定义的rng.h发现只声明了两个MicroPython对象:

MP_DECLARE_CONST_FUN_OBJ_0(pyb_rng_get_obj);MP_DECLARE_CONST_FUN_OBJ_1(pyb_rng_get_bytes_obj);

对应的实现为:

/// \function pyb_rng_get()///// Return a 30-bit hardware generated random number: or fail!//STATICmp_obj_tpyb_rng_get(void){ // Get and return the new random number returnmp_obj_new_int(rng_get_or_fault() >>2);}
/// \function rng_get_bytes()/// Fill a buffer with random bits; caller must provide sized buffer.STATICmp_obj_tpyb_rng_get_bytes(mp_obj_tbuffer_io){
 mp_buffer_info_tbufinfo; mp_get_buffer_raise(buffer_io, &bufinfo, MP_BUFFER_WRITE);
 mp_uint_tcount = bufinfo.len; if(count <1) {   mp_raise_ValueError(NULL);  }
 // Read 32-bit words and unpack into provided buffer random_buffer(bufinfo.buf, count);
 returnmp_const_none;}
MP_DEFINE_CONST_FUN_OBJ_0(pyb_rng_get_obj, pyb_rng_get);MP_DEFINE_CONST_FUN_OBJ_1(pyb_rng_get_bytes_obj, pyb_rng_get_bytes);

rng_get_or_fault() 本身读取 STM32 RNG 外设:

staticuint32_trng_get_or_fault(void){ // Enable the RNG peripheral if it's not already enabled rng_init();
 // Wait for a new random number to be ready, takes on the order of 10us uint32_tstart =HAL_GetTick();
 while(!(RNG->SR & RNG_SR_DRDY)) {   if(HAL_GetTick() - start >= RNG_TIMEOUT_MS) {     // hardware failure... do not return anything!     mp_raise_OSError(MP_EFAULT);    }  }
 // Get and return the new random number  last_value = RNG->DR;
 returnlast_value;}

这说明 Coldcard 自定义代码确实想要使用硬件 RNG,但它只保证调用 pyb_rng_get* 或其内部 random_buffer() 时使用该硬件函数。

而在钱包创建时实际调用的是以下代码,其中 shared/seed.py 中的钱包创建函数为:

asyncdefmake_new_wallet(nwords): # Pick a new random seed. awaitux_dramatic_pause('Generating...',3)  seed = generate_seed()  words =awaitapprove_word_list(seed, nwords) ifwords:   awaitcommit_new_words(words)

该调用首先进入 Coldcard 的 shared/random.py 模块。历史版本中,random.py 明确依赖 ngu.random,并保留:

# random.py - subset of random module, with no compat, and using crypto-quality rng# for bytes, use ngu.random.byte(len)#bytes = ngu.random.bytes

即钱包初始化所用的是 random.bytes,不是 pyb.rng(),自定义的 pyb_rng_get_obj 并未自动覆盖 random.bytes。

由于 MICROPY_HW_ENABLE_RNG 被设为 0 ,钱包生成时并没有使用硬件 RNG,而是调用了micropython/ports/stm32/rng.c的pyb_rng_yasmarang:

#ifMICROPY_HW_ENABLE_RNG
uint32_trng_get(void){ // use STM32hardware RNG  ...}
#else
// For MCUs that don't have an RNG we still need to provide a rng_get() function// A pseudo-RNG is not really ideal but we go with it for now.
// Yasmarang random number generatorstaticuint32_tpyb_rng_yasmarang(void){ staticboolseeded =false; staticuint32_tpad =0, n =0;  ...}
uint32_trng_get(void){ returnpyb_rng_yasmarang();}
#endif

而pyb_rng_yasmarang 是伪随机数生成器,作为硬件钱包种子生成是非常不安全的,攻击者可以通过暴力破解获得密钥。目前,Coinkite已在makefile文件中明确排除了 stm32/rng.c:

# Do not compile MicroPython's fallback PRNG. The board-specific rng.c
# provides rng_get(), and this empty object satisfies the upstream object list.
$(BUILD)/rng.o:CFLAGS+= -Dpyb_rng_yasmarang=error-do-not-want-this
$(BUILD)/rng.o:
$(ECHO)"SKIP stm32/rng.c"
$(Q)$(CC)$(CFLAGS) -x c -c /dev/null -o$@

二、被盗资金追踪

目前,已有多个受害者钱包的资金被转移并完成归集,存放在多个地址中,还未做进一步的清洗Beosin Trace通过威胁情报及链上行为分析,监测到以下归集地址:

bc1qq85v2c926eg6pgxhwp6q7lf6cnsz80qs3fcu9r(562 BTC)

bc1qx76cae2706qd5q576feh7xq8rfcsjpf2htfhe3(398.47 BTC)

此外,还有以下归集地址,其资金流向图与上图类似,目前并未有进一步的转移:

  • bc1q8jy96fe5lf8vfugydnte3cguk92gpev7kwtp3q (89.62 BTC)
  • bc1q0rvn88w08j75k4h48lf9fvhan7unjp7vjf5q6m(64.9 BTC)
  • bc1qtfrwa4j6rmj9rsgspv6a0yjumkg39js2numu75(45.9 BTC)
  • bc1qmd5m5ktv7m5ffujxv4248fxv36myvdx79n8jp6(30.18 BTC)

针对Coldcard钱包的攻击仍在进行,Beosin团队正持续监测更多归集地址及分析相关资金流向。

三、结语

此次Coldcard硬件钱包的重大安全事故源于开发团队对于随机数生成的实现错误,在关键的钱包种子生成环节使用了伪随机数生成。开发团队应对代码进行持续、全面的测试与审计,而Coldcard钱包用户应尽快完成资产的转移,并密切关注Coinkite后续的安全公告。

Beosin是一家领先的区块链安全与监管合规科技公司,专注于项目上线前的智能合约安全审计、项目运行时的安全风险监控与阻断、被盗追回、虚拟资产反洗钱(AML)以及调查追踪。Beosin已为全球20多个国家和地区的监管与执法机构、200多家虚拟资产服务商以及4500多家Web3项目提供“一站式”区块链合规产品+安全服务。

分享至:

作者:Beosin

本文为PANews入驻专栏作者的观点,不代表PANews立场,不承担法律责任。

文章及观点也不构成投资意见

图片来源:Beosin如有侵权,请联系作者删除。

关注PANews官方账号,一起穿越牛熊
PANews APP
谷歌正与AI公司Mechanize洽谈价值超过15亿美元的交易
PANews 快讯