Найти в Дзене
ExploitDarlenePRO

RingSide Replay Attack (Milk Sad CVE-2023-39910): Recovering private keys of lost Bitcoin wallets by exploiting a critical weak entropy vuln

The RingSide Replay Attack (Milk Sad CVE-2023-39910) is a textbook example of how flaws in the entropy source can have catastrophic consequences for Bitcoin and other cryptocurrencies. This attack, known as the “Entropy Weakness Exploit in Key Generation” or “PRNG Seed Recovery Attack,” illustrates scientifically how a fundamental flaw in cryptoengineering can undermine trust in entire classes of wallets and threaten all user assets for years to come. cve+4 The CVE-2023-39910 vulnerability clearly demonstrates that a single mistake in the choice of a cryptographic random number generator can undermine the entire security of Bitcoin and violate the fundamental trust in decentralized assets. Weak entropy in seed and private key generation gave attackers a real opportunity to reproduce the keys of millions of users and steal cryptocurrency en masse—both from the Bitcoin network and from other blockchains using vulnerable Libbitcoin wallets . An attacker with knowledge of a random number
Оглавление

RingSide Replay Attack – A Spectacular Hack Based on Weak Entropy

The RingSide Replay Attack (Milk Sad CVE-2023-39910) is a textbook example of how flaws in the entropy source can have catastrophic consequences for Bitcoin and other cryptocurrencies. This attack, known as the “Entropy Weakness Exploit in Key Generation” or “PRNG Seed Recovery Attack,” illustrates scientifically how a fundamental flaw in cryptoengineering can undermine trust in entire classes of wallets and threaten all user assets for years to come. cve+4

The CVE-2023-39910 vulnerability clearly demonstrates that a single mistake in the choice of a cryptographic random number generator can undermine the entire security of Bitcoin and violate the fundamental trust in decentralized assets. Weak entropy in seed and private key generation gave attackers a real opportunity to reproduce the keys of millions of users and steal cryptocurrency en masse—both from the Bitcoin network and from other blockchains using vulnerable Libbitcoin wallets .

An attacker with knowledge of a random number generator vulnerability (for example, the use of a Mersenne Twister-type PRNG with small seeds) stages a veritable “cryptographic boxing match in the ring”: they observe the public keys and salts in Borromean ring signatures published on a blockchain or other protocol that uses libbitcoin.

Critical Vulnerability in Private Key Generation: The Devastating Milk Sad Attack on Bitcoin Cryptocurrency Security

https://cryptou.ru/btcdetect

A Critical Vulnerability in Ring Signatures and Its Impact on Bitcoin Security

The development of cryptocurrencies has given rise to numerous innovative cryptographic protocols, among which ring signature systems play a crucial role. However, even the most modern schemes are vulnerable to risks due to poorly implemented random number generators. In 2023, a widely publicized attack, scientifically dubbed “Milk Sad” and registered as CVE-2023-39910, resulted in the mass theft of hundreds of thousands of dollars’ worth of bitcoins due to a weakness in the pseudorandom number generator in the libbitcoin library. feedly+3

The mechanism of vulnerability occurrence

Vulnerable versions of Libbitcoin Explorer (3.0.0–3.6.0) used the mt19937 (Mersenne Twister) generator to generate private key entropy, which limited the internal entropy to only 32 bits, regardless of user settings. This meant that an attacker could:

  • Fix the public parameters of the transaction (public ring, salts, challenge).
  • Try all possible seed values ​​(2^32 options in total) to recover the salt and the entire path to calculating the private key.
  • Obtain a user’s private key and move funds without the owner’s knowledge. cryptodeeptech+1

Impact on Bitcoin cryptocurrency attacks

This vulnerability allowed attackers to carry out targeted mass theft of bitcoins from wallets created using vulnerable versions of the library. Here’s a scientific analysis of the consequences:

  • Compromise of private keys: An attacker could reproduce the key generation process and find a private key for any known public address if it was generated via a “bx seed” or other vulnerable method.
  • Massive thefts: In 2023, over $900,000 was stolen from the Bitcoin wallets of users whose keys were compromised using the method described. cryptodeep+2
  • A threat to the entire Bitcoin community: Bitcoin, as a system based on the complete irreversibility of transactions, does not provide any means of recovery or return of assets after theft using a private key.
  • Widespread Impact: The vulnerability affected not only Bitcoin, but also other cryptocurrencies where Libbitcoin was used to generate keys (Ethereum, Dogecoin, Zcash, etc.). cryptodeeptech

Scientific name of the attack and its CVE

  • Scientific name: Milk Sad Attack (Weak entropy attack on PRNG in private key/seed generation).
  • CWE Standard Category: CWE-338 (Use of a Cryptographically Weak Pseudorandom Number Generator).
  • Registered threat ID: CVE-2023-39910.incibe +3

Code example – vulnerable spot

cpp:

// Уязвимый вариант — слабый PRNG!
std::mt19937 rng(seed);
// seed — 32-битное значение из системного времени и/или пользователя
uint256 secret;
for (size_t i = 0; i < 32; ++i)
secret[i] = rng() & 0xFF;
// всего 2^32 вариантов!

How to prevent such attacks in the future

  • Use only cryptographically strong random number generators: /dev/urandom, OpenSSL RAND_bytes, system CSPRNG.
  • Perform regular audits of third-party libraries and carefully check their documentation.
  • If the security of private keys has already been compromised, funds must be moved to a new address immediately.

A secure code snippet for generating a private key:

cpp:

#include <fstream>
void secure_random_bytes(uint8_t* buf, size_t len) {
std::ifstream urandom("/dev/urandom", std::ios::in | std::ios::binary);
if (!urandom) throw std::runtime_error("Cannot open /dev/urandom");
urandom.read(reinterpret_cast<char*>(buf), len);
if (urandom.gcount() != static_cast<std::streamsize>(len))
throw std::runtime_error("Read error from /dev/urandom");
}
// Генерация нормально распределённого защищённого секрета
std::array<uint8_t, 32> secret;
secure_random_bytes(secret.data(), secret.size());

Conclusion

Milk Sad (CVE-2023-39910) is a textbook example of how flaws in the entropy source can have catastrophic consequences for Bitcoin and other cryptocurrencies. This attack, known as the “Entropy Weakness Exploit in Key Generation” or “PRNG Seed Recovery Attack,” illustrates scientifically how a fundamental flaw in cryptoengineering can undermine trust in entire classes of wallets and threaten all user assets for years to come. cve+4

Cryptographic vulnerability

Analysis of cryptographic vulnerabilities in ring signature code

After analyzing the provided Borromean ring signature implementation code and existing research on vulnerabilities in cryptographic systems, I can identify several potential areas where cryptographic vulnerabilities related to secret key and private key leakage may occur.

Main vulnerable areas in the code

1. Lines 46-59: Processing and storing secret keys

cpp:

static bool generate_keys_map(secret_keys_map& out,
const secret_list& secrets) NOEXCEPT
{
for (const auto& secret: secrets)
{
ec_compressed public_key;
if (!secret_to_public(public_key, secret))
return false;
out.insert({ public_key, secret });
}
return true;
}

Vulnerability: Secret keys are stored in cleartext in the data structure secret_keys_map.

https://github.com/libbitcoin/libbitcoin-system/blob/master/src/crypto/ring_signature.cpp
https://github.com/libbitcoin/libbitcoin-system/blob/master/src/crypto/ring_signature.cpp

This structure may remain in memory longer than necessary, creating a risk of leakage via side-channel attacks or memory dumps. crises-deim.urv+1

2. Lines 201-222: Critical operation with secret key

cpp:

// Find secret key used for calculation in the next step.
BC_ASSERT(known_key_index < ring.size());
const auto& known_public_key = ring[known_key_index];
BC_ASSERT(secret_keys.find(known_public_key) != secret_keys.end());
const auto& secret = secret_keys[known_public_key];
// Now close the ring using this calculation:
const auto& k = salts[i];
const auto& x = secret;
const auto s = k - e_i_j * x;
if (!s)
return false;

Critical vulnerability: Line 216 contains a direct use of a secret keyxin an arithmetic operations = k - e_i_j * x. This operation is extremely vulnerable to:

  • Timing attacks : The execution time may depend on the values ​​of the secret key crises-deim.urv
  • Power analysis attacks : Power consumption can reveal secret key information
  • Fault injection attacks : Injecting errors can lead to leakage of key information

3. Lines 29-42: Borromean hash function

cpp:

static ec_scalar borromean_hash(const hash_digest& M, const data_slice& R,
uint32_t i, uint32_t j) NOEXCEPT
{
// e = H(M || R || i || j)
hash_digest hash{};
stream::out::fast stream{ hash };
hash::sha256::fast sink(stream);
sink.write_bytes(R);
sink.write_bytes(M);
sink.write_4_bytes_big_endian(i);
sink.write_4_bytes_big_endian(j);
sink.flush();
return hash;
}

Potential vulnerability: While the function itself appears secure, the order of data concatenation may create opportunities for length extension or collision attacks in certain scenarios. arxiv

4. Lines 147-168: Generation and use of salts

cpp:

static bool calculate_e0(ring_signature& out, const key_rings& rings,
const hash_digest& digest, const secret_list& salts,
const index_list& known_key_indexes) NOEXCEPT
{
// ...
const auto last_R = calculate_last_R_signing(ring, i, digest, out,
known_key_index, salts);
// ...
}

Vulnerability : Salts (salts) are used to generate signatures, but the code does not check their cryptographic strength. If salts are generated with insufficient entropy (as in the Milk Sad vulnerability), this may lead to the possibility of recovering private keys .

Context of vulnerabilities in the Libbitcoin library

It’s important to note that the Libbitcoin library itself has already encountered critical vulnerabilities:

CVE-2023-39910 (Milk Sad) : The entropy generation mechanism in Libbitcoin Explorer 3.0.0-3.6.0 used a weak Mersenne Twister pseudorandom number generator (mt19937), which limited the internal entropy to 32 bits. This allowed attackers to recover private wallet keys and steal over $900,000. incibe+3

Safety recommendations

For line 216 (critical operation):

  • Use constant-time arithmetic to prevent timing attacks
  • Apply camouflage techniques to protect against side-channel attacks
  • Clear secret data after use

For the generate_keys_map function:

  • Use secure memory allocation to store secret keys
  • Apply memory obfuscation techniques
  • Ensure keys are securely deleted from memory after use

General recommendations:

  • Conduct an audit of entropy sources for salt generation
  • Add additional validity checks for cryptographic parameters
  • Use proven cryptographic libraries for critical operations

The most critical line is 216 , where a direct computation using the secret key occurs without protection from side-channel attacks sciencedirect+1

https://b8c.ru/btcdetect
https://b8c.ru/btcdetect

Btcdetect: Scientific Analysis of Entropy Weakness Exploits in Bitcoin Private Key Recovery

The Milk Sad vulnerability (CVE-2023-39910) revealed a devastating flaw in the entropy generation mechanism of the Libbitcoin library, which relied on the non-cryptographic Mersenne Twister (mt19937) pseudorandom number generator. This weakness reduced the search space of generated Bitcoin private keys to only 2322^{32}232 possibilities, enabling adversaries to reconstruct wallet keys through brute-force examination of deterministic outputs.
To address such risks in both research and defensive contexts, specialized instruments like
Btcdetect can be leveraged. Btcdetect, developed as a cryptographic entropy analysis and detection framework, is capable of identifying weak randomness in Bitcoin wallet generation, tracing infected keyspaces, and reconstructing vulnerable entropy paths. Its methodology provides a pathway both for academic exploration of PRNG-based attacks and for recovery of lost cryptocurrency wallets by re-deriving private keys from flawed entropy sources.

https://cryptou.ru/btcdetect

Core Mechanism of Btcdetect

Btcdetect operates by systematically tracing the entropy initialization process in key generation routines, applying mathematical analysis, and reproducing potential weak seeds. Its operational model involves three primary steps:

  1. Entropy Source Profiling
    Btcdetect collects and characterizes entropy used in wallet creation by analyzing wallet binaries, entropy initialization calls, and key generation code paths. In the case of Libbitcoin Explorer versions 3.0.0–3.6.0, Btcdetect isolates the specific use of std::mt19937 as the central weakness.
  2. Seed Space Exhaustion
    Given the restricted entropy space of only 2322^{32}232 possible seeds, the tool performs an efficient full search using parallelized keyspace traversal. Each seed candidate is expanded into a private key, which is then translated into its compressed/uncompressed Bitcoin address format.
  3. Blockchain Correlation
    Derived addresses are rapidly compared against the Bitcoin blockchain using a real-time UTXO set scanner. In this stage, Btcdetect validates which reconstructed private keys map to existing on-chain addresses, thereby proving exposure and enabling recovery attempts.

Impact on Bitcoin Security

The implication of Btcdetect’s research methodology is profound in the context of CVE-2023-39910 and similar entropy-related flaws. By exposing the deterministic nature of weak key generation, it demonstrates how millions of wallets may be at risk when entropy is not cryptographically secure.

  • Private Key Reconstruction
    Given the predictability of mt19937, attackers (or ethical security analysts) are able to reconstruct private keys tied to visible public addresses. This directly undermines the foundation of Bitcoin security—the assumption that private keys are computationally unguessable.
  • Mass Exploitation Risk
    The fact that Btcdetect can traverse the entire vulnerable entropy space within hours on modern GPU clusters implies that attackers can automate mass wallet scanning. This explains the large-scale thefts exceeding $900,000 in the Milk Sad incident.
  • Recovery of Lost Wallets
    In legitimate contexts, Btcdetect enables the ethical recovery of user funds when original seeds or mnemonics were generated under flawed PRNG conditions. By reconstructing predictable entropy pathways, wallets mistakenly assumed to be irretrievable can be restored.

Cryptographic Implications

The scientific significance of Btcdetect extends beyond the Milk Sad case, as its methodology applies to a wide class of PRNG vulnerabilities:

  • Weak entropy (CWE-338): Predictable number sequences such as mt19937, linear congruential generators (LCGs), or other insecure PRNGs fall under exploitable models.
  • Side-channel artifacts: Inadequate clearing of entropy pools may leave predictable system states, detectable by entropy profiling.
  • Cross-ecosystem impact: Since many cryptocurrencies adopt similar libraries, Btcdetect’s model extrapolates beyond Bitcoin into Ethereum, Dogecoin, and Zcash ecosystems.

Its findings demonstrate that entropy itself must be treated as a cryptographic primitive. A weak PRNG corrupts the entire security chain from seed generation to transaction authorization.

Scientific Recommendations

The lessons drawn from Btcdetect’s analytical model emphasize rigorous cryptographic engineering principles:

  • Mandatory CSPRNG Use
    Replace all outdated or speed-optimized PRNGs with cryptographically secure generators (e.g., /dev/urandom, OpenSSL RAND_bytes, libsodium’s randombytes()).
  • Entropy Testing Frameworks
    Integrate analysis tools like Btcdetect into development pipelines to automatically identify non-secure entropy paths before deployment.
  • Secure Memory Handling
    Prevent lingering exposure of seeds and salts by employing secure memory clearing and constant-time execution of cryptographic arithmetic.
  • Incident Mitigation
    When weak entropy is discovered, implement urgent migration protocols to reset wallet seeds with CSPRNG-based entropy while monitoring blockchain exposure.

Conclusion

Btcdetect demonstrates, through scientific analysis and practical application, how entropy mismanagement fundamentally undermines the cryptographic guarantees of Bitcoin wallets. The Milk Sad CVE-2023-39910 case illustrates the catastrophic real-world consequences of relying on insecure pseudorandom number generators, leading to mass theft of user assets.

By systematically detecting weak entropy sources, reproducing predictable key generation, and correlating results to blockchain datasets, Btcdetect offers both attackers and defenders a powerful model of entropy exploitation. Its research contributions underscore a critical axiom in cryptocurrency security: a system’s resilience is only as strong as the randomness at its core.

Without continuous auditing, rigorous avoidance of weak PRNGs, and integration of detection frameworks like Btcdetect, the integrity of Bitcoin and other decentralized systems will remain perpetually vulnerable to entropy-driven key recovery attacks.

-4

Research paper: Critical entropy vulnerability in ring signatures and ways to securely eliminate it

Introduction

Ring signatures, used in various cryptocurrency protocols (including the Borromean ring signature implementation in libbitcoin), ensure signer anonymity and protect user privacy. However, improper implementation of random number generation leads to serious cryptographic vulnerabilities: private keys can be recovered, leading to theft of funds. This type of attack was vividly demonstrated in the Milk Sad incident, where a weak generator led to a massive compromise of private keys. pmc.ncbi.nlm.nih+2

The mechanism of vulnerability occurrence

The vulnerability occurs when using a pseudorandom number generator (PRNG) with low entropy or outdated algorithms (such as the Mersenne Twister). In many versions of libbitcoin, a similar bug resulted in the generation of salts ( salts) with predictable values. The attack is implemented as follows: people.csail.mit+2

  • The attacker intercepts (or finds in the blockchain) the public parameters of a transaction with a ring signature: challenge, public key ring, salts.
  • Iterates over possible PRNG seeds (if the entropy is low, for example, only 2^32 options).
  • Finds the seed that reproduces the salts of the current signature.
  • Reproduces the calculations and is able to reveal the private key, since the main equation s=k−e×xs = k — e \times xs=k−e×x allows finding the secret given known s, e, and k.

Thus, weak entropy directly destroys the anonymity and strength of the signature, and also leads to a complete compromise of the private keys of all users whose signatures were generated using this implementation. sciencedirect+1

Safe solution and correct implementation

Choosing the Right Random Number Generator

An absolute requirement is the use of a cryptographically secure pseudorandom number generator (CSPRNG). Such generators include:

  • /dev/urandom or /dev/random on Unix systems
  • Windows CryptGenRandom
  • Libraries libsodium or OpenSSL RAND_bytes

ATTENTION: Standard or fast generators such as mt19937 (Mersenne Twister) are absolutely not suitable!

Example of corrected code (C++)

cpp#include <random>
#include <fstream>
#include <array>

// Получение truly random bytes на платформе Linux:
void secure_random_bytes(uint8_t* buf, size_t len) {
std::ifstream urandom("/dev/urandom", std::ios::in | std::ios::binary);
if (!urandom) throw std::runtime_error("Cannot open /dev/urandom");
urandom.read(reinterpret_cast<char*>(buf), len);
if (urandom.gcount() != static_cast<std::streamsize>(len))
throw std::runtime_error("Could not read enough random bytes");
}

// Генерация криптостойкой соли:
ec_scalar generate_strong_salt() {
std::array<uint8_t, 32> rand_bytes;
secure_random_bytes(rand_bytes.data(), rand_bytes.size());
return ec_scalar(rand_bytes);
}

Replacement for the deprecated salt generation call

Was:

cppec_scalar salt = mt19937_generate();

It became:

cppec_scalar salt = generate_strong_salt();

Additional measures

  • Use memory clearing (memset_s or std::fill) to store secret values.
  • Guarantee constant-time execution of key operations (constant-time arithmetic).
  • Regularly update dependent libraries and audit third-party code.

General recommendations for preventing attacks

For any cryptographic software, independent external entropy and thorough examination of all randomness generation methods during the design and integration phases are vital. Implementing automated tests and quality assurance tools that check both the entropy source and the behavior of the CSPRNG is highly recommended. tsapps.nist+1

Conclusion

Cryptographic systems are only as strong as their weakest element. Implementation errors are not due to theoretical maturity, but to trivial engineering miscalculations. Use only proven and modern cryptographically secure PRNGs, adhere to best practices for clearing secrets from memory, and don’t rely on generation speed—only on its strength. Only then will ring signatures implemented according to the standard protect users, not compromise them.

  • Secure Ring Signature Scheme for Privacy-Preserving Applications, 2023 pmc.ncbi.nlm.nih
  • How to Leak a Secret: Theory and Applications of Ring Signatures, Rivest, Shamir, Tauman Kalai people.csail.mit
  • Quantum-Resistant Ring Signature-Based Schemes, 2025 sciencedirect
  • NIST: Entropy-as-a-Service. Unlocking Full Potential of Secure Crypto tsapps.nist
  • CVE-2023-39910 and Milk Sad crypto-economy+1 attack

Final scientific conclusion

The Milk Sad attack and the CVE-2023-39910 vulnerability clearly demonstrate that a single mistake in the choice of a cryptographic random number generator can undermine the entire security of Bitcoin and violate the fundamental trust in decentralized assets. Weak entropy in seed and private key generation gave attackers a real opportunity to reproduce the keys of millions of users and steal cryptocurrency en masse—both from the Bitcoin network and from other blockchains using vulnerable Libbitcoin wallets .

This isn’t just an engineering oversight, but a tragedy for the ecosystem and users, who lost access to their funds as a result of an exploit that completely destroys the anonymity and sovereignty of personal assets. This incident clearly demonstrates that disregard for basic cryptographic principles instantly turns the most modern protocols into an open door for attackers.

The Milk Sad critical vulnerability is a stark scientific lesson: even a single weak component (for example, the outdated mt19937 PRNG with 32 bits of entropy) can destroy the integrity of Bitcoin wallets, allowing attackers to gain total control over users’ private keys and assets. Without constant auditing, the use of only cryptographically secure random number generation libraries, and prompt incident response, risks in cryptocurrency systems will always be fatal and systemic.

Main sources: