นายอาร์ม เจาะลึกบั๊ก Coldcard! ทำไมฟังก์ชันสุ่มฮาร์ดแวร์ไม่เคยถูกเรียกใช้เลย
ท่ามกลางกระแสช่องโหว่ Coldcard ที่ยังคงเป็นประเด็นร้อนในวงการ Bitcoin นายอาร์ม ยูทูปเบอร์สายเทคโนโลยี ได้อธิบายกลไกทางเทคนิคเบื้องหลังบั๊กนี้อย่างละเอียดในคลิปของเขา เผยมุมมองที่ลึกกว่ารายงานทั่วไป โดยเฉพาะประเด็นเรื่องที่มาของโค้ดที่มีปัญหา และกลไกการชนกันของฟังก์ชันที่ทำให้ระบบสุ่มเลขฮาร์ดแวร์ที่ถูกต้องไม่เคยถูกเรียกใช้งานเลยแม้แต่ครั้งเดียว
📜 จุดเริ่มต้น: ปัญหาเรื่องลิขสิทธิ์ซอฟต์แวร์
ตามคำอธิบายของนายอาร์ม เดิมที Coldcard ใช้โค้ดสำหรับสร้างตัวเลขสุ่ม (Random Number Generator) จากไลบรารีโอเพนซอร์สของ Trezor คู่แข่งในตลาดกระเป๋าฮาร์ดแวร์ ซึ่งอยู่ภายใต้สัญญาอนุญาต GPL (General Public License) ที่กำหนดว่าหากนำโค้ดไปดัดแปลงแล้วส่งต่อให้ลูกค้า จะต้องเปิดเผยซอร์สโค้ดฉบับดัดแปลงนั้นต่อสาธารณะด้วย Coinkite บริษัทผู้ผลิต Coldcard ไม่ต้องการผูกพันตามเงื่อนไขนี้ จึงตัดสินใจเขียนไลบรารีของตัวเองขึ้นมาใหม่ในชื่อ "NGU" (libngu) โดย CTO ของบริษัทเป็นผู้พัฒนา ภายใต้แนวคิด "Source-Verifiable" คือเปิดให้ตรวจสอบโค้ดได้ แต่ไม่อนุญาตให้นำไปใช้ซ้ำแบบโอเพนซอร์สทั่วไป
⚙️ จุดที่พลาด: ฟังก์ชันชื่อชนกันตอน Link โค้ด
นายอาร์มอธิบายว่า เมื่อ Coinkite ดึงโค้ดของ Trezor ออกและเปลี่ยนมาใช้ไลบรารี NGU ของตัวเอง ปัญหาที่เกิดขึ้นคือฟังก์ชันสำหรับดึงค่าตัวเลขสุ่มจากฮาร์ดแวร์ (เรียกแบบง่ายว่าฟังก์ชัน Get Random) ที่ Coinkite เขียนขึ้นในไลบรารี NGU ของตัวเอง ดันมีชื่อเรียกซ้ำกับฟังก์ชันที่มีอยู่แล้วในไลบรารี MicroPython ซึ่งเป็นภาษาที่ใช้เขียนเฟิร์มแวร์ของอุปกรณ์ เมื่อกระบวนการ Link โค้ดทั้งสองไลบรารีเข้าด้วยกัน ตัว Linker จะเลือกใช้ฟังก์ชันที่เจอก่อนตามลำดับที่กำหนดไว้ในระบบ ซึ่งผลลัพธ์คือมันเลือกไปเรียกใช้ฟังก์ชันของ MicroPython แทนที่จะเป็นฟังก์ชันฮาร์ดแวร์แท้จริงของ Coinkite เอง ทั้งที่โค้ดฝั่ง Coinkite เขียนไว้ถูกต้องสมบูรณ์แล้วก็ตาม
🚩 ตัวแปร Flag ที่ถูกตีความผิด
ประเด็นซ้อนที่ทำให้บั๊กนี้ไม่ถูกจับได้ตั้งแต่ต้น คือความเข้าใจผิดเรื่องตัวแปร `MICROPY_HW_ENABLE_RNG` นักพัฒนาของ Coinkite เข้าใจว่าหากตั้งค่าตัวแปรนี้เป็น 0 จะหมายถึงการปิดใช้งานฟังก์ชันสุ่มเลขแบบซอฟต์แวร์ทั้งหมด แล้วบังคับให้ระบบไปใช้ฟังก์ชันฮาร์ดแวร์ของตัวเองแทน แต่ในความเป็นจริง ไม่ว่าจะตั้งค่าตัวแปรนี้เป็น 0 หรือ 1 ระบบก็ไม่เคยวิ่งไปเรียกใช้ฟังก์ชันฮาร์ดแวร์ที่แท้จริงของ Coinkite เลย เพราะปัญหาการชนกันของชื่อฟังก์ชันที่กล่าวไปข้างต้นเกิดขึ้นก่อนที่ตรรกะของตัวแปรนี้จะมีผลเสียอีก
🎲 Yasmarang: ตัวสุ่มเลขปลอมที่คาดเดาได้
ผลจากความผิดพลาดนี้ ทำให้ระบบไปใช้ฟังก์ชันสุ่มเลขสำรองของ MicroPython ที่ชื่อว่า Yasmarang ซึ่งเป็นตัวสุ่มเลขแบบพื้นฐาน อ้างอิงจากหมายเลขประจำชิป (Chip ID ที่สามารถอ่านค่าได้) บวกกับค่าตัวจับเวลาตั้งแต่เปิดเครื่อง ซึ่งมีขอบเขตแคบมากเพียง 0 ถึง 79,999 ค่าเท่านั้น นายอาร์มยังตั้งข้อสังเกตเพิ่มเติมว่า ในโค้ดของ Coinkite เอง มีความพยายามเพิ่มความสุ่มด้วยการนำค่าอื่นมา Exclusive OR (XOR) ร่วมกับผลลัพธ์ของ Yasmarang แต่ค่าที่นำมาผสมนั้นกลับถูกเขียนเป็นค่าคงที่ (Constant) ที่ไม่เปลี่ยนแปลงเลย ทำให้ไม่ได้เพิ่มเอนโทรปีให้กับระบบแต่อย่างใด
🔓 วิธีที่ผู้โจมตีไล่หาบัญชี
เมื่อขอบเขตของค่าที่เป็นไปได้แคบเพียงหลักหมื่น ผู้โจมตีสามารถไล่คำนวณค่าที่เป็นไปได้ทั้งหมดตั้งแต่ 0 ถึง 79,999 สำหรับแต่ละหมายเลขชิปที่รู้จัก แล้วนำไปสร้างเป็น Seed Phrase และที่อยู่ Bitcoin เพื่อตรวจสอบกับบล็อกเชนสาธารณะว่าที่อยู่ใดมีเงินอยู่บ้าง นายอาร์มชี้ว่ากระบวนการนี้ไม่มีการจำกัดจำนวนครั้งเหมือนการเดารหัสผ่านเข้าระบบทั่วไป เพราะการตรวจสอบยอดเงินในบัญชี Bitcoin เป็นการ Query ข้อมูลสาธารณะที่ไม่มีใครมาจำกัดอัตราการเข้าถึงได้ ผู้โจมตีจึงสามารถคำนวณแบบออฟไลน์ที่บ้านตัวเองล่วงหน้าเป็นรายการยาว แล้วค่อยนำไปตรวจสอบยอดเงินบนเชนภายหลัง โดยไม่จำเป็นต้องใช้อุปกรณ์คำนวณที่ทรงพลังหรือ Server Farm ขนาดใหญ่แต่อย่างใด
💰 ความเสียหายและสถานะปัจจุบัน
นายอาร์มระบุในคลิปว่า ยอดความเสียหายล่าสุดที่เขาติดตามอยู่ที่ราว 220 ล้านดอลลาร์ หรือกว่า 6,000 ล้านบาท (ตัวเลขนี้เป็นการประเมินของนายอาร์มเอง ณ ช่วงเวลาที่บันทึกคลิป ซึ่งสูงกว่าตัวเลขล่าสุดที่ Bitcoinaddict.com เคยรายงานไว้จากแหล่งอื่น สะท้อนว่าสถานการณ์ยังมีความไม่แน่นอนและอาจมีการประเมินตัวเลขที่แตกต่างกันไปในแต่ละช่วงเวลา) โดยเงินที่ถูกขโมยไปกระจุกตัวอยู่ใน 3 บัญชีหลักที่ชุมชนกำลังจับตาดู และส่วนใหญ่ยังไม่ถูกเคลื่อนย้ายออกไป
🛡️ ทางแก้ที่ Coldcard เสนอไว้ตั้งแต่ต้น
นายอาร์มยังย้ำว่า Coldcard มีโหมดให้ผู้ใช้ทอยลูกเต๋าจริงเพื่อสร้าง Seed Phrase แบบ True Random ได้เองอยู่แล้ว โดยไม่ต้องพึ่งพาตัวสุ่มเลขของอุปกรณ์เลย ผู้ใช้ที่เลือกวิธีนี้จะไม่ได้รับผลกระทบจากบั๊กนี้ (Bitcoinaddict.com เคยอธิบายรายละเอียดวิธีนี้ไว้แล้วในบทความก่อนหน้า) เช่นเดียวกับผู้ที่ตั้ง BIP-39 Passphrase เพิ่มเติมก็จะปลอดภัยกว่าเช่นกัน
💬 มุมมองต่อความรับผิดชอบ
นายอาร์มให้ความเห็นว่าความผิดพลาดลักษณะนี้ (การใช้ If-Defined ผิดเงื่อนไข) เกิดขึ้นได้บ่อยในการเขียนโปรแกรม แต่สำหรับอุปกรณ์ที่เกี่ยวข้องกับความปลอดภัยทางการเงินโดยตรงอย่างกระเป๋าฮาร์ดแวร์ ควรมีการทดสอบตรวจสอบว่าฟังก์ชันที่เรียกใช้จริงมาจากไลบรารีใดอย่างละเอียดกว่านี้ พร้อมตั้งข้อสังเกตว่าเคยมีผู้ใช้รายหนึ่งเตือน Coinkite มาก่อนหน้านี้แล้วว่าการทำงานของระบบสุ่มเลขดูผิดปกติ แต่เรื่องก็เงียบไปจนกระทั่งเกิดการโจมตีจริงจึงเป็นที่สนใจ
📎 ข่าวที่เกี่ยวข้องจาก Bitcoinaddict.com:
👉 เจาะลึกช่องโหว่ Coldcard: ทำไมกระเป๋าฮาร์ดแวร์ Bitcoin อาจไม่ปลอดภัยอย่างที่คิด
👉 Galaxy เผย! อย่างน้อย 15 แฮกเกอร์รุมโจมตีช่องโหว่ Coldcard ส่วน AI ถอดรหัสได้ในไม่ถึง 20 นาที
👉 Coldcard ระลอก 4 เสียหายพุ่งใกล้ $114 ล้าน เผยบั๊กเฟิร์มแวร์ 5 ปี CEO ลั่น 'เสียใจสุดๆ'🔗 อ้างอิงต้นฉบับ: คลิปวิเคราะห์โดยนายอาร์ม / youtube.com/watch?v=eb_5z2bFyGM
💬 ความเห็นบรรณาธิการ Bitcoinaddict:
คำอธิบายของนายอาร์มช่วยเติมเต็มภาพที่รายงานข่าวทั่วไปมักไม่ลงลึกถึง โดยเฉพาะที่มาเชิงลิขสิทธิ์ซอฟต์แวร์ที่ทำให้ Coinkite ต้องเขียนไลบรารีสุ่มเลขของตัวเองขึ้นมาใหม่ ก่อนจะพลาดพลั้งจากปัญหาการชนกันของชื่อฟังก์ชันที่มองข้ามได้ง่ายมาก บทเรียนสำคัญคือแม้จะเป็นความผิดพลาดที่เข้าใจได้ในเชิงเทคนิค แต่สำหรับอุปกรณ์ที่เกี่ยวข้องกับทรัพย์สินทางการเงินโดยตรง มาตรฐานการทดสอบควรเข้มงวดกว่านี้มาก ส่วนตัวเลขความเสียหาย 220 ล้านดอลลาร์ที่นายอาร์มกล่าวถึงเป็นเพียงการประเมินส่วนตัว ผู้อ่านควรติดตามตัวเลขจากแหล่งวิจัยที่เป็นทางการอย่าง Galaxy Research ประกอบด้วยเพื่อความแม่นยำ
Tags / คีย์เวิร์ด SEO: Coldcard, RNG, Coinkite, Bitcoin, ช่องโหว่
— รายงานโดยทีมข่าว Bitcoinaddict.com