How Milk Sad Exploited Wallets: Seed To Bitcoin ID Explained

There is a new vulnerability related to the usage of bx seed program which is distributed by libbitcoin [here]. With this, the seed value…

How Milk Sad Exploited Wallets: Seed To Bitcoin ID Explained

There is a new vulnerability related to the usage of bx seed program which is distributed by libbitcoin [here]. With this, the seed value is based on a 32-bit time value. This means that there are only 2³² different seed values that can be created. If someone has used the bx program, they will thus only be able to create 2³² possible Bitcoin addresses. Thus an intruder can run through all the possible seed values and generate the associated private key and Bitcoin address. Once they find these, the intruder would search for the public ID on the Bitcoin ledger and then use the associated private key to transfer funds. It is as simple as that. Now, let’s look at the basic stages.

You can download BX here.

Bitcoin seed to address

With Bitcoin, we create a 256-bit random value for the private key and then convert it to Wallet Interchange Format key (WiF) format, which is a Base-58 form for the random key. This is the format that is stored in the Bitcoin Wallet. For example, a sample private key is:

Private key: 5c04990cf2fb95ca8749d4021100ee98b0744e81a5ec00a2177aeaf4b29c00d3

We then convert this into WiF format (Base-58) to give:

5JWp4FM7sfAAE88DW3yvGF5mQyrsEXeWzXZn79bg61Vg8YMfJjA

This can be stored in a Bitcoin wallet. Next, we can take the private key and a hash value and covert it into a useable Bitcoin address, such as:

1A3CohNBuB6kFAMtp3KFEYwv3Eu58F2HyN

The format of the keys is defined below, where we create a 256-bit private key and convert this to a WiF private key. Next, we generate a 512-bit public key and then take a 160-bit RIPEM-160 hash and convert it to a Bitcoin address:

Converting from seed to address

The major problem with using bx seed is that it takes its seed value from the 32-bit system clock, and so only 2³² seeds will be produced, and thus only 2³² possible Bitcoin addresses. If we use a pure random number, we would have 2²⁵⁶ different seed values, and which would be almost impossible to search through. But, with bx seed, we only have 2³² — which is relatively easy.

We can then easily write a script to go through possible seed values and discover the associated private key, the public key, and the Bitcoin address [here]:

$seed = bx seed 
"Seed: ",$seed

$pri = bx ec-new $seed
" `nEC private key: ",$pri

$mn =bx mnemonic-new $seed
"`nMnemonic: ",$mn


$wif = bx ec-to-wif $pri
" `nWif: ",$wif

$pub = bx ec-to-public $pri
" `nPublic key: ",$pub


$add = bx ec-to-address $pub
" `nBitcoin address: ",$add

A sample run gives:

Seed: 
313dd7017988f73e8869008c2ac28e390094bc85208adde3

EC private key:
7173fc4e3bf366417d163dd936eefc29117fd1cc78a540f0a3c38b19d55f006d

Mnemonic:
couple upgrade scare vessel month palm canvas cactus method figure phone improve announce furnace behind bacon target bonus

Wif:
L12FPHg9UmzEgSJ1uj7pHxzjDQirERTZX3dSFLjVFdV8ovZJUnro

Public key:
021ac378f7738efb40216f014e4eb347ee28823a7e8d8c00624b53c6ce87b0246c

Bitcoin address:
1HXeUdHCk2FnHf9Q3toqoxQKXngJVZACAL

In this case, we start with a seed of “313dd7017988f7 … 094bc85208adde3”, and then can generate a new 256-bit private key of “7173fc4e3bf366 … c38b19d55f006d”. If we need a mnemonic version of the private key to write down, we can see it is “couple upgrade scare vessel month palm canvas cactus method figure phone improve announce furnace behind bacon target bonus”. It can then be converted into a Wif format of “L12FPHg9Um … SFLjVFdV8ovZJUnro”. Next, we generate the public key of “021ac378f7738 … 3c6ce87b0246c”. In this case, we have a compressed public key point, and is the x-axis point, and a “02” if the y-point is even, or a “03” if the point is odd. If we try another key, we get an odd y-axis point:

Public key: 
036ba64d0a2ea6d187da00262b819b44f78ceaae757ef90dead3c141e57e84deb4

And, so, up to this point, we have gathered the seed, the private key, the Wif, and the public key. It is now simple to take the public key and convert it into a Bitcoin ID. In this case, we have an ID of “1HXeUd … KXngJVZACAL”. Once this is discovered, an intruder would then be able to link it with the associated private, and sign-off a transaction.

What not to do

And, so, to repeat. An intruder basically tries each of the 32-bit seed values and then generates all the required keys and maps to a public Bitcoin ID. With this ID, they can then find the address on the Bitcoin ledger and know the associated private key. The weakness is that there are only 4,294,967,296 possible seed values, so it is easy to search through these.

The usage of random seeds (or nonce) values is always a problem in cryptography. For this, the actual method of converting a seed value into a random number is through a deterministic process, and where the same seed will give the same random value output. In this case, the seed is taken from a poorly defined source which only has 32 bits of entropy. In most cases, we would take other sources of randomization from the operation system and aim to generate 256 bits of a seed value. This would mean we would then generate one of 2²⁵⁶ different keys, of which there are:

115792089237316195423570985008687907853269984665640564039457584007913129639936

Conclusions

Coding with cryptography is not for novices and needs to be carefully understood and engineered. Most wallets (hopefully) will use a proper seed value for the creation of the wallet.

Here is the conversion of seed to address:

https://asecuritysite.com/blockchain/bx_keys

Go learn some crypto:

https://asecuritysite.com