Hacker News new | past | comments | ask | show | jobs | submit login
Milk Sad Disclosure (milksad.info)
136 points by dgrove on Aug 8, 2023 | hide | past | favorite | 125 comments



"On Libbitcoin Explorer 3.x versions, bx seed uses the Mersenne Twister pseudorandom number generator (PRNG) initialized with 32 bits of system time."

That's a hell of an amateur mistake to make. 50/50 odds whether it was incompetence or deliberate fraud. Maybe 80/20; that flaw is so simple anyone can attack it. Which apparently is happening right now. It's much better if your crypto library generates keys only you can hack.


A non-cryptographic PRNG with a 32 bit seed and yet all the other maths/details are correct? I refuse to believe that that is anything but deliberate fraud.


Mersenne Twister is an attractive nuisance. It's complicated and insecure, but a CSPRNG can be done in a few lines of code.

I think people pick it because it has a cool sounding name.


Seeing it declared a WONTFIX to me helps answer which of those it was. If it was fraud, you'd expect a fake apology and a fix at this point.


Why? The regress is infinite, it's zero information. A malicious party can anticipate any public-information rational for dismissing their actions and pretend to be whatever flavor of fool you might accept.

"Now, a clever man would put the poison into his own goblet, because he would know that only a great fool would reach for what he was given. I am not a great fool, so I can clearly not choose the wine in front of you. But you must have known I was not a great fool, you would have counted on it, so I can clearly not choose the wine in front of me. ... Because iocane comes from Australia, as everyone knows, and Australia is entirely peopled with criminals, and criminals are used to having people not trust them, as you are not trusted by me, so I can clearly not choose the wine in front of you."


This quote is from "The Princess Bride" movie. The actor who spoke this was also, IIRC, the Grand Nagus in ST:DS9. Brilliant in both roles.


Wallace Shawn also has some memorable voice roles, such as the T-Rex in Tony Story, and the insurance-company boss in The Incredibles, etc.


Tony Story.. that movie got two thumbs up.

"Tony Story" has you laughing straight out of the gate. Billed as an action-comedy, it's the ultimate clash of the titans between machismo and mirth.

The film follows our hero, Tony, a middle-aged man who wakes up one morning to find himself inexplicably transformed into a small plastic action figure. The plot thickens as he learns he's the star of a beloved, but sadly discontinued, line of 90s toys.

Tony is forced to navigate the wild world of suburban backyards, dodging ferocious pet chihuahuas and the sticky hands of sugar-fueled toddlers. His quest for a return to normality is as hilarious as it is heartwarming.

The brilliant use of slapstick humor, a dash of existential dread, and a sprinkling of well-timed puns are skillfully mixed into a cocktail of laughs. The film's standout moment involves Tony, a malfunctioning Roomba, and a perplexed cat, in a scene that will leave you in stitches.

The voice acting is second to none, with Tony's gruff, action-hero voice (think Clint Eastwood meets Optimus Prime) contrasting hilariously with his miniature plastic form. The supporting cast of misfit toys, including a neurotic yo-yo and a sassy Barbie doll, add to the hilarity.

"Tony Story" is a wild roller coaster of laughter that reminds us all not to take life too seriously. As Tony himself puts it, "I may be small, but my problems sure aren't!" This film truly delivers a unique blend of comedy and action that will leave you chuckling long after the credits roll.


I logged in for the first time in a decade to say that I am sad this movie isn't real.


I am replying to confess that I was wooshed and had sent a note to my partner that we should watch it.


A year from now AI will make it real. Reschedule movie night.


Alas, my new phone doesn't transcribe/edit quite the same as the old one.

Awl sew, thee spiel checquer frowned know tissues bee four eye clacked.


Would a CSPRNG be at all an improvement with only a 32 bit seed? Couldn't you still brute force it?


i think the bigger problem is that the seed is easily guessed or found, so all the output can be regenerated.

so it's not even 32 bits of entropy, it's some tiny fraction of that. (system times for a few years interval)


As discussed elsethread, it used the lower bits of the time value, so while there is is a fraction of the 2^32 space due to precision loss in the OS time calculations, it is not as simple as "between when this software was released and now, in seconds".


That is correct, you still have 2^32 permutations of possible values.


Given it's seeded with system time, depending on the resolution, that may in practice be as low as tens of thousands of possible values (as in time(2) )


2^32 is still incredibly small for crypto and is inexcusable.


A fact which was unambiguously well known to the authors prior to the report: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022...


It was actually an intentional change but a very dumb one because they never warned enough that bx seed should not be used to store money with in the first place.


if it’s something only you can attack then there is no plausible deniability if you become accused as the code contributor


To verify, this is something anyone can attack, as was proven by our brute force lookup service: https://lookup.milksad.info.


Why is it a mistake?


The difference between 32 bits and 64 bits is the amount of people on Earth compared to (EDIT) the amount of grains of sand on Earth. 32 bits is nothing when it comes to entropy, and it can take a security researcher (like us) only $100 to rent a machine to completely brute force it. Nowadays, only values less than 128 or 256 bits (which are exponentially bigger) are seen as appropriate.


You mean time is the only source of entropy there? I don't think number of bits would even matter for it to be bad in such case.


That is correct, time is the only entropy for the command, and the function they use to generate random numbers is also flawed in that it can only produce 2^32 possible outputs.


As the article explains, 32 bits of entropy isn't enough for any cryptographic secret because it can be easily brute-forced.


Also if it's really the date it's nowhere near 32 bits of entropy. I'm guessing you can pretty easily guess to the day when a Bitcoin wallet was created, so that's about 16 bits of entropy. Less if you know the time, possibly 0.


It actually uses the most precise 32 bits of the date, so it's any, like, nanosecond between 0 and some other small amount of seconds. You can't brute force a wallet by knowing approximately when it was made, but you can brute force every mnemonic if you have the time or a bit of cash to throw at a server.

EDIT: It loops around to 0 every 4.something seconds, so it's not like everything after 4 is the same key. It's just a more random distribution than what you may be thinking.


There is often very low entropy in the lowest few bits of system time as well (due to the underlying clock having a different resolution than the system call). Given that every bit you lose halves the time for a brute-force, that's a problem.


Note: "Libbitcoin" here is a company name, and not a name of the core bitcoin library.

Only their products and whoever used them as a 3rd party is affected.


libbitcoin isn't a company. It's an alternative C++ implementation (https://github.com/libbitcoin) to the Bitcoin Core (https://github.com/bitcoin/bitcoin) implementation. Bitcoin Core is the one originally from Satoshi. Libbitcoin came in like 2011 or so iirc and was led by Amir Taaki. Libbitcoin is a lot less popular than Bitcoin Core, as you can see on the github stats.


Last release 2019, master branch marked as non-functional. Doesn't seem to be very active. Their homepage https://libbitcoin.info/ looks polished, but no signs of recent life. This vulnerability seems unmentioned. Well, they claim it's not a vulnerability but a demo implementation that should not be used to store anything of value. But there is no prominent note about that and some users did exactly that.


Here's a thread on how bitcoin core generates entropy https://twitter.com/raw_avocado/status/1445024873382809604


that thread is a little confused:

Particularly, 'The Dynamic and Static events are mixed in(mostly) by using "<<" Left Shift Bits. Because it's a binary operation, every digit is a power of 2, so shifting the bit n positions ends up multiplying by 2^n. This adds further confusion when multiple numbers are used at once.' --- the tweet appears to be confusing C++ stream usage of "<<" with shifting (and as a result makes it sound like the code is doing something idiotic).

Here is how it works: Lots of potential entropy sources including the essential good ones (as well as junk ones like timestamps and user/host info) are fed into a cryptographic hash then strengthened with iterated hashing. The junk sources are included as a hail mary so the user might have some chance to move their funds if they learn about vulnerabilities in their OS/hardware RNGs before an attacker can brute force out the weak sources.


OMG, i'm a bit star struck seeing you reply to this. Been reading you posts on btctalk for years :D

Sorry about that, my bad, I though i understand how that works, when I was exploring this topic i literally asked everyone i know and no one seemed to have any idea, and then when i felt i got a conclusion i was happy i found some explanation.

Anyway that just an excuse at the end of the day.

I have added to the thread a screenshoot of your reply and link to this conversation.

https://twitter.com/raw_avocado/status/1689317198626422784

Thanks for clarifying that.


No need for excuses. The fact that people didn't already get this stuff well enough to correct you on the spot suggests that there is a need for more explanation!


Exactly what I came here to find out, thank you.


Reminds me of attacks people were running on 'brainwallets' a while back - i.e. wallets whose initial key material was just a passphrase you'd remember. The idea was that you could keep the passphrase stored nowhere and not have to worry about it being stolen by... well, any of the 10,000 things out there looking for cryptocurrency keys. Of course, there is no way in hell you can actually make the human brain store enough entropy perfectly, and once people realized that these wallets were crackable, they all got drained pretty quick.

Owning Bitcoin is like paying into an involuntary bug bounty program. Every time someone finds a bug, your life savings get wiped out.


Do you have a reference for large numbers of brain wallets being drained? I believe you are repeating a myth/FUD, but I might be wrong.


https://www.cs.unm.edu/~vasek/papers/vasekfc16.pdf

Also, there was an ethereum wallet with over 40,000 ETH that got drained.


From their conclusion:

> By examining 300 billion candidate passwords, we found 884 brain wallets that were active at some point in time. Unfortunately, we also found that nearly all were drained – usually quickly. While our findings are necessarily incomplete, they certainly suggest that brain wallets are not a secure method for using bitcoin. Perhaps the most surprising result of our analysis is the relative scarcity of brain wallets in use today. This is actually quite encouraging, because it means that fewer users are at risk to these attacks than has previously been supposed.

I don’t think that logic holds up.

It’s pretty much an entire paper of FUD.

And no, anyone with 400,000 ETH who claims they used a brain wallet, and oppsie .. someone stole it. Is having a boating accident, if you know what I mean.


Someone used the passphrase "how much wood could a woodchuck chuck if a woodchuck could chuck wood" to store 250 BTC. I personally drained it by mistake, then tracked down the owner, via the pool he'd mined it from.

I'm a co-author of that paper, we later got funding to do a larger cracking run and found more wallets, and even some that still had balances. See slide 18:

https://rya.nc/files/measuring_the_use_and_abuse_of_brain_wa...

Feeding a massive corpus reddit comments and six years of IRC logs into the cracking tool was particularly interesting.

> And no, anyone with 400,000 ETH who claims they used a brain wallet, and oppsie .. someone stole it. Is having a boating accident, if you know what I mean.

It was about 40,000. The password was "guybrush", and I spoke to the guy who made it. He didn't understand how the tool worked when he made an address. Much later, the Ethereum foundation sent him the ETH. It was gone by the time he went to spend it. Dude put out a press release offering to let whoever did it keep half if they gave back the other half. The ETH hasn't moved since the day it was stolen, almost eight years ago.

I assure you, the guy made a genuine fucky wucky.

If I'd gone blackhat with this research, I could be retired to a volcano lair on a private island by now.

WTF is your angle here?


That sounds exactly like a well acted boating accident.

My angle is that simple brain wallets that use a combination of a memorable phrase with some individual information, like the user’s name, birthdate, address and a 4 digit PIN, used as salt, are then extremely secure. And your paper and the original comment I responded to don’t emphasize that it’s the user’s use of such an systen that makes them vulnerable not the foundation of the technique of brainwallets.

Basically you’re blaming the car for the drivers not understanding how to drive and immediately crashing.


And you're blaming the victim for not understanding things that were never explained to them until after they were already pwned.

The correct way to handle this would be for brainwallet software to generate and provide the user with a high-entropy passphrase rather than asking for the user to provide one. Failing that, it could at least reject very-low-entropy passwords (e.g. impose a minimum 20 character limit).

But even then we're band-aiding the underlying problem, which is that decentralization[0] and finance go together about as well as twizzlers and guacamole. Transaction reversibility is a feature, not a bug, and there's no trustworthy way to implement that sort of thing in a decentralized finance system. Absent a way to dispute fraudulent transactions the only way to avoid your money becoming everyone's money is to overcompensate on preventative measures: i.e. insanely long passphrases stored on hardware keys in lockboxes buried under a garden birdbath.

And sure, yes, we can point and laugh at the credit card industry for treating primary account numbers printed on the front of the card as secure tokens, taking decades to adopt EMV cards in the US, charging horrible swipe and chargeback fees to businesses, and so on. However, there is a reason why, a decade and a half in, people use credit cards and not Bitcoin. Credit cards actually function as a payment mechanism and you are less likely to be defrauded using them.

[0] I additionally dispute the idea that any cryptocurrency system is actually decentralized. The need to agree on the validity and order of transactions necessarily requires one individual or institution actually decide the rules everyone else, with unanimity, agrees upon. Operation of the network is nominally decentralized but the need for security against transaction reordering in the face of no strong identity being available means that practically, it is centralized.

We've seen this with the 'scaling wars' of Bitcoin. Two groups of shadowy puppetmasters - developers and miners - duked it out over absurdly stupid technical arguments regarding how to scale Bitcoin.


> don’t emphasize that it’s the user’s use of such an systen that makes them vulnerable not the foundation of the technique of brainwallets.

That's because it is the foundation of the technique that makes them vulnerable. They are an "attractive nuisance". A system must be evaluated based on "typical use", not "perfect use".

You come across as a social Darwinist who would be happy for all the warning labels to be removed from everything and all safety regulations repealed. The world you advocate for would be an awful dystopia. You have nothing to say I haven't heard before.


> WTF is your angle here?

I think this more applied to you. You actually invested time to write a paper about brainwallets because some people don’t understand or know how to use them properly. The paper is not logical, if it was then a small POC I know about is all of them, which obviously it isn’t, you can’t find serious people’s brainwallets, they would be salted in a way that it’s hopeless to crack.

You claim brainwallets are fundamentally unsafe, which honestly is total nonsense if you understand them and how they work.

I’m gonna guess you’re a ban Bitcoin type because it’s… wrong or whatever.


I'm going to go play chess with a pigeon, it seems like a better use of my time.


It’s not not a myth. Not even really lost to time (or a simple Google search). E.g

https://www.reddit.com/r/Bitcoin/comments/1zti1p/17956_hacke...

https://www.wired.com/2015/07/brainflayer-password-cracker-s...


FUD!! and you know it if you actually took time to read the post.

> I could find the passwords for 17.956 of the addresses. * Only 2 addresses of the hacked brainwallets are currently not empty, and the total money that I could actually steal is 0.00115215 BTC.

> Somebody seems to have systematically flooded the blockchain with transaction to brainwallets. E.g. this transaction: https://blockchain.info/tx/ba421da33e5f85669d9312b804e22fa4c... It seems that each target address is actually a brainwallet and alphabetically ordered. The passwords for the first 3 addresses are Hollister, hollowing,

Nobody’s real brain wallets are being hacked! It’s just left over traces from someone running aome testing in early days of bitcoin.

This one says 17K wallets … oppsie all empty and obviously programmatically generated! i.e not used for real.

The other paper found 800!! supposedly… all empty.

A well designed brainwallet is perfectly fine and safe, just don’t use a sequential phrase from known sources and modify the words you do. Obviously.


> Nobody’s real brain wallets are being hacked! It’s just left over traces from someone running aome testing in early days of bitcoin.

I've talked to a LOT of real people who's real brainwallets were hacked. Certainly there is also some 'testing' but that doesn't change the fact that there have been real and substantial losses.

Brainwallets are very dangerous.

A brainwallet is the same thing as using a user provided password to secure a high value system that has an unsalted and public password hash database. This is a negligent practice. In the corporate world it wouldn't be shocking to learn that a security engineer was instantly fired for implementing such a practice.

Good security advice results in practical security even if the user uses the system less than perfectly. Attacker-originated security "advice" provides security only under unrealistic perfect use. Telling people to use brainwallets is like recommending one-time-pad encryption. In practice the security will be fragile if not outright broken though in theory with it may go okay sometimes.

Correct usage would require secure mechanically generated uniformly random seed phrases with a hundred plus bits of entropy. That isn't generally what people do in practice and the few who have often have issues with retention of the string being inevitably very poor, causing them to lose the funds by forgetting (esp after getting a fever). (Of course, if they're going to write it down and they didn't generate it themselves then it's not something anyone should be calling a brainwallet anymore.)


> A well designed brainwallet is perfectly fine and safe

Especially if the brainwallet adds a salt, which is maybe the problem that the previous poster was referring to. Brainwallets that don't add a salt are definitely a risk.


Did a brainwallet write this?


What would change your view about that?

This was one of the best uses of GPUs 10 years ago, people still have those instances running just in case people use “obscure” common phrases from books again instead of mnemonics

Its more like anyone that thought they were clever got swept. There arent statistics, just threads on bitcointalk and reddit


If you used common phrases from books you definitely aren’t clever and deserve to have your funds swept.


The person who originated the practice and created the first "brainwallet" site did exactly what you're doing: insisted that it was secure, and insisted that people who lost their funds deserved it. Are you also doing what he did? stealing the funds of the deserving victims yourself?

Eventually taking the weak brainwallets he talked people into creating wasn't enough: He lost his bitcoin (I think via gambling but maybe an exchange hack), whined he was broke for a while, and whined that not many people were making hackable brainwallets, then added a more explicit vulnerability to the site. He vanished after it was caught.


You only need a phrase of twelve words from a 2048 word dictionary to have 128 bits of entropy. Twelve words is up to "Thy kingdom" in the Lord's Prayer, so certainly people are able to memorize twelve word phrases or even 24 word phrases without too much trouble.

And English is a lot more than 2048 words - so you could probably use a shorter phrase and still be fine.


The thing about the Lord's Prayer doesn't really follow. If you use a grammatically correct and semantically commonplace 12 word sequence like that, you surely don't have 128 bits of entropy. But the ease of memorization comes almost entirely from those attributes!

To get 128 bits of entropy with words, you need to pick about thirteen out of a million words--which is on the order of all the words in the English language--and give all of them equal probability. The sequence needs to be fully random as well. What you end up with will surely be easier to memorize than a UUID, but substantially more difficult than the start of the Lord's Prayer.

EDIT: Math is wrong, I was thinking 10 bits per million instead of 20. So 6-7 words out of a million (whole language) or 13 words out of a thousand (very limited subset of the language). Point about random selection still stands, but it's certainly easier than 13 very uncommon words. Still much harder than a realistic sentence of that length, though.


But the phrases are random, so unlike poems or prayers they are difficult to memorize.


Create your own haiku, never publish it. What are the odds of someone creating exactly the same haiku?


Probably much higher than you suspect. Making password haikus is an obvious idea which has been suggested many times before.

I'm sure that even with a great statistical model of password haikus (say an LLM) yours would still be one in a billion which still seems unlikely, but a cracking cluster can try billions per second.

In these cases it's very easy to have security that depends on the odds that a powerful attacker just hasn't gotten around to seriously trying the broad class of predictable generation schemes you've used.


For reference, normal English writing has about 1 bit of entropy per character.


Unfortunately there is good reason to think that memorability and low entropy (against a sufficiently advanced sequence generator) are highly related.


> Of course, there is no way in hell you can actually make the human brain store enough entropy perfectly

Sure there is. Have horse batteries taught us nothing?

https://xkcd.com/936/

Don't confuse key length with entropy. A properly-scaled PBKDF remains secure with as little as 48 bits or so. Needless to say, though, a 32 bit time value is hardly a properly designed key derivation input.


Diceware has been round for ages to do this (2 decades+?) https://theworld.com/~reinhold/diceware.html

I made a little android app using it to generate passphrases, each word gives 13 bits. So 6 words is plenty for a disk encryption password at boot.

https://github.com/mkj/dice


This xkcd comic has been instrumental to me.

I wrote a command-line utility a couple of years ago that I use myself regularly to generate secure and memorable passwords

https://github.com/ctsrc/Pgen

With this tool you can also see how many bits of entropy the passphrase generation settings you are using will result in.

For example, generating a 5 word passphrase using the long wordlist

    pgen -l -n 5
will yield a passphrase like:

    joyous embolism outsider evasion mashed
And when we ask the tool for the entropy with these settings

    pgen -l -n 5 -e
it will tell us:

    Current settings will create passphrases with 64.62 bits of entropy.
And hey, if you have reason to not trust the randomness capabilities of the program or your computer guess what :)

My program supports the use of physical dice to generate your password.

Have a look, try it out yourselves :D

https://github.com/ctsrc/Pgen


That’s excellent! I had the same idea I completed a few weeks ago in python trying to write it with the standard library and have it be easily auditable. You can check it out here if you want:

https://github.com/avnigo/nodice-cli


It looks neat, I'll pass this along to the team and take a deeper look at it later.


Also generating a BIP39 seed from https://iancoleman.io/bip39/ and using as many words from the output as you want for your purposes.


dibs on joyous embolism outsider evasion mashed. this is my new password


It’s better than your last one, hunter2


I use these passwords all the time. However, you should keep in mind the text in the comic:

> (Plausible attack on a weak remote web service. Yes, cracking a stolen hash is faster, but it's not what the average user should worry about.)

This is almost a sound assumption for most web services[1]. However, this is Bitcoin. The only thing the attacker has is your hash. And you're using a payments system which economically incentivizes the creation of ever-larger systems for brute-forcing hashes. The network's hash power as a whole is estimated to be around 331 exahashes per second, so 68 bits of entropy would take one second to crack.

Correct horse battery staple would be cracked in fractions of a second by the full network. Eight common words would take 12 days. If we go further to 12 words, then we do get reasonable levels of security, but I'm assuming hashrates stay constant forever which is a bad assumption. And 12 word passphrases will already be about as much of a pain to remember as the 'password policy compliant' passwords xkcd was railing against.

[1] The most likely attack is actually credential-stuffing, not brute-force. xkcd is assuming you already use separate passwords.

Related: The password hashes for the xkcd forums actually did leak and it turned out most people's passwords were "correct horse battery staple".

No, not four random words. I mean the literal text "correct horse battery staple".


> However, this is Bitcoin. The only thing the attacker has is your hash.

You're doing exactly the "confusing entropy with key length" thing I was mentioning above.

That's not the situation at hand. The entropy in question is the private key generation, it's not related to any SHA256 hash in the protocol. But you're right, if you were trying to generate symmetric keys using a 48 bit password expanded using SHA256 as a PBKDF that would be a disaster. But no software is doing that[1]. All you need to do is pull a key derivation function off the shelf and use it with recommended parameters. Really these have been stable, even bcrypt is still very solid.

Your question was essentially "can a human being remember enough entropy to secure a bitcoin wallet". And the answer is absolutely yes.

[1] What it was doing was even worse, of course.


>Related: The password hashes for the xkcd forums actually did leak and it turned out most people's passwords were "correct horse battery staple".

Not sure I would read too much into that. I am sure many people value the community there, but it it ultimately, a web forum around a web comic.


Encrypting your hard drive is like paying into an involuntary bug bounty program. Every time someone finds a bug, your nudes get posted to the internet.


Your last sentence should be a t-shirt.


Worth noting: libbitcoin is an obscure project with an impressive name.

In that it's not used by bitcoind or any wallets I know of: it's mainly of interest here because the book Mastering Bitcoin used it for examples.


It is also of interest because at least ~$1m of funds were stolen from thousands of wallets made by people that wanted a simple and seemingly reputable CLI tool to generate a mnemonic and derive addresses for various coins.


Sigh. I did not know that, thanks :(


Now I'm busy making my own CLI for that, after this mess.


It's far from the first time that people have sought to make themselves extra secure and as a result found themselves using obscure software which was inadequately reviewed and flawed or even outright backdoored and as a result received almost no security at all.


there are a couple crypto programming youtube videos like that, remix IDE put up a warning at one point

its an interesting attack vector

provide educational resources with compromised examples

wait for dev or their users to deposit funds in the copy and pasted contract or dependency

long game, been wondering how well that worked


> https://blog.ledger.com/Funds-of-every-wallet-created-with-t...

This "Milk Sad" was apparently discovered by the guys at Ledger (they make a hardware wallet but which can also be used as a U2F device for, say, SSH logins).

These guys are good. Their CTO (or ex-CTO ?) was part of the original FIDO alliance that came up with the U2F spec.


We found the flaw in bx before ever knowing the Trustwallet flaw existed. We are not the Ledger team but their writeup on their very similar finding was fantastic so we reference it prominently.


The spiciest bit:

> During our accelerated coordinated disclosure to the Libbitcoin team, the Libbitcoin team quickly disputed the relevancy of our findings and the CVE assignment. By our understanding, they consider bx seed a command that should never be used productively by any bx user since it is sufficiently documented as unsuited for safe wallet generation.

> We do not agree with this assessment.

https://milksad.info/disclosure.html#libbitcoin-vendor-respo...


Look at the big warning there: https://github.com/libbitcoin/libbitcoin-explorer/wiki/bx-se...

He's right.


No, he's not. Why have it?

This isn't a general purpose programming language, a pile of ore from which you might conceivably construct a footgun. It's a toolkit specifically designed for financial applications with a "leak your financial details" tool built in.

Sure, it's AGPL, they're not literally liable, but it's not great.


I would call your attention to the several places it was demonstrated for use by libbitcoin team members -without- a warning, such as in their contributed examples in Mastering Bitcoin. We cover a few of such examples in the writeup.

Also note that the tool bothers to refuse to use a flag to specify 32 bit seeds, due to their known risks, but then proceeds to give you only 32 bits of entropy anyway even if you ask for 256.


Seems a bit overkill with a brand + domain name for every new vulnerability.

Don't get me wrong, it's a nice find and all, but I'm really distracted by all the fluff.


That's on you, though. The name doesn't cost anything, but it does make the vulnerability easier to talk about.


I suspect the domain literally cost money...


It cost me $4 to help get the word out on a bug that is being actively exploited right now, stealing valuable property. I am good with that.


Where do you buy a $4 domain?


based on the `whois milksad.info` Domain registrar is Namecheap :shrug:


Porkbun? I buy under a dollar domains from them frequently


Eh, let the security consultants have their moment. Also it's a great name. "Running bx seed on 3.x versions with a system time of 0.0 always generates the following secret: milk sad wage cup reward..."


we had so much fun trying to figure out the icon!


Milk sad is ok.

“Wage cup reward” is almost poetry …


Was the code seeding by seconds since epoch, or nanoseconds since epoch truncated to 32 bits? Broken either way.

https://github.com/libbitcoin/libbitcoin-system/blob/a1b777f...

        const auto now = high_resolution_clock::now();
        return static_cast<uint32_t>(now.time_since_epoch().count());


Nanoseconds since epoch, which means eventually it does loop around, so at the very least it's not possible to generate a specific wallet by knowing when it was first used.


A quick search says it's actually ticks, which is OS and machine dependent (kernel tunable). Nanosecond resolution is not enough for a seed if it's a real datetime, so the 32-bit truncation is a separate problem.


Weird. I've been assured, repeatedly, that time seeded PRNGs are never used for crypto and it's not an issue worth addressing.


There is no single codebase for "crypto," so that would be an extraordinary assurance for someone to make. Even Bitcoin has many different compatible implementations of varying quality.


As long as people can write code, bugs will exist.


Some extra relevant links:

https://github.com/libbitcoin/libbitcoin-system/pull/559

The pull request adding the vulnerability, the lack of review or collaboration is worth noticing. The prior code was already dubious in that AFAIK std::random_device library doesn't promise that the randomness is suitable for cryptography. I believe on common systems where this code was run the old code was not likely to be exploitable, but I wouldn't bet my money on it.

https://twitter.com/evoskuil/status/1688657656620167169

Developer commentary on this issue. I can't figure out what "long-documented intended usage" a seed command that mandates 128-bits of output but never has more than 32-bits of entropy would have.

https://archive.is/A7Jn6

The documentation the tweet references. I don't know how the 'Pseudorandom seeding' warning there would be distinguishable from warnings against CSPRNGs in favor of dice rolls or whatever, perhaps this is an example of the harm that chicken-little crying about CSPRNGS causes. Nor can I figure out for whose convenience this function would serve except attackers. In any case, this is the only place I found any kind of warning and the warning postdates the mastering bitcoin usage (as well as the change that made the command unconditionally unsafe).

https://archive.is/HDe8h

Current libbitcoin-explorer instructions telling users to use the seed command to generate private keys.

https://archive.is/fhm5J#selection-12915.2-12915.10

Current libbitcoin-explorer instructions telling users to use the seed command to generate BIP39 seeds (also private keys).

https://archive.is/PWLKJ

Current libbitcoin-explorer documentation on randomness noting that bx seed is the ONLY source of randomness available to users in the package, and that all other commands that need randomness require the user to provide it. It also notes that 'bx seed' will not function if less than 128-bits are requested.

The private key and bip39 seed usage (above) sure appears to be the "intended usage" in their documentation, but the "bx seed" function as currently implemented (since 2016) is unambiguously not fit for those purpose.


https://twitter.com/evoskuil/status/1689128996120776704

No intent to change. The tweet confused about thinking this was some third party wallet using libbitcoin.

Instead, from the writeup it appears that at least some of the users followed the above BIP39 seed generation instructions to generate a seed that they used with other assorted BIP39 compatible wallets such as typical hardware wallets.



> Current libbitcoin-explorer instructions telling users to use the seed command to generate private keys.

.. and receive bitcoin at them.

Wow brutal.


I love how many references to Stack Overflow that PR added to the codebase. Always a good sign.


LOL! The second S.O. link actually goes to show how broken C++ is: https://stackoverflow.com/a/18298965/544947


That's really a C related comment and all it doing is subbing in implementation specific pre-standard versions for the benefit of compatibility with compilers prior to the introduction of the feature in the C11 standard.

The standard calls it "_Thread_local", pre-standard MSVC/icc(win)/borland called it __declspec(thread), and pre-standard GCC/icc(linux)/clang/sun called it __thread.

Code would also be free to just use _Thread_local and say that a C11 conforming compiler is required.


I wonder whether they modified brainflayer for brute forcing this, or if they wrote something from scratch.


We used the broken algorithm from `bx` in a custom Rust program to brute force this.


What sort of rate did you get for computing the hashed public keys?


I was not involved in that specific aspect, so I can't provide accurate information. We may release more information later in the future.


2^32 search space for each set? That seems to imply a little under 2,000 keys per second?


My numbers are very rough estimates and not good enough to do work on. More accurate information may be made public later.


I would be interested to see performance stats - I would expect an optimized attack (batch point inversion, large precomputed table to speed up multiplication, not bothering to try to be constant time) to run well over an order of magnitude faster than that.

Not that it's particularly worth bothering if you have an 80 core machine and only 13 billion keys to check.


And indeed, we did have an 80 core machine. <1 day after some code optimization passes.


lol just straight up not using a cryptographically secure source of randomness. that's literally the first thing you do when you want secure cryptography. idiots


Are any of the following two things true:

Multi signature addresses mitigate this attack vector?

With the “taproot+schnoor” upgrade last year, it is impossible to tell if funds are stored in a single signature vs multi signature address?


If all the keys were generated with bad entropy, more of them is only buying you some obfuscation.


Generate keys with different apps or methods, for more peace of mind

That was one of the goals of initial multisignature technology in bitcoin, it was about if one of your devices got compromised you could have 2 factor and not approve the transaction. People werent thinking about if your private key generation was compromised, but it works here too


[flagged]


One perspective is that it mimics society more evenly: if you’re one step ahead you also get to steal everyone else’s. Being a perpetual bug bounty is utility.

A more collaborative perspective is that the adaptable nature of the protocol adds to the confidence in it. Only new addresses created after an update of one program were affected. And now it is fixed already. Bitcoin use has pointed out flaws in other encryption methods before which quickly got fixed solely because there was a financial motive to fix it suddenly.

The primary thing that you missed is that the upgrade last year was not “snakeoil to mitigate this problem”, its just also an additional way to mitigate this potential problem, its just happens to also provide an improvement on 10 year old multisignature technology

But an overlapping analogy to your primary observation would be how insecure accepting credits over the internet was in 1995. That problem actually never went away, despite layers and layers of patches and payment processors and security standards, SSL, TLS, PCI Compliance v1 v2.. venture backed competitor payment processors with fraud detection

and yet nobody threw their hands up and said “we’re going to stop trying now”


[flagged]


That’s not what I wrote, I wrote there were some similarities and listed them, and you presented different differences and discredited those differences as an attempt to discredit me and the entire concept

That is called a strawman argument, do better.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: