Kerentanan Coldcard Hardware Wallet Menyebabkan Pencurian Bitcoin Lebih dari $88 Juta

iconMetaEra
Bagikan
AI summary iconRingkasan
Kerentanan pada dompet perangkat keras Coldcard yang terkait dengan RNG yang salah konfigurasi menyebabkan pencurian lebih dari 594 BTC, senilai lebih dari $88 juta. Masalah ini memengaruhi model Coldcard Mk2, Mk3, Mk4, Q, dan Mk5, sehingga kunci pribadi terpapar terhadap serangan brute-force. Beosin telah melacak dana terkumpul ke beberapa alamat Bitcoin. Kejadian ini menimbulkan kekhawatiran di bawah CFT dan menyoroti urgensi kepatuhan terhadap MiCA seiring UE memperketat regulasi kripto.

Kerugian melebihi $88 juta: Analisis kerentanan Coldcard hardware wallet dan pelacakan dana yang dicuri Pada 31 Juli, sekitar 500 unit hardware wallet Coldcard kehilangan total 594 bitcoin, senilai sekitar $38 juta. Selanjutnya, perusahaan yang bertanggung jawab memproduksi wallet Coldcard, Coinkite, mengonfirmasi adanya kerentanan keamanan pada proses generasi kunci, yang memengaruhi berbagai generasi produk Coldcard seperti Mk2, Mk3, Mk4, Q, dan Mk5.

Saat ini, kerugian akibat serangan terhadap kerentanan ini telah melebihi $88 juta, dan serangan masih berlangsung. Pengguna Coldcard wallet sebaiknya segera memindahkan dana mereka ke alamat lain. Berikut adalah analisis Beosin terhadap kerentanan ini dan pelacakan dana yang dicuri.

Satu, analisis kerentanan

Menganalisis riwayat commit kode firmware Coldcard, dapat ditemukan bahwa pada commit sebelumnya 37e4af5451c260c1e7d429fe8972c4cb5e68ee59, tim pengembang memperbarui beberapa kode terkait konfigurasi MK4, termasuk di mpconfigboard.h:

// Kami memiliki versi kami sendiri dari kode ini.#define MICROPY_HW_ENABLE_RNG       (0)

Di sisi MicroPython STM32, makro ini mengontrol jalur kompilasi untuk binding generator angka acak perangkat keras default (RNG) dan implementasi angka acak umum. Menetapkannya ke 0 menyebabkan jalur RNG perangkat keras default tidak digunakan sebagai backend untuk rng_get() umum.

Catatannya menyatakan bahwa pengembang akan mengimplementasikan RNG sendiri; setelah memeriksa rng.h khusus, ditemukan hanya mendeklarasikan dua objek MicroPython:

MP_DECLARE_CONST_FUN_OBJ_0(pyb_rng_get_obj); MP_DECLARE_CONST_FUN_OBJ_1(pyb_rng_get_bytes_obj);

Implementasi yang sesuai adalah:

/// \function pyb_rng_get()///// Kembalikan angka acak yang dihasilkan perangkat keras 30-bit: atau gagal!//STATIC mp_obj_t pyb_rng_get(void){    // Dapatkan dan kembalikan angka acak baru    return mp_obj_new_int(rng_get_or_fault() >> 2);}
/// \function rng_get_bytes()/// Isi buffer dengan bit acak; pemanggil harus menyediakan buffer berukuran tertentu.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);    }
    // Baca kata 32-bit dan uraikan ke dalam buffer yang disediakan    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() secara langsung membaca perangkat STM32 RNG:

static uint32_t rng_get_or_fault(void){    // Aktifkan perangkat RNG jika belum diaktifkan    rng_init();
    // Tunggu hingga angka acak baru siap, memakan waktu sekitar 10us    uint32_t start = HAL_GetTick();
    while (!(RNG->SR & RNG_SR_DRDY)) {        if (HAL_GetTick() - start >= RNG_TIMEOUT_MS) {            // kegagalan perangkat keras... jangan kembalikan apa pun!            mp_raise_OSError(MP_EFAULT);        }    }
    // Dapatkan dan kembalikan angka acak baru    last_value = RNG->DR;
    return last_value;}

Ini menunjukkan bahwa kode khusus Coldcard memang ingin menggunakan hardware RNG, tetapi hanya menjamin penggunaan fungsi hardware tersebut saat memanggil pyb_rng_get* atau random_buffer() internalnya.

Sedangkan saat pembuatan dompet, kode berikut yang sebenarnya dipanggil, di mana fungsi pembuatan dompet di shared/seed.py adalah:

async def make_new_wallet(nwords):    # Pilih seed acak baru.    await ux_dramatic_pause('Menghasilkan...', 3)    seed = generate_seed()    words = await approve_word_list(seed, nwords)    if words:        await commit_new_words(words)

Panggilan ini pertama-tama masuk ke modul shared/random.py Coldcard. Dalam versi sebelumnya, random.py secara eksplisit bergantung pada ngu.random, dan mempertahankan:

# random.py - subset dari modul random, tanpa kompatibilitas, dan menggunakan rng berkualitas kriptografi  
# untuk bytes, gunakan ngu.random.byte(len)  
# bytes = ngu.random.bytes

Artinya, wallet initialization menggunakan random.bytes, bukan pyb.rng(), dan pyb_rng_get_obj yang disesuaikan tidak secara otomatis menimpa random.bytes.

Karena MICROPY_HW_ENABLE_RNG diatur ke 0, RNG perangkat keras tidak digunakan saat pembuatan dompet, melainkan memanggil pyb_rng_yasmarang dari micropython/ports/stm32/rng.c:

#if MICROPY_HW_ENABLE_RNG
uint32_t rng_get(void) {    // gunakan RNG perangkat keras STM32    ...}
#else
// Untuk MCU yang tidak memiliki RNG, kami tetap perlu menyediakan fungsi rng_get()// Pseudo-RNG tidak benar-benar ideal, tetapi kami menggunakannya sementara ini.
// Generator angka acak 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

Sedangkan pyb_rng_yasmarang adalah pseudorandom number generator yang sangat tidak aman untuk digunakan dalam pembuatan seed dompet perangkat keras, karena penyerang dapat memperoleh kunci melalui serangan brute force. Saat ini, Coinkite telah secara eksplisit mengecualikan stm32/rng.c dalam file makefile:

# Jangan mengompilasi PRNG cadangan MicroPython. File rng.c spesifik papan
# menyediakan rng_get(), dan objek kosong ini memenuhi daftar objek 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. Pelacakan Dana yang Dicuri

Saat ini, dana dari beberapa dompet korban telah dipindahkan dan dikumpulkan ke dalam beberapa alamat, belum dilakukan pencucian lebih lanjut. Beosin Trace melalui intelijen ancaman dan analisis perilaku di blockchain, memantau alamat pengumpulan berikut:

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

Selain itu, ada alamat pengumpulan berikut yang pola aliran dananya serupa dengan gambar di atas, dan saat ini belum ada transfer lebih lanjut:

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

Serangan terhadap dompet Coldcard masih berlangsung, tim Beosin terus memantau lebih banyak alamat pengumpulan dan menganalisis arus dana terkait.

Tiga, Penutup

Insiden keamanan besar pada dompet perangkat keras Coldcard ini berasal dari kesalahan implementasi tim pengembang dalam pembangkitan angka acak, yang menggunakan pembangkit angka pseudo-acak pada tahap kritis pembuatan seed dompet. Tim pengembang harus melakukan pengujian dan audit kode secara berkelanjutan dan menyeluruh, sementara pengguna Coldcard Wallet sebaiknya segera memindahkan aset mereka dan memantau pengumuman keamanan selanjutnya dari Coinkite.

Beosin adalah perusahaan teknologi keamanan blockchain dan kepatuhan regulasi terkemuka yang berfokus pada audit keamanan kontrak cerdas sebelum peluncuran proyek, pemantauan dan pencegahan risiko keamanan selama operasi proyek, pemulihan aset yang dicuri, anti pencucian uang (AML) untuk aset virtual, serta investigasi dan pelacakan. Beosin telah menyediakan produk kepatuhan blockchain "all-in-one" dan layanan keamanan kepada 200+ penyedia aset virtual, serta 4.500+ proyek Web3 di lebih dari 20 negara dan wilayah di seluruh dunia.

Penafian: Informasi pada halaman ini mungkin telah diperoleh dari pihak ketiga dan tidak mencerminkan pandangan atau opini KuCoin. Konten ini disediakan hanya untuk tujuan informasi umum, tanpa representasi atau jaminan apa pun, dan tidak dapat ditafsirkan sebagai saran keuangan atau investasi. KuCoin tidak bertanggung jawab terhadap segala kesalahan atau kelalaian, atau hasil apa pun yang keluar dari penggunaan informasi ini. Berinvestasi di aset digital dapat berisiko. Harap mengevaluasi risiko produk dan toleransi risiko Anda secara cermat berdasarkan situasi keuangan Anda sendiri. Untuk informasi lebih lanjut, silakan lihat Ketentuan Penggunaan dan Pengungkapan Risiko.