Vulnerabilidade na carteira de hardware Coldcard leva ao roubo de mais de US$ 88 milhões em bitcoin

iconMetaEra
Compartilhar
AI summary iconResumo
Uma falha na carteira de hardware Coldcard relacionada a um RNG mal configurado resultou no roubo de mais de 594 BTC, avaliados em mais de US$ 88 milhões. O problema afetou os modelos Coldcard Mk2, Mk3, Mk4, Q e Mk5, expondo chaves privadas a ataques de força bruta. A Beosin rastreou os fundos agregados para várias endereços de Bitcoin. O incidente levanta preocupações sob a CFT e destaca a urgência de conformidade com o MiCA, à medida que a UE aperta as regulamentações de criptoativos.

Perda superior a US$ 88 milhões: Análise da vulnerabilidade da carteira de hardware Coldcard e rastreamento dos fundos roubados Em 31 de julho, aproximadamente 500 carteiras de hardware Coldcard foram roubadas, totalizando 594 bitcoins, com valor aproximado de US$ 38 milhões. Posteriormente, a Coinkite, empresa responsável pela produção das carteiras Coldcard, confirmou a existência de uma vulnerabilidade de segurança no processo de geração de chaves, afetando múltiplas gerações de produtos, incluindo Coldcard Mk2, Mk3, Mk4, Q e Mk5.

Atualmente, o valor perdido devido a este ataque de vulnerabilidade já ultrapassou US$ 88 milhões, e o ataque ainda está em andamento. Os usuários do Coldcard devem transferir seus fundos para outros endereços o mais rápido possível. A seguir, apresentamos a análise da Beosin sobre esta vulnerabilidade e o rastreamento dos fundos roubados.

I. Análise de vulnerabilidade

Analisando o histórico de commits do firmware do Coldcard, pode-se observar que, no commit anterior 37e4af5451c260c1e7d429fe8972c4cb5e68ee59, a equipe de desenvolvimento atualizou vários trechos de código relacionados à configuração do MK4, incluindo em mpconfigboard.h:

// Temos nossa própria versão deste código.#define MICROPY_HW_ENABLE_RNG       (0)

Na plataforma MicroPython STM32, este macro controla o caminho de compilação para o gerador de números aleatórios de hardware padrão (RNG) e a implementação geral de números aleatórios. Defini-lo como 0 faz com que o caminho do RNG de hardware padrão não seja usado como backend para rng_get().

Seu comentário indica que o desenvolvedor implementará o RNG; ao verificar o rng.h personalizado, descobriu-se que apenas dois objetos MicroPython foram declarados:

MP_DECLARE_CONST_FUN_OBJ_0(pyb_rng_get_obj);MP_DECLARE_CONST_FUN_OBJ_1(pyb_rng_get_bytes_obj);

A implementação correspondente é:

/// \function pyb_rng_get()///// Retorna um número aleatório gerado por hardware de 30 bits: ou falha!//STATIC mp_obj_t pyb_rng_get(void){    // Obter e retornar o novo número aleatório    return mp_obj_new_int(rng_get_or_fault() >> 2);}
/// \function rng_get_bytes()/// Preenche um buffer com bits aleatórios; o chamador deve fornecer um buffer dimensionado.STATIC mp_obj_t pyb_rng_get_bytes(mp_obj_t buffer_io) {
    mp_buffer_info_t bufinfo;    mp_get_buffer_raise(buffer_io, &bufinfo, MP_BUFFER_WRITE);
    mp_uint_t count = bufinfo.len;    if(count < 1) {        mp_raise_ValueError(NULL);    }
    // Ler palavras de 32 bits e desempacotar no buffer fornecido    random_buffer(bufinfo.buf, count);
    return mp_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() lê diretamente o periférico RNG do STM32:

static uint32_t rng_get_or_fault(void){    // Habilita o periférico RNG, se ainda não estiver habilitado    rng_init();
    // Aguarda até que um novo número aleatório esteja pronto, levando aproximadamente 10us    uint32_t start = HAL_GetTick();
    while (!(RNG->SR & RNG_SR_DRDY)) {        if (HAL_GetTick() - start >= RNG_TIMEOUT_MS) {            // falha de hardware... não retorne nada!            mp_raise_OSError(MP_EFAULT);        }    }
    // Obtém e retorna o novo número aleatório    last_value = RNG->DR;
    return last_value;}

Isso indica que o código personalizado do Coldcard realmente deseja usar o RNG de hardware, mas garante apenas o uso dessa função de hardware ao chamar pyb_rng_get* ou seu internal random_buffer().

E durante a criação da carteira, o código a seguir é realmente chamado, onde a função de criação de carteira em shared/seed.py é:

async def make_new_wallet(nwords):    # Escolha uma nova semente aleatória.    await ux_dramatic_pause('Gerando...', 3)    seed = generate_seed()    words = await approve_word_list(seed, nwords)    if words:        await commit_new_words(words)

Essa chamada entra primeiro no módulo shared/random.py do Coldcard. Nas versões anteriores, o random.py dependia explicitamente do ngu.random e mantinha:

# random.py - subconjunto do módulo random, sem compatibilidade e usando RNG de qualidade criptográfica  
# para bytes, use ngu.random.byte(len)  
# bytes = ngu.random.bytes

Ou seja, o wallet initialization usa random.bytes, não pyb.rng(), e pyb_rng_get_obj personalizado não substitui automaticamente random.bytes.

Como MICROPY_HW_ENABLE_RNG foi definido como 0, ao gerar a carteira não foi utilizado o RNG de hardware, mas sim pyb_rng_yasmarang de micropython/ports/stm32/rng.c:

#if MICROPY_HW_ENABLE_RNG
uint32_t rng_get(void) {    // use STM32 hardware RNG    ...}
#else
// Para MCUs que não possuem RNG, ainda precisamos fornecer uma função rng_get()// Um pseudo-RNG não é realmente ideal, mas vamos adotá-lo por enquanto.
// Gerador de números aleatórios Yasmarangstatic uint32_t pyb_rng_yasmarang(void) {    static bool seeded = false;    static uint32_t pad = 0, n = 0;    ...}
uint32_t rng_get(void) {    return pyb_rng_yasmarang();}
#endif

E pyb_rng_yasmarang é um gerador de números pseudoaleatórios, sendo muito inseguro para geração de sementes de carteiras de hardware; atacantes podem obter a chave por força bruta. Atualmente, a Coinkite já excluiu explicitamente stm32/rng.c no arquivo makefile:

# Não compile o PRNG de fallback do MicroPython. O rng.c específico da placa
# fornece rng_get(), e este objeto vazio satisfaz a lista de objetos upstream.
$(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 $@

II. Rastreamento de fundos roubados

Atualmente, os fundos de várias carteiras de vítimas já foram transferidos e reunidos, armazenados em vários endereços, ainda não realizada a lavagem adicional. A Beosin Trace, por meio de inteligência de ameaças e análise de comportamento na cadeia, monitorou os seguintes endereços de reunião:

bc1qq85v2c926eg6pgxhwp6q7lf6cnsz80qs3fcu9r (562 BTC)

https://wdcdn.qpic.cn/MTMxMDI3MDE1MTgxMDU0NzA_369595_usmImxZpHsKmu9X__1785899827?w=1080&h=656

bc1qx76cae2706qd5q576feh7xq8rfcsjpf2htfhe3 (398,47 BTC)

https://wdcdn.qpic.cn/MTMxMDI3MDE1MTgxMDU0NzA_304781_-IeWjFtIQ4RhvCbz_1785899827?w=1080&h=674

Além disso, existem os seguintes endereços de coleta, cujos fluxos de fundos são semelhantes ao gráfico acima, e até o momento não houve transferências adicionais:

  • bc1q8jy96fe5lf8vfugydnte3cguk92gpev7kwtp3q (89,62 BTC)
  • bc1q0rvn88w08j75k4h48lf9fvhan7unjp7vjf5q6m (64,9 BTC)
  • bc1qtfrwa4j6rmj9rsgspv6a0yjumkg39js2numu75 (45,9 BTC)
  • bc1qmd5m5ktv7m5ffujxv4248fxv36myvdx79n8jp6 (30,18 BTC)

Ataques contra a carteira Coldcard ainda estão em andamento, e a equipe da Beosin continua monitorando endereços de coleta adicionais e analisando os fluxos de fundos relacionados.

III. Conclusão

Este grave incidente de segurança no hardware wallet Coldcard surgiu de um erro na implementação da geração de números aleatórios pela equipe de desenvolvimento, que utilizou um gerador de números pseudoaleatórios no processo crítico de geração da semente da carteira. A equipe de desenvolvimento deve realizar testes e auditorias contínuos e abrangentes no código, enquanto os usuários da carteira Coldcard devem transferir seus ativos o mais rápido possível e manter-se atentos aos próximos comunicados de segurança da Coinkite.

Beosin é uma empresa líder em segurança blockchain e tecnologia de conformidade regulatória, especializada em auditoria de segurança de contratos inteligentes antes do lançamento de projetos, monitoramento e bloqueio de riscos de segurança durante a operação dos projetos, recuperação de ativos roubados, combate à lavagem de dinheiro (AML) para ativos virtuais e investigação e rastreamento. A Beosin já forneceu produtos e serviços de conformidade blockchain “tudo-em-um” para 200+ provedores de ativos virtuais e 4.500+ projetos Web3 em mais de 20 países e regiões globais.

Aviso legal: as informações nesta página podem ter sido obtidas de terceiros e não refletem necessariamente os pontos de vista ou opiniões da KuCoin. Este conteúdo é fornecido apenas para fins informativos gerais, sem qualquer representação ou garantia de qualquer tipo, nem deve ser interpretado como aconselhamento financeiro ou de investimento. A KuCoin não é responsável por quaisquer erros ou omissões, ou por quaisquer resultados do uso destas informações. Os investimentos em ativos digitais podem ser arriscados. Avalie cuidadosamente os riscos de um produto e a sua tolerância ao risco com base nas suas próprias circunstâncias financeiras. Para mais informações, consulte nossos termos de uso e divulgação de risco.