8800 ডলারের বেশি ক্ষতি: Coldcard হার্ডওয়্যার ওয়ালেট ভালনারেবিলিটি বিশ্লেষণ এবং চুরি করা অর্থের ট্র্যাকিং জুলাই ৩১, প্রায় ৫০০টি Coldcard হার্ডওয়্যার ওয়ালেট থেকে ৫৯৪টি বিটকয়েন চুরি হয়, যার মূল্য প্রায় ৩৮ মিলিয়ন ডলার। তারপর, Coldcard ওয়ালেটের উৎপাদনকারী কোম্পানি Coinkite নিশ্চিত করে যে, Coldcard Mk2, Mk3, Mk4, Q এবং Mk5 সহ অনেকগুলি প্রজন্মের পণ্যে কী জেনারেশনের সময় একটি নিরাপত্তা দুর্বলতা ছিল।
এখন পর্যন্ত, এই দুর্বলতার আক্রমণের কারণে ক্ষতির পরিমাণ 88 মিলিয়ন ডলারের বেশি পৌঁছেছে, এবং আক্রমণ এখনও চলছে। Coldcard ওয়ালেট ব্যবহারকারীদের তাদের অর্থ অন্য ঠিকানায় স্থানান্তরিত করার জন্য দ্রুত ব্যবস্থা করা উচিত। Beosin-এর এই দুর্বলতা সম্পর্কিত বিশ্লেষণ এবং চুরি করা অর্থের ট্র্যাকিংয়ের বিবরণ নিম্নরূপ:
এক, ভেদ্যতা বিশ্লেষণ
Coldcard ফার্মওয়্যার কোডের কমিট হিস্ট্রি বিশ্লেষণ করে দেখা যায় যে, আগের Commit 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-বিট হার্ডওয়্যার জেনারেটেড র্যান্ডম সংখ্যা ফেরত দিন: অথবা ব্যর্থ হন!//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-বিট শব্দ পড়ুন এবং প্রদত্ত বাফারে অনপ্যাক করুন 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 - র্যান্ডম মডিউলের একটি সাবসেট, কোনো কম্প্যাটিবিলিটি ছাড়া, এবং ক্রিপ্টো-কোয়ালিটি আরএনজি ব্যবহার করে # বাইটের জন্য, ngu.random.byte(len) ব্যবহার করুন #bytes = ngu.random.bytes
যেহেতু ওয়ালেট ইনিশিয়ালাইজেশনে random.bytes ব্যবহার করা হয়েছে, পাইবি.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
// যাদের এমসিইউ-তে 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 থেকে বাদ দিয়েছে:
মাইক্রোপাইথনের ফলব্যাক পিআরএনজি কম্পাইল করবেন না। বোর্ড-নির্দিষ্ট 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)
কোল্ডকার্ড ওয়ালেটের বিরুদ্ধে আক্রমণ চলছে, বিওসিন টিম আরও সংগ্রহ ঠিকানা এবং সংশ্লিষ্ট ফান্ড প্রবাহ বিশ্লেষণের জন্য নিয়মিত মনিটরিং করছে।
তিন, সমাপ্তি
এই কোল্ডকার্ড হার্ডওয়্যার ওয়ালেটের গুরুতর নিরাপত্তা দুর্ঘটনার কারণ হল র্যান্ডম নম্বর জেনারেশনের বাস্তবায়নে ত্রুটি, যেখানে কীভাবে ওয়ালেট সিড তৈরি করা হচ্ছিল সেখানে প্রতিকৃতি-র্যান্ডম নম্বর জেনারেটর ব্যবহার করা হয়েছিল। ডেভেলপমেন্ট টিমকে কোডের জন্য নিয়মিত, সম্পূর্ণ টেস্টিং এবং অডিট করা উচিত, এবং কোল্ডকার্ড ওয়ালেট ব্যবহারকারীদের তাদের সম্পদ দ্রুত স্থানান্তরিত করা উচিত এবং Coinkite-এর পরবর্তী নিরাপত্তা ঘোষণাগুলির প্রতি দৃষ্টি রাখা উচিত।
Beosin হল একটি অগ্রণী ব্লকচেইন নিরাপত্তা এবং নিয়ন্ত্রণ পালন প্রযুক্তি কোম্পানি, যা প্রকল্প লঞ্চের আগে স্মার্ট চুক্তির নিরাপত্তা অডিট, প্রকল্প চলাকালীন নিরাপত্তা ঝুঁকি মনিটরিং এবং বন্ধ করা, চুরি করা সম্পদ ফেরত পাওয়া, ভার্চুয়াল সম্পদের বিপরীতে ধোওয়া (AML) এবং তদন্ত ও ট্র্যাকিং-এর উপর ফোকাস করে। Beosin বিশ্বের 20টিরও বেশি দেশ এবং অঞ্চলের নিয়ন্ত্রণকারী এবং বাহিনী সংস্থা, 200টিরও বেশি ভার্চুয়াল সম্পদ সেবাদানকারী এবং 4500টিরও বেশি Web3 প্রকল্পকে “ওয়ান-স্টপ” ব্লকচেইন কমপ্লায়েন্স পণ্য + নিরাপত্তা সেবা প্রদান করেছে।

