MultiversX Tracker is Live!

[SERIOUS 2] Results of reproducing the MK3 weak-RNG search: 1157 weak wallet roots reconstructed and evidence the hack extended to ETH.

All Cryptocurrencies

by COINS NEWS 30 Views

I spent the past month working to study, reconstruct, and play with the MK3 (not MK2) Coldcard and its weak RNG. I set out to reproduce what I speculated was the attacker's search behavior to identify victims rather than trying to follow the bitcoin transactions from known attacker wallets. First, I want to credit Coinkite, Galaxy Research, Wizardsardine, and Praveen Perera for their prior work since it formed my starting point.

The most strking thing I can't find any one talking about yet is that the attack also drained ETH from the weak-seed wallets. It was not much, only about 15.5ETH; however, it may help those who are much better at chain analytics than I am.

TLDR: I implemented the affected MK3 seed generation process independently and deployed it on a NVIDIA 3090 GPU, using bloom filters to accelerate the search and electrs to filter out false positives. So far:

  • 1157 distinct week-seed wallet roots have been reconstructed.
  • 2808 Bitcoin addresses matched to the wallets.
  • All 2808 Bitcoin addresses are empty -- they were either drained in the attack or were previously emptied by their owners.
  • Cross chain analysis of the wallets found 8 Ethereum wallets, all drained. There was one LTC wallet; however, all LTC was moved from it back in 2022. Future work may look at XRP, SOL, DOGE or other chains. I'm undecided.

I'm not going to publish mnemonics, private keys, or the PRNG coordinates that regenerate them.

The Vulnerability Reproduction

The vulnerability is now well understood publicly: affected firmware stopped getting seed entropy from the STM32 hardware RNG and then used micropython's non-cryptographic Yasmarng PRNG. For the MK3, the initial state reduces to a pad defined by:

pad = uid32 ^ SysTick->VAL

The uid32 is not a fold or hash of the STM32's full 96-bit unique ID. It is the first 32-bit word, read directly from the STM32 UID address: *(uint32_t*)MP_HAL_UNIQUE_ID_ADDRESS. On the MK3 this starts at 0x1FFF7A10.

The full 12 byte UID is read elsewhere in the firmware for other purposes but not used by the RNG to set its state.

The first UID word contains structured manufacturing information associated with die position, while SysTick->VAL contributes timing state. Everything after that is deterministic once the PRNG state and RNG-consuming sequence of events are known. This effectively means the pad, as represented by UID word 0, represents a unique hardware serial number.

This UID pattern is consistent with Wizardsardine's analysis that estimated approximately 2^22 initial states for the MK3. In my runs, I found that the pad dimension space was 2^24 bits wide.

There was an interesting consequence of using UID 0 word 0 and I think its worth mentioning. The first UID word is not uniformly random. The first UID word encodes the X/Y postion of the die on the silicon wafer. As I recovered more weak wallets, their candidate states showed clustering consistent with groups of STM32 parts entering coldcard's MK3 manufacturing suply chain together. Basically, the vulnerable RNG did not just reduce the cryptograph search space, it seems to have preserved traces of the physical manufacturing distribution used to build the cold card devices themselves.

Practical Search Cost

My implementation was a candidate search on a Nvidia 3090 from my old gaming PC. I computed a bloom filter and then performed the seed computation and path search on GPU using the filter loaded into the GPU. As results were reported back, I queried a locally hosted mempool/electrs instance to filter out false positives. A complete pass through the 24-bit pad dimension took just a bit more than four and a half hours.

Bitcoin Results

The search yielded 1,157 reconstructed weak wallets. Of those, 678 showed their last on-chain movement on or after July 15, 2026. The majority of transactions occurred starting July 30th. This group includes 104 wallets whose last movement was on July 30, 541 on July 31, and 25 on August 1. A small set of wallets were active between July 15th and July 29th, but I don't see evidence of a shared collector between them and the main wave, and the behavior seems like normal owner activity.

From what I saw, ~982.96 were drained during the attack. There was one wallet that was active during the attack that had a 0.051btc transaction during the attack, but since it used a common destination address for a little over a year, I excluded it from the total. That same address later received two small transactions on Aug 2nd and Aug 4th that were swept by the attacker.

Bitcoin Transaction Summary Table

These are transaction on or after July 30th where the destination address recieved a sweep from more than 1 wallet. I do not claim all of these are an attacker or that they are the same attacker. I consider any destination as receiving sweeps from more than one week MK3 wallet as suspect.

Destination Transactions Wallets Involved BTC Total First Seen Last Seen
bc1qsjrf5ze5tmulz7y2x4pc7qaex2a35sanp3rqlx 794 200 34.917319 July 31 04:54 July 31 08:36
bc1qnk4zh9qcnap2mycp56qjrgza3cc8ylrh8fecp0 414 187 527.402589 July 30 01:36 July 30 01:51
bc1qc779m8gec84k3t0ffvu0pps94zheht7lr7ueyn 212 82 279.792016 July 30 01:32 July 30 01:32
bc1qmd5m5ktv7m5ffujxv4248fxv36myvdx79n8jp6 91 74 30.183625 July 31 05:48 July 31 05:58
bc1qh0l7q0mca3ln7wsl9luwns0jc9jhgrtft025l4 62 31 0.435072 July 30 1:10 July 30 01:10
bc1qdaarag7729c2n4l2wnyt3hkhfpcs66n98z7uuh 55 18 20.642015 July 30 01:10 July 30 01:10
bc1q0mh6rs0mjvv5ncdyqwhqma7hgup3aycucsc279 9 9 0.509860 July 31 20:07 July 31 20:16
bc1qf2my39y2lfgp2pylnhu8q2xktqumlpjy2fur4d 7 6 0.027447 Aug 1 04:30 Aug 1 09:35
bc1qcr9wcc6k0dlqgwfze3dfvwlj4xgvnrfylrz5k7 6 3 0.341358 July 31 18:51 July 31 18:51
bc1qgr36zfhfw2uph8w2545y0np65qgfw6v2r2drrx 3 6 0.038280 July 31 16:18 July 31 17:07
bc1q5z9gl2kl736hhwkrpau9m8n8656veyu4phew4z 3 3 0.133538 July 31 12:46 July 31 12:46
bc1qk87f7mxqxv63rxlp4kl43lltxf866fqhhzj46h 3 2 0.134537 July 31 03:27 July 31 05:24
bc1q9ancn2kw5malzz25395009zssmk6k5d443kjv5 2 4 0.000458 July 31 19:13 July 31 19:29
bc1q4r63xh9l3vg7zn2zterjvf6me49xwyfscxvwpd 2 2 0.553943 July 31 12:38 July 31 12:38
bc1q69gptc6cmjmpmxkpjrhs960kp5df6avwuufqvx 2 2 0.331536 July 31 12:23 July 31 13:30
bc1qme77vs7vuxdj6rxf78m6xenv4v9fk7ftzxtnwe 2 2 0.311292 July 31 12:23 July 31 13:30
bc1qzrl67rtyaqdvtl78rlklxmraqjk7d9f6cf23jm 2 2 0.089004 July 31 16:03 July 31 16:03
bc1qjvufmqrhm6pk7cevyapc6mqpm5mk4anlk8ar99 2 2 0.059995 July 31 13:04 July 31st 13:14
bc1qjd6tcd5ey96fdujpkr7zgn2zjzp29h208xlvxg 2 2 0.010009 July 31 19:53 July 31st 19:53

ETH Results

On a hunch, I attempted to scan other chains for transactions associated with the wallets. I first focused on ETH. Out of all of the wallets checked, I found 7 ETH active roots. There seem to be two collector addresses, perhaps hinting at two actors? Again, I only consider these interesting of further research because they collect transactions from more than one weak mk3 wallet.

Destination Transactions Wallets Involved ETH Amount First Seen Last Seen
0x968626a5769ac2B26FC01c2b9B1225d16a54B154 3 3 15.2130978 August 1st 04:21 August 1st 04:45
0x490F26D4BA65753F87c5885476F7d7d35026204A 2 2 0.1931901 August 3rd 22:31 August 29th 08:51:59

Of note is that one wallet that was drained to 0x490F was receiving small amounts of funds during the month that were later transferred to the 0x490F wallet.

Sources and Prior Research:

submitted by /u/pavvappav
[link] [comments]
Get BONUS $200 for FREE!

You can get bonuses upto $100 FREE BONUS when you:
💰 Install these recommended apps:
💲 SocialGood - 100% Crypto Back on Everyday Shopping
💲 xPortal - The DeFi For The Next Billion
💲 CryptoTab Browser - Lightweight, fast, and ready to mine!
💰 Register on these recommended exchanges:
🟡 Binance🟡 Bitfinex🟡 Bitmart🟡 Bittrex🟡 Bitget
🟡 CoinEx🟡 Crypto.com🟡 Gate.io🟡 Huobi🟡 Kucoin.



Comments