8800 ڈالر سے زیادہ کا نقصان: Coldcard ہارڈویئر ویلٹ کی خرابی کا تجزیہ اور چوری شدہ فنڈز کی ٹریسنگ 31 جولائی کو، تقریباً 500 Coldcard ہارڈویئر ویلٹس سے کل 594 بٹ کوائن چوری ہو گئے، جن کی قیمت تقریباً 38 ملین امریکی ڈالر تھی۔ بعد میں Coldcard ویلٹس کے پیدا کرنے والی کمپنی Coinkite نے تصدیق کی کہ اس کے پروڈکٹ میں کلید پیدا کرنے کے مرحلے میں ایک سیکورٹی خرابی تھی، جس میں Coldcard Mk2، Mk3، Mk4، Q اور Mk5 سمیت متعدد نسلوں کے پروڈکٹس شامل تھے۔
اب تک، اس خلل کے نتیجے میں ہونے والے نقصان کی رقم 88 ملین امریکی ڈالر سے زیادہ ہو چکی ہے، اور حملہ جاری ہے، لہذا Coldcard والٹ کے صارفین کو اپنے فنڈز فوراً دوسرے پتے پر منتقل کر لینا چاہیے۔ Beosin کی جانب سے اس خلل کا تجزیہ اور چوری ہونے والے فنڈز کی ٹریسنگ کی تفصیل مندرجہ ذیل ہے۔
ایک، خامی کا تجزیہ
کولڈکارڈ فارم ویئر کوڈ کے کمٹ ریکارڈز کا تجزیہ کرنے سے پتہ چلتا ہے کہ پہلے کمٹ 37e4af5451c260c1e7d429fe8972c4cb5e68ee59 میں، ڈویلپمنٹ ٹیم نے MK4 کانفیگریشن کے متعدد کوڈز کو اپڈیٹ کیا تھا، جس میں mpconfigboard.h میں شامل ہے:
ہمارے پاس اس کوڈ کا اپنا ورژن ہے۔#define MICROPY_HW_ENABLE_RNG (0)
مائیکرو پائیتھن 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()///// 30-bit ہارڈویئر جنریٹڈ رینڈم نمبر واپس کریں: یا ناکامی!//STATIC mp_obj_t pyb_rng_get(void){ // نیا رینڈم نمبر حاصل کریں اور واپس کریں return mp_obj_new_int(rng_get_or_fault() >> 2);}
/// \function rng_get_bytes()/// ایک بفر کو رینڈم بٹس سے بھریں؛ کالر کو سائز شدہ بفر فراہم کرنا ہوگا۔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); }
// 32-bit الفاظ پڑھیں اور مہیا کردہ بفر میں انسٹال کریں 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() خود STM32 RNG پیریفیرل پڑھتا ہے:
static uint32_t rng_get_or_fault(void){ // اگر RNG پیریفیرل پہلے سے آن نہیں ہے تو اسے آن کریں rng_init();
// ایک نیا تصادفی نمبر تیار ہونے کا انتظار کریں، جس میں تقریباً 10us لگتے ہیں uint32_t start = HAL_GetTick();
while (!(RNG->SR & RNG_SR_DRDY)) { if (HAL_GetTick() - start >= RNG_TIMEOUT_MS) { // ہارڈویئر خرابی... کچھ بھی واپس نہیں کریں! mp_raise_OSError(MP_EFAULT); } }
// نیا تصادفی نمبر حاصل کریں اور واپس کریں last_value = RNG->DR;
return last_value;}
یہ ظاہر کرتا ہے کہ Coldcard کسٹم کوڈ واقعی ہارڈویئر RNG کا استعمال کرنا چاہتا ہے، لیکن یہ صرف pyb_rng_get* یا اس کے اندر random_buffer() کو بلانے کے وقت اس ہارڈویئر فنکشن کا استعمال یقینی بناتا ہے۔
اور ویلٹ بناتے وقت درج ذیل کوڈ کو حقیقی طور پر کال کیا جاتا ہے، جہاں shared/seed.py میں ویلٹ بنانے کا فنکشن ہے:
async def make_new_wallet(nwords): # نئی تصادفی سیڈ منتخب کریں۔ await ux_dramatic_pause('Generating...', 3) seed = generate_seed() words = await approve_word_list(seed, nwords) if words: await commit_new_words(words)
یہ کال سب سے پہلے Coldcard کے shared/random.py ماڈیول میں جاتا ہے۔ قدیم ورژن میں، random.py صرف ngu.random پر منحصر تھا، اور یہ رکھا گیا تھا:
# random.py - رینڈم ماڈیول کا ایک ذیلی مجموعہ، بے کمپیٹ، اور کرپٹو کوالٹی RNG کا استعمال کرتے ہوئے # بائٹس کے لیے، 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 فنکشن کال کیا گیا:
#if MICROPY_HW_ENABLE_RNG
uint32_t rng_get(void) { // STM32 ہارڈویئر RNG کا استعمال کریں ...}
#else
// جن MCUs میں RNG نہیں ہوتا، ہمیں اب بھی rng_get() فنکشن فراہم کرنے کی ضرورت ہے۔// ایک پسیوڈو-RNG اصل میں مثالی نہیں لیکن ہم اب اسے استعمال کرتے ہیں۔
// Yasmarang تصادفی نمبر جنریٹرstatic 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
اور pyb_rng_yasmarang ایک جعلی تصادفی نمبر جنریٹر ہے، جو ہارڈویئر والٹ سیڈ جنریشن کے لیے بہت غیر محفوظ ہے، حملہ آور طاقت کے ذریعے کلید حاصل کر سکتے ہیں۔ ابھی، Coinkite نے makefile فائل میں stm32/rng.c کو واضح طور پر مستثنیٰ کر دیا ہے:
مائیکرو پائیتھن کے فیل بیک PRNG کو نہیں مجموعہ کریں۔ بورڈ-خصوصی rng.c
rng_get() فراہم کرتا ہے، اور یہ خالی آبجیکٹ اپ اسٹریم آبجیکٹ فہرست کو پورا کرتا ہے۔
$(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 ہارڈویئر والٹ کی بڑی سیکیورٹی حادثہ کا سبب ڈویلپمنٹ ٹیم کی طرف سے رینڈم نمبر جنریٹر کے غلط اطلاق تھا، جس میں اہم والٹ سیڈ جنریشن کے دوران جعلی رینڈم نمبر جنریٹر استعمال کیا گیا۔ ڈویلپمنٹ ٹیم کو کوڈ کا مستقل اور مکمل ٹیسٹنگ اور آڈٹ کرنا چاہئے، اور Coldcard والٹ صارفین کو اپنے اثاثوں کو جلد سے جلد منتقل کرنا چاہئے اور Coinkite کے بعد کے سیکیورٹی اعلانات پر نظر رکھنا چاہئے۔
بیوسن ایک رہنما بلاکچین سیکیورٹی اور ریگولیٹری کمپلاینس ٹیک کمپنی ہے جو پروجیکٹ لانچ سے پہلے اسمارٹ کنٹریکٹ سیکیورٹی آڈٹ، پروجیکٹ کے عمل کے دوران سیکیورٹی خطرات کی نگرانی اور روک تھام، چوری شدہ اثاثوں کی واپسی، ورچوئل اثاثوں کے خلاف دھوکہ دہی (AML) اور تحقیق و ٹریکنگ پر توجہ مرکوز کرتی ہے۔ بیوسن نے عالمی سطح پر 20 سے زائد ممالک اور علاقوں کے ریگولیٹری اور ایکزیکیوٹو اداروں، 200 سے زائد ورچوئل اثاثہ سروس فراہم کنندگان اور 4500 سے زائد ویب3 پروجیکٹس کو "ایک ہی جگہ" بلاکچین کمپلاینس مصنوعات + سیکیورٹی سروسز فراہم کی ہیں۔

