● 2026-08-05
บั๊กบรรทัดเดียวมูลค่าพันล้าน: เมื่อ Coldcard Hardware Wallet ถูกขโมย Bitcoin เพราะ Firmware อัปเดตพลาด
#cryptocurrency #hacking #cybersecurity
สรุปสั้น: ช่องโหว่ใน firmware ของ Coldcard hardware wallet (มีนาคม 2021 – กรกฎาคม 2026) ทำให้กระบวนการสุ่ม Seed Phrase ที่ควรมี Entropy ระดับ 128/256 bits เหลือเพียงประมาณ 32–72 bits เปิดช่องให้ผู้โจมตี brute-force หา seed และขโมย Bitcoin ได้ มูลค่าความเสียหายที่มีรายงานอยู่ระหว่าง 38–88 ล้านดอลลาร์ (แหล่งข่าวรายงานตัวเลขต่างกัน)
สารบัญ
- ภาพรวมปัญหา
- จุดเริ่มต้นของหายนะ: Root Cause ระดับ Source Code
- Timeline
- Commit และไฟล์ที่เกี่ยวข้อง
- ทำไม Audit ก่อนหน้านี้ถึงจับบั๊กนี้ไม่ได้
- ผลกระทบ
- บทเรียนและวิธีป้องกัน (สำหรับผู้ใช้ COLDCARD)
- อ้างอิง
ภาพรวมปัญหา
เป็นเรื่องของ hardware wallet ที่โดนช่องโหว่จาก Firmware อัปเดตผิดพลาด (เริ่มตั้งแต่เวอร์ชัน 4.0.0 ช่วงเดือนมีนาคม 2021) ส่งผลให้กระบวนการสุ่ม Seed Phrase ที่ควรมี Entropy ระดับ 128/256 bits กลับลดลงเหลือเพียงประมาณ 32-72 bits เท่านั้น เปิดช่องให้ผู้โจมตีสามารถคำนวณหา Seed และดึงเงินออกจากกระเป๋าไปได้ โดยไม่ต้องขโมยเครื่องหรือรอให้อุปกรณ์ต่อเน็ตเลยด้วยซ้ำ
มาดูกันในระดับ Source Code ว่า “ฮาร์ดแวร์ระดับเทพ พลาดท่าให้ซอฟต์แวร์ได้ยังไง”
จุดเริ่มต้นของหายนะ: Root Cause ระดับ Source Code
ปกติแล้ว hardware wallet ส่วนใหญ่เวลาสร้าง Seed Phrase จะต้องเรียกใช้ Hardware TRNG (True Random Number Generator) ที่ฝังอยู่ในชิปความปลอดภัยโดยตรง ผ่านคำสั่งอย่าง ckcc.rng_bytes()
แต่ทีมพัฒนาได้ทำการปรับโค้ดใหม่ เปลี่ยนไปเรียกใช้ฟังก์ชัน ngu.random.bytes() ใน shared/seed.py (ฟังก์ชัน generate_seed()) แทน โดยมี comment กำกับไว้ว่า “Generate 32 bytes of best-quality high entropy TRNG bytes” — แต่ในความเป็นจริง ฟังก์ชันนี้ไปเรียกไลบรารีคริปโตที่ชื่อ libngu มาทำงานแทน โดยไม่ได้ใช้ True Random Number Generator ในชิปความปลอดภัยตามที่ตั้งใจไว้
ในไลบรารี libngu (external/libngu/ngu/random.c บรรทัดที่ 28) มีโค้ดสำหรับตรวจสอบว่าระบบเปิดใช้งาน Hardware TRNG แล้วหรือยัง เขียนไว้ประมาณนี้:
#ifndef MICROPY_HW_ENABLE_RNG
#error "get a HW TRNG plz"
#endif
(ถ้าจะแซวก็คงต้องเติมว่า #error "มึงลืม #if รึเปล่า" — ไม่ใช่โค้ดจริงในไฟล์ แค่ล้อเจตนาของบั๊กให้เห็นภาพ)
จุดที่พลาดคือ โค้ดนี้ตรวจแค่ว่า “มีการประกาศตัวแปร MICROPY_HW_ENABLE_RNG หรือยัง” (#ifndef = is it defined?) แต่ไม่ได้ตรวจว่าค่าของมันคืออะไร (ไม่ใช่ #if ที่เช็คค่า true/false)
ปัญหาคือในไฟล์ config ของ firmware (stm32/COLDCARD_MK4/mpconfigboard.h บรรทัดที่ 78 — และไฟล์เทียบเท่าใน Mk3) ตัวแปรนี้ถูกประกาศไว้ว่า:
// We have our own version of this code.
#define MICROPY_HW_ENABLE_RNG (0)
ซึ่งหมายถึง “ปิดการใช้งาน RNG ของ MicroPython เพราะเรามี hardware RNG ของตัวเองแล้ว” — เจตนาดั้งเดิมถูกต้อง แต่เพราะตัวแปรนี้ถูก “ประกาศ” ไว้แล้ว (แม้ค่าจะเป็น 0) #ifndef เลยผ่านฉลุย ไม่มี compile error ทั้งที่จริง ๆ ชิป TRNG ถูกปิดไปแล้วในเส้นทางที่ libngu เชื่อมอยู่
ในอีกไฟล์หนึ่ง external/micropython/ports/stm32/rng.c ที่ตรวจสอบตัวแปรเดียวกันแต่ใช้ #if (เช็คค่าถูกต้อง) เมื่อเห็นค่าเป็น 0 มันจึง compile โค้ด branch สำรอง (#else) แทน ซึ่งก็คือฟังก์ชัน rng_get() ที่ return ค่าจาก Yasmarang (Pseudorandom Number Generator - PRNG) ซอฟต์แวร์แทนที่จะอ่านค่าจากชิปฮาร์ดแวร์จริง
ส่วน hardware TRNG ของ Coldcard เอง (stm32/COLDCARD_MK4/rng.c) ยังทำงานถูกต้องสมบูรณ์ แต่มัน export ออกมาเป็น pyb_rng_get_obj / random32() เท่านั้น — ไม่มีที่ไหนในโค้ดทั้งหมดที่ประกาศ symbol ตรง ๆ ชื่อ rng_get() ที่ libngu ต้องการลิงก์ด้วย ผลคือ hardware TRNG ที่ทำงานถูกต้อง กลับถูก “ตัดขาด” จากเส้นทางการสร้าง seed ไปเลย
ปัญหาของการสุ่มแบบซอฟต์แวร์ (Yasmarang) คือมันไม่ใช่การสุ่มที่แท้จริง แต่อาศัย Seed ตั้งต้นมาคำนวณผ่านสมการคณิตศาสตร์ โดยดึงค่ามาจาก 3 ส่วนหลัก ๆ คือ:
UID_low32— หมายเลขประจำตัวชิป (ไม่ใช่ความลับ, fixed device metadata)SysTick->VAL— รอบการทำงานของ CPU (คาดเดา/จำกัดช่วงได้)RTC->TRและRTC->SSR— ค่าเวลา (คาดเดา/จำกัดช่วงได้เช่นกัน)
จุดที่พังจริง ๆ อยู่ตรงนี้: ระบบที่ควรมีความปลอดภัยระดับ 256-bit (การเดาแทบเป็นไปไม่ได้) ถูกลด Entropy ลงเหลือแค่ราว 32-72 bit เท่านั้น — บนรุ่น Mk2/Mk3 ตัวเลขนี้ถึงขั้นกลายเป็น deterministic ทั้งหมด (ใช้ UID + timing เท่านั้น ไม่ต้องรู้อะไรเพิ่มเลยต่อเครื่อง) ส่วนรุ่น Mk4/Q/Mk5 มีการผสม entropy จาก secure element เข้ามาบ้างตอน boot แต่ก็ hash แล้วเก็บไว้แค่ 4 ไบต์ ก่อนใช้แทนที่ state คำนวณ Yasmarang เพียง 1 word (32-bit) เท่านั้น ทำให้เพดาน entropy ที่แท้จริงต่ำกว่าตัวเลข 128-bit ที่ตั้งใจไว้มาก
นั่นแปลว่าอะไร? ถ้าผู้โจมตีรู้แค่ “ช่วงเวลาโดยประมาณ” ที่คุณเปิดเครื่องขึ้นมาสร้าง Wallet ครั้งแรก พวกเขาสามารถใช้คอมพิวเตอร์ประสิทธิภาพสูงจำลองค่าเวลาและรอบ CPU ย้อนหลัง แล้วทำ Brute-force attack ไล่หาค่าที่เป็นไปได้ โดยไม่จำเป็นต้องขโมยเครื่องหรือรอให้อุปกรณ์ต่อเน็ตเลยด้วยซ้ำ — แค่รู้ address สาธารณะก็สามารถ regenerate candidate seed แล้วเทียบ address เพื่อยืนยันได้
Timeline
| วันที่ | เหตุการณ์ |
|---|---|
| 2018-05 | MicroPython upstream เพิ่ม Yasmarang software fallback เข้ามาใน codebase (ยังไม่เกี่ยวกับ Coldcard ณ จุดนี้) |
| 2021-01-28 | libngu STM32 guard (#ifndef ที่บกพร่อง) เริ่มมีอยู่ในโค้ด |
| 2021-03-01 | มีการ migrate ระบบ seed generation ไปใช้ libngu (commit ที่มีรายงานว่าชื่อ b18723dd — "First pass w/ libNgU") |
| 2021-03-17 | Firmware v4.0.0 ออกวางจำหน่ายพร้อมเส้นทางที่มีช่องโหว่ |
| 2021-05-21 | commit 37e4af54 (“runs”) — จุดที่ตั้งค่า MICROPY_HW_ENABLE_RNG (0) เข้าไปจริง ตามการสืบสวนย้อนหลัง |
| 2022-03-11/14 | เพิ่ม API reseed() แบบ 32-bit และเริ่มใช้ boot reseeding บน Mk4 v5.0.0 |
| 2026-06-16/17 | มีการทำ security audit ภายนอกต่อ codebase (commit a24a894c) — ตรวจ RNG แล้วสรุปว่าปลอดภัย (false negative) เพราะ git submodules สำคัญ (external/libngu, external/micropython ฯลฯ) ไม่ได้ถูก initialize ไว้ตอน clone |
| 2026-07-30 | Block และนักวิจัยด้านความปลอดภัยอื่น ๆ เริ่มสังเกตรายงานผู้ใช้ Coldcard ถูกขโมยเงิน และเริ่มสืบสวน |
| 2026-07-30/31 | Coinkite ออก advisory และ hot patch (commit ca724637 — "fixes rng") |
| 2026-08-02 | ผู้ตรวจ audit เดือนมิถุนายนเผยแพร่ postmortem อธิบายว่าทำไมถึงพลาดบั๊กนี้ |
Commit และไฟล์ที่เกี่ยวข้อง
Repository: github.com/Coldcard/firmware
| Commit / PR | คำอธิบาย |
|---|---|
b18723dd — “First pass w/ libNgU” (2021-03-01) | migrate เส้นทาง seed generation ไปพึ่งพา libngu |
37e4af54 — “runs” (2021-05-21) | commit ที่ตั้งค่า #define MICROPY_HW_ENABLE_RNG (0) ซึ่งเป็นจุดกำเนิดบั๊กจริง (ตามการสืบย้อนใน audit postmortem) |
a24a894c (2026-05-16, master ณ ตอน audit) | สถานะโค้ดที่ถูก audit ในเดือนมิถุนายน 2026 (ก่อนแก้บั๊ก) |
ca724637 — “fixes rng” (2026-07-31 hotfix) | แก้ไขให้ rng_get() กลับไปผูกกับ hardware TRNG จริง — แต่ในเวลาต่อมามีรายงานว่า hotfix นี้เองมีบั๊กใหม่เรื่อง rng_get_or_fault() ที่ไม่มี recovery path เมื่อเกิด error flag จน RNG peripheral ค้างถาวร (ดู PR #692) |
ไฟล์หลักที่เกี่ยวข้อง:
shared/seed.py:319-325, 599— จุดเรียกใช้ngu.random.bytes(32)ในgenerate_seed()/make_new_wallet()external/libngu/ngu/random.c:28-30— guard ที่บกพร่อง (#ifndefแทนที่จะเป็น#if)stm32/COLDCARD/mpconfigboard.h(บรรทัด ~77) และstm32/COLDCARD_MK4/mpconfigboard.h(บรรทัด ~78) — จุดที่ตั้งค่าMICROPY_HW_ENABLE_RNG (0)external/micropython/ports/stm32/rng.c:30-96— จุดที่ MicroPython เช็คค่าเดียวกันถูกต้องด้วย#ifแล้ว fallback ไปที่pyb_rng_yasmarang()stm32/COLDCARD_MK4/rng.c— hardware TRNG ที่ถูกต้องแต่ export symbol คนละชื่อ (random32()) จึงไม่ได้ถูกใช้งานshared/mk4.py:43-49— จุดที่ entropy จาก secure element ถูก truncate จาก 256 บิตเหลือ 32 บิตก่อนใช้reseed()
ทำไม Audit ก่อนหน้านี้ถึงจับบั๊กนี้ไม่ได้
น่าสนใจว่ามี security audit ภายนอกเกิดขึ้นก่อนบั๊กนี้จะถูกเปิดเผยเพียง ~6 สัปดาห์ (audit วันที่ 2026-06-17) และ “Weak RNG source” อยู่ใน scope การตรวจอย่างชัดเจน แต่กลับถูกสรุปว่าเป็น “false positive” โดยระบุว่า “Entropy = STM32 TRNG + ATECC608 + DS28C36 mixed via SHA256d … No weak PRNG in the seed/key/signing path”
ฉบับขำๆ (เข้าใจง่าย)
เอางี้ ลองนึกภาพเหตุการณ์แบบนี้
มึงล็อกบ้านด้วยกุญแจ แต่ยามที่ประตูดันตรวจแค่ว่า “มีกุญแจในมือมั้ย” ไม่ได้ตรวจว่า “กุญแจนั้นมันใช่ดอกที่ไขได้จริงป่ะ” — เจ้าของบ้านเลยยื่นกุญแจเปล่าๆ ที่แกะสลักคำว่า “ปลอม” ไว้ตรงกลางดอกไปให้ยาม ยามเห็นว่า “อ๋อ มีของอยู่ในมือ” ผ่านฉลุยเลยจ้า เข้าบ้านได้สบายมาก 5 ปีเต็มๆ
ทีนี้มาถึง audit ที่ควรจะจับได้ก่อนหน้านี้… เรื่องมันตลกกว่านั้นอีก
หมอ (auditor) เดินเข้ามาตรวจร่างกายคนไข้ (Coldcard) แล้วถามหา “ไต” (libngu) กับ “ตับ” (micropython) — ปรากฏว่า ไม่มีอวัยวะพวกนี้ในตัวคนไข้เลย เพราะตอน clone ร่างกายมา ลืมกด git submodule update --init เป็นโพรงกลวงๆ อยู่ในท้อง แต่หมอไม่ตกใจ ไม่ถามหาไต ไม่ถามหาตับ
หมอกลับไปอ่าน สติ๊กเกอร์แปะข้างเตียงคนไข้ แทน ซึ่งเขียนไว้ว่า:
“ผมมีไตสำรองของตัวเองอยู่แล้วนะครับ (ขายไตเก่าไปแล้ว)”
หมออ่านจบ พยักหน้า: “อ๋อ งั้นก็โอเคครับ สุขภาพดีเยี่ยม ไม่มีอะไรน่าห่วง” — เซ็นใบรับรองแพทย์ให้เรียบร้อย โดยไม่เคยง้างซี่โครงเข้าไปดูเลยสักครั้งว่าไตสำรองที่ว่านั้นมันต่ออยู่จริงมั้ย หรือมันแค่สายยางเปล่าๆ ห้อยอยู่เฉยๆ
แล้วที่ฮาที่สุดคือระบบตรวจของหมอมันมีแค่ปุ่ม “ผ่าน ✅” กับ “ไม่ผ่าน ❌” — ไม่มีปุ่ม “เดี๋ยวๆ กูหาอวัยวะมึงไม่เจอ จะให้ตอบไงวะ” พอหาไม่เจอ ระบบเลยเดาส่งเดชกดปุ่ม “ผ่าน” ไปเอง
เหมือนตำรวจไปสืบคดีที่บ้านร้าง ประตูล็อก ไม่มีใครอยู่ แล้วสรุปสำนวนว่า “ไม่พบหลักฐานการก่ออาชญากรรม คดีปิด” ทั้งที่ความจริงต้องเขียนว่า “กรู…เข้าบ้านไม่ได้ด้วยซ้ำ ตอบไม่ได้”
สรุปคือทีมตรวจไปอ่าน “สเปกบนกล่อง” ว่าไตดีแค่ไหน แทนที่จะแกะเครื่องออกมาเช็คว่าไตมันต่ออยู่จริงรึเปล่า — แล้วก็เซ็นชื่อมั่นใจเต็มร้อยซะด้วยว่า “ปลอดภัย 100%”
สาเหตุที่ทำให้ตรวจไม่พบ (ตามที่ postmortem วิเคราะห์ไว้):
- Git submodules ไม่ได้ถูก initialize — โฟลเดอร์
external/libngu,external/micropythonที่เป็นจุดเกิดบั๊กจริงว่างเปล่าตอน clone (ใช้ clone แบบไม่--recursiveและไม่ได้รันgit submodule update --init) ทำให้ auditor ไม่เห็นไฟล์ที่มีบั๊กอยู่จริง ๆ เลย - Adversarial verifier ไม่มีทางเลือก “ไม่แน่ใจ” — มีแค่ CONFIRMED/REFUTED สองทาง เมื่อ source ไม่มีให้ตรวจ ก็ถูกจัดเป็น REFUTED (false) แทนที่จะเป็น UNVERIFIABLE
- ไม่มีใครถามว่า entropy มาจากไหนจริง ๆ — การตรวจเน้นที่ dataflow จาก untrusted input ไปยัง sink แต่ที่มาของ entropy เป็นคำถามเชิง “linking” (ต้อง resolve symbol ไปยัง definition ข้าม build configuration) ซึ่งเป็นคนละแบบกับการอ่านโค้ดตรง ๆ
- เชื่อ docstring มากกว่าการ trace จริง — comment ว่า “best-quality high entropy TRNG bytes” ถูกรับเป็นหลักฐานแทนที่จะตามรอย call
- ไฟล์ที่เห็นได้เล่าเรื่องที่ดูสมเหตุสมผล —
#define MICROPY_HW_ENABLE_RNG (0)คู่กับ comment “We have our own version of this code” อ่านแล้วเหมือนการตั้งใจเปลี่ยนไปใช้ hardware RNG จริง ๆ (ซึ่งเป็นเจตนาดั้งเดิม แต่ผลลัพธ์จริงตรงกันข้าม)
บทเรียนสำคัญ: สำหรับฟังก์ชันแบบ random_bytes() ต้อง trace symbol ไปจนถึง definition จริงข้าม build configuration ทั้งหมดก่อนจะสรุปคุณภาพของมันได้ และ build-configuration macro (#ifndef vs #if) สมควรได้รับการตรวจสอบเข้มงวดเท่ากับ logic code ทั่วไป
ผลกระทบ
- ช่วงที่ได้รับผลกระทบ: Coldcard Mk2/Mk3 firmware 4.0.1–4.1.9 (เต็มรูปแบบ, deterministic) และบางส่วนใน Mk4/Q/Mk5 (entropy ลดแต่ไม่ถึงขั้น deterministic เต็มรูปแบบ)
- Entropy ที่แท้จริง: Coinkite ประเมินไว้ราว ~40 bits (Mk3) และ ~72 bits (Mk4/Mk5/Q) เทียบกับ 128 bits ที่ 12-word BIP-39 seed ควรมี — บางแหล่งวิเคราะห์เชิงลึกกว่านั้นชี้ว่าเพดานจริงต่ำกว่านี้อีก (ใกล้ 2³²)
- มูลค่าความเสียหาย: รายงานจากสื่อต่าง ๆ ให้ตัวเลขต่างกัน อยู่ในช่วง 38–88 ล้านดอลลาร์ (ยังไม่มีตัวเลขสรุปที่เป็นทางการหนึ่งเดียว)
- หมายเหตุสำคัญ: ความเสี่ยงขึ้นกับ เวอร์ชัน firmware ที่ใช้ตอนสร้าง seed ครั้งแรก ไม่ใช่ firmware เวอร์ชันปัจจุบัน และไม่ใช่วันที่ซื้อเครื่อง — การอัปเดต firmware ไม่ทำให้ seed เดิมที่สร้างไว้แล้วปลอดภัยขึ้นย้อนหลัง
บทเรียนและวิธีป้องกัน (สำหรับผู้ใช้ COLDCARD)
หากคุณใช้ COLDCARD ที่สร้างกระเป๋าในช่วงปี 2021 ถึงกลางปี 2026 คุณมีความเสี่ยง สิ่งที่ควรทำ:
- อัปเดต Firmware ทันที — ทาง Coinkite ออก hot patch แก้ปัญหานี้แล้ว (commit
ca724637) รีบอัปเดตเป็นเวอร์ชันล่าสุดเพื่อปิดช่องโหว่สำหรับ seed ใหม่ ที่จะสร้างต่อจากนี้ (ไม่ช่วย seed เก่า) - สร้าง Wallet ใหม่ด้วยฟีเจอร์ “Dice Rolls” — จุดแข็งของ COLDCARD คือรองรับการสร้าง Seed โดยไม่ต้องพึ่งระบบสุ่มของเครื่องเลย ให้หยิบลูกเต๋าจริงมาทอย (อย่างน้อย 50-99 ครั้ง) แล้วป้อนผลลัพธ์เข้าเครื่อง ระบบจะคำนวณ Seed จากผลทอยลูกเต๋าล้วน ๆ ซึ่งเป็นวิธี Trustless 100%
- ย้ายสินทรัพย์โดยเร็ว — เมื่อได้กระเป๋าใหม่ที่สร้างจากลูกเต๋าและรันบน Firmware เวอร์ชันล่าสุดแล้ว ให้รีบโอน Bitcoin ทั้งหมดจากกระเป๋าเก่า (ที่อาจสร้างขึ้นในช่วง firmware มีช่องโหว่) มายังกระเป๋าใหม่ทันที
- สำหรับ multisig: หากกระเป๋า multisig ประกอบด้วย Coldcard ที่มีช่องโหว่ทั้งหมด ความเสี่ยงยังคงอยู่เต็มรูปแบบ ต้องมี quorum ของอุปกรณ์ที่ปลอดภัยจริงจึงจะป้องกันได้
สรุป: เคสนี้สอนให้เห็นว่า ต่อให้ฮาร์ดแวร์ถูกออกแบบมาแน่นหนาแค่ไหน แค่โค้ดผิดโทเคนเดียว (#ifndef แทน #if) ก็กลายเป็นบั๊กมูลค่าหลายสิบล้านดอลลาร์ได้ และแม้แต่ security audit ที่ตั้งใจตรวจ RNG โดยเฉพาะก็ยังพลาดได้ หากสภาพแวดล้อมการตรวจ (เช่น git submodules) ไม่สมบูรณ์
สรุปรวบยอด
- บั๊กเกิดจาก: โค้ดเช็คผิดคำสั่ง (
#ifndefแทนที่จะเป็น#if) — เหมือนเช็คว่า “มีกุญแจอยู่ในมือรึเปล่า” แทนที่จะเช็คว่า “กุญแจนี้ไขประตูได้จริงไหม” พอมีกุญแจ (แม้จะเป็นกุญแจปลอม) ระบบก็ปล่อยผ่านให้เข้าบ้านได้เลย - ผลลัพธ์: Entropy ของ seed หล่นจาก 128/256 บิต เหลือแค่ 32-72 บิต ทำให้ brute-force ได้จริง
- ทำไม audit หาไม่เจอ:
- ไฟล์จริงหายไปตอน clone (ลืมโหลด submodule) — หาของในลิ้นชักที่ไม่มีอยู่จริง
- เชื่อป้าย ไม่เชื่อของจริง — เห็น comment สวยๆ ก็เชื่อ ไม่ได้ตามรอยโค้ดจริง
- ระบบตรวจไม่มีตัวเลือก “ไม่รู้” — มีแต่ ผ่าน/ไม่ผ่าน พอข้อมูลขาด เลยเดาว่า “ผ่าน” แทนที่จะบอกว่า “ตรวจไม่ได้”
- บทเรียน: ต่อให้ผู้ตรวจเก่งแค่ไหน ถ้า environment ไม่ครบ (ไฟล์หาย, submodule ไม่ได้โหลด) ผลตรวจก็ไม่มีความหมาย และการเช็คแค่ “มีตัวแปรนี้ยัง” ไม่เท่ากับเช็คว่า “ตัวแปรนี้ทำงานถูกต้องไหม”
อ้างอิง
- Coinkite — Technical Deep Dive into the Entropy Issue
- Coinkite — Coldcard Mk3 Seed Generation Warning (Advisory)
- Block Engineering Blog — Predictable RNG Fallback and 32-Bit Reseed in COLDCARD Firmware
- Wizardsardine — Critical Coldcard flaw: what happened, who is affected, and what to do
- Fystack Blog — What the Coldcard Exploit Taught Us About Wallet Entropy
- The Hacker News — Coldcard Hardware Wallet Flaw Linked to $70 Million Bitcoin Theft in 41 Minutes
- TechTimes — Coldcard Hardware Wallet Hacked via Firmware Bug That Bypassed RNG for Five Years
- Korben — A misread zero in Coldcard’s firmware made Bitcoin keys guessable for five years
- Glitchwire — Block Discovers Critical Coldcard Firmware Flaw as $38 Million in Bitcoin Vanishes From 500 Wallets
- AkitaOnRails — Exploiting Coinkite’s RNG Egregious Problem
- Frank Corva (Substack) — This Isn’t the End of Bitcoin Self-Custody
- Dusty Daemon (Insider newsletter) — When random.bytes() runs but doesn’t work
- GitHub PoC — DK27ss/ColdCard-38M-PoC
- GitHub PR — Coldcard/firmware#692 — rng: recover the TRNG after a seed/clock error instead of failing forever
- Nick Farrow (Gist) — Coldcard Firmware Security Audit 2026-06-17 + Audit log and postmortem: the June 2026 pass that missed the entropy bug
เอกสารนี้รวบรวมจากรายงานสาธารณะหลายแหล่งเพื่อวัตถุประสงค์ทางการศึกษา ไม่ใช่คำแนะนำทางการเงินหรือความปลอดภัยอย่างเป็นทางการ กรุณาตรวจสอบ advisory ต้นฉบับจาก Coinkite ก่อนดำเนินการใด ๆ กับกระเป๋าของท่าน
Retrieve the raw markdown file or structured JSON of this post directly in your command line:
curl -sL https://dekkapok.engineering/blogs/coinkite.txt curl -sL https://dekkapok.engineering/blogs/coinkite.json