Kerentanan Dompet Perkakas Coldcard Menyebabkan Bitcoin Dicuri Lebih Daripada $88J

iconMetaEra
Kongsi
AI summary iconRingkasan
Kecacatan pada dompet keras Coldcard yang berkaitan dengan RNG yang salah konfigurasi menyebabkan lebih dari 594 BTC dicuri, bernilai lebih dari $88 juta. Masalah ini mempengaruhi model Coldcard Mk2, Mk3, Mk4, Q, dan Mk5, mendedahkan kunci peribadi kepada serangan brute-force. Beosin telah melacak dana terkumpul ke beberapa alamat Bitcoin. Kejadian ini menimbulkan kebimbangan di bawah CFT dan menekankan keperluan mendesak untuk mematuhi MiCA semasa EU memperketat peraturan kripto.

Kerugian melebihi US$88 juta: Analisis lubang keamanan pada dompet keras Coldcard dan pelacakan dana yang dicuri Pada 31 Julai, sebanyak 500 dompet keras Coldcard telah dicuri, dengan jumlah 594 bitcoin bernilai kira-kira US$38 juta. Selepas itu, Coinkite, syarikat yang bertanggungjawab atas penghasilan dompet Coldcard, mengesahkan bahawa terdapat lubang keamanan dalam proses penghasilan kunci pada produk tersebut, yang mempengaruhi pelbagai generasi Coldcard seperti Mk2, Mk3, Mk4, Q, dan Mk5.

Sekarang, jumlah kerugian akibat serangan terhadap lubang keamanan ini telah melebihi US$88 juta, dan serangan masih berterusan. Pengguna dompet Coldcard seharusnya segera memindahkan dana mereka ke alamat lain. Analisis Beosin terhadap lubang keamanan ini dan pengesanan dana yang dicuri adalah seperti berikut.

Satu, analisis lubang keamanan

Menganalisis rekod penghantaran kod firmware Coldcard, dapat ditemui bahawa dalam Commit sebelumnya 37e4af5451c260c1e7d429fe8972c4cb5e68ee59, pasukan pembangun telah mengemas kini beberapa kod berkaitan konfigurasi MK4, termasuk dalam mpconfigboard.h:

// Kami mempunyai versi kami sendiri untuk kod ini.#define MICROPY_HW_ENABLE_RNG       (0)

Pada sisi MicroPython STM32, makro ini mengawal laluan kompilasi untuk pengikatan penghasil nombor rawak peranti (RNG) lalai dan pelaksanaan rawak am. Menetapkannya kepada 0 menyebabkan laluan RNG peranti lalai tidak digunakan sebagai backend untuk rng_get() am.

Catatannya menyatakan bahawa pembangun akan melaksanakan RNG sendiri; semak rng.h yang disesuaikan dan mendapati hanya menyatakan 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 sepadan ialah:

/// \function pyb_rng_get()///// Kembalikan nombor rawak yang dihasilkan peranti 30-bit: atau gagal!//STATIC mp_obj_t pyb_rng_get(void){    // Dapatkan dan kembalikan nombor rawak baru    return mp_obj_new_int(rng_get_or_fault() >> 2);}
/// \function rng_get_bytes()/// Isi buffer dengan bit rawak; pemanggil harus menyediakan buffer bersaiz.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 perkataan 32-bit dan bongkar 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() membaca peranti RNG STM32:

static uint32_t rng_get_or_fault(void){    // Aktifkan periferal RNG jika belum diaktifkan    rng_init();
    // Tunggu sehingga nombor rawak baru sedia, mengambil masa kira-kira 10us    uint32_t start = HAL_GetTick();
    while (!(RNG->SR & RNG_SR_DRDY)) {        if (HAL_GetTick() - start >= RNG_TIMEOUT_MS) {            // kegagalan peranti keras... jangan kembalikan apa-apa!            mp_raise_OSError(MP_EFAULT);        }    }
    // Dapatkan dan kembalikan nombor rawak baru    last_value = RNG->DR;
    return last_value;}

Ini menunjukkan bahawa kod tersuai Coldcard memang ingin menggunakan RNG peranti keras, tetapi ia hanya menjamin penggunaan fungsi peranti keras tersebut apabila memanggil pyb_rng_get* atau random_buffer() dalaman.

Sementara itu, semasa penciptaan dompet, kod berikut sebenarnya dipanggil, di mana fungsi penciptaan dompet di shared/seed.py ialah:

async def make_new_wallet(nwords):    # Pilih benih rawak 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 masuk terlebih dahulu ke modul shared/random.py Coldcard. Dalam versi sebelumnya, random.py secara eksplisit bergantung pada ngu.random, dan menyimpan:

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

Iaitu, yang digunakan untuk inisialisasi dompet ialah random.bytes, bukan pyb.rng(), dan pyb_rng_get_obj yang disesuaikan tidak menimpa random.bytes secara automatik.

Kerana MICROPY_HW_ENABLE_RNG ditetapkan sebagai 0, RNG peranti keras tidak digunakan semasa penghasilan dompet, tetapi pyb_rng_yasmarang dari micropython/ports/stm32/rng.c dipanggil:

#if MICROPY_HW_ENABLE_RNG
uint32_t rng_get(void) {    // gunakan RNG peranti keras STM32    ...}
#else
// Untuk MCU yang tidak mempunyai RNG, kami masih perlu menyediakan fungsi rng_get()// Pseudo-RNG bukanlah pilihan ideal, tetapi kami menggunakannya sementara ini.
// Penghasil nombor rawak 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

Sementara itu, pyb_rng_yasmarang adalah pseudorandom number generator yang sangat tidak selamat digunakan untuk penghasilan benih dompet keras, kerana penyerang boleh mendapatkan kunci melalui serangan brute force. Semasa ini, Coinkite telah secara jelas mengecualikan stm32/rng.c dalam fail makefile:

# Jangan kompilasi PRNG fallback MicroPython. Fail rng.c yang spesifik papan
# menyediakan rng_get(), dan objek kosong ini memenuhi senarai objek hulu.
$(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 $@

Dua: Penjejakan dana yang dicuri

Sekarang, dana dari beberapa dompet mangsa telah dipindahkan dan dikumpulkan ke dalam beberapa alamat, tetapi belum dilakukan pembersihan lanjutan. Beosin Trace melalui intelijen ancaman dan analisis perilaku di rantai, 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, terdapat alamat pengumpulan berikut yang pola aliran dananya serupa dengan gambar di atas, dan saat ini tidak ada pemindahan lanjutan:

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

Serangan terhadap dompet Coldcard masih berterusan, pasukan Beosin terus memantau lebih banyak alamat pengumpulan dan menganalisis aliran dana yang berkaitan.

Tiga, Penutup

Keselamatan besar dalam dompet keras Coldcard ini berpunca daripada kesilapan pelaksanaan pasukan pembangun dalam penghasilan nombor rawak, di mana nombor rawak palsu digunakan dalam proses penghasilan benih dompet yang kritikal. Pasukan pembangun perlu melakukan ujian dan audit yang berterusan dan menyeluruh terhadap kod, manakala pengguna Coldcard wallet perlu segera memindahkan aset mereka dan memantau pengumuman keselamatan seterusnya daripada Coinkite.

Beosin ialah syarikat teknologi keselamatan blockchain dan kepatuhan regulasi terkemuka, yang berfokus pada audit keselamatan kontrak pintar sebelum pelancaran projek, pemantauan dan penghalangan risiko keselamatan semasa operasi projek, pemulihan aset yang dicuri, anti pencucian wang (AML) aset maya, serta penyiasatan dan pelacakan. Beosin telah menyediakan produk kepatuhan blockchain "sekali jalan" dan perkhidmatan keselamatan kepada 200 lebih penyedia aset maya, serta 4,500 lebih projek Web3 di lebih 20 negara dan wilayah di seluruh dunia.

Penafian: Maklumat yang terdapat pada halaman ini mungkin telah diperoleh daripada pihak ketiga dan tidak semestinya menggambarkan pandangan atau pendapat KuCoin. Kandungan ini adalah disediakan bagi tujuan maklumat umum sahaja, tanpa sebarang perwakilan atau waranti dalam apa jua bentuk, dan juga tidak boleh ditafsirkan sebagai nasihat kewangan atau pelaburan. KuCoin tidak akan bertanggungjawab untuk sebarang kesilapan atau pengabaian, atau untuk sebarang akibat yang terhasil daripada penggunaan maklumat ini. Pelaburan dalam aset digital boleh membawa risiko. Sila menilai risiko produk dan toleransi risiko anda dengan teliti berdasarkan keadaan kewangan anda sendiri. Untuk maklumat lanjut, sila rujuk kepada Terma Penggunaan dan Pendedahan Risiko kami.