The real lesson here is that when you fix your mistakes, go back and fix your mistakes retroactively!
AM used an insecure login token at one point, and 3 years ago they fixed it. They switched from an MD5 of lower(pass)+username to an MD5 of the bcrypted pass+username, which is no longer reversible.
Apparently they never updated all of the previous login tokens though, so anyone who had created an account before the new secure system was put in place still had a vulnerable token stored.
When it comes to security, when you fix something - fix it for everyone people! Even if it's hard.
The good news for these folks is that the passwords revealed appear to be over 3 years old, and we all chang our passwords more often than that, right????
I thought the standard way of migrating your PW hashing function was that you could only do it during a login, because that's the only time you have the PW in plain text. No?
Seems like a 10 minute fix at most to me to rehash the old password once the user was authenticated then put a flag whether they've been 'fixed' or not. After 3 months deactivate the old passwords and sent them an email reset.
Although AM was in the business of essentially blackmailing their customers. So ease of getting back in was of higher priority apparently.
Maybe another lesson is that security by obscurity is never going to work in this age. If someone steals your code, which is incredibly likely with the amount of digital infiltration happening constantly, your security mechanism still better be safe.
How do you verify that? Since bcrypt generates a random salt when you hash a value, if you MD5 the resulting hash, you lose the salt. So, are they storing the bcrypt work factor and salt but doing an MD5 only on the hash portion? Seems like a needless extra step. Storing the bcrypt work factor, salt, and hash should be sufficiently secure.
Updating them retroactively requires those users to log in again, doesn't it? I have had to do a similar update and you can't just update everyone's hashes retroactively. If you've properly hashed it, you need them to actually input their password again.
Hindsight is 20/20. Working on legacy software devs sometimes want to implement the proper solution on paper rather than the best one. Perhaps it was a task that the dev didn't get enough time to write something to update the passwords of a few million users. Perhaps they thought they'd come back to it in a few months and force a reset on users that hadn't switched their password yet. Who knows.
For a non-native speaker, could you please confirm or invalidate my understanding of this interesting text:
1. They attacked some login/api-token unrelated to bcrypt.
2. If I use bcrypt-validate for logins and only temporarily associate rotating, random login/api-tokens with an account, I should not be prone to such attacks.
AM took the unencrypted password, lowercased it, and hashed it into an MD5 token that they then stored - conjecture is that it was used as a login token. That is what the article indicates was cracked, since MD5 is very weak, to get a lowercased password, then tried every permutation of capital letters on the bcrypted passwords, to get the actual passwords out.
To avoid similar issues, if you generate a token, don't use the unencrypted password as part of it. Random tokens are fine.
The title of the article should really be changed to
"How we cracked millions of Ashley Madison passwords by bypassing their strong bcrypt hashes because they thought they were clever" but that's less clickbaity
Also, never ever roll your own encryption - it will be flawed (unless you employ at least 3 crypto experts and get it peer reviewed - and even then it's probably still flawed).
They didn't really roll their own encryption right?
They rolled their own session login stuff, used it for some sort of login-key (what I assume they passed with server sessions). Why they would do that instead of a simple session ID I will probably never know. Maybe they did it so they could have independent backends (instead of having to share session keys across load balanced api servers).
This should be extended to "Never roll your own security", because that's really the crux. As many, many people have pointed out in the past, that's why books like Modern Cryptography exist. In these books, they basically say "hey, use these functions and these parameters, and you probably wont die", but in this case, ALM said "screw those parameters, we're smarter than you!!!!" and rolled their own security. As noted by the article, bad move.
I understand the meme: "Never ever roll your own encryption", but I am stubborn enough to ask: "Why?".
Why use bcrypt over scrypt over pbkdf2? Because crypto experts told you? How could you know it is correct, if you are not able to inspect it? By the amount of people yelling "Use bcrypt"?
I know that in crypto you should expect an attacker to be able to read your source code. If you can keep secrets, while your source is out in the open, then it is good crypto. But does that mean you do not need a script-based salt? An attacker which can get into your database, should be able to get code-read access too right? I don't think so... Databases are leaked on forums without any trace of the source code/app logic. When these people did not roll their own encryption, any attack which is able to beat modern crypto (you will never hear of this, as you are not an expert), could now attack you. They fingerprint the hashes, try to find out which expert roll you used, open their suitcase of crypto breaking tools written by the same expert when she was working for the NSA, under cover of doing a PhD at MIT, and go to town.
Don't listen to me, because I am not an crypto authority, but do roll your own encryption: Give your own twist to it. That is security by obfuscation, and would not put all eggs in the same basket. An attacker has to be able to break your custom scheme now, for every different site/database attacked. It could be simple, it could be near perfect, but it won't be as simple as pressing a button on the "break modern crypto"-toolkits.
If you are one of the few doing this: People will move to less arcane targets in the never-roll-your-own-basket. If you are one of the many doing this, breaking crypto would become an unmanageable field of eggs.
If I was a state actor in charge of keeping secrets and breaking crypto, these two memes: "Never roll your own encryption" and "just use bcrypt" are exactly the memes I would propagate to the tech crowd. Even moreso when you can already break bcrypt (or expect to in 5 years and just store everything that looks encrypted with bcrypt) and want to keep your task manageable.
AM would be harder to crack if they'd ROT-13'd the hashes in the source code.
I recently found out that piwik also uses a login token of the MD5 of the password[0]. So this mistake is still very prevalent.
If you want to provide a one-click automatic login to Piwik for your users, you can use the ‘logme’ mechanism, and pass their login & the md5 string of their password in the URL parameters:
That's actually a whole lot worse than the AM version here. The MD5 hashes themselves are usable as valid password!
And the cracking of the MD5 hash back to original password is fully amenable to rainbow tables. All you need is hashes which you can extract from DB or webserver logs... Or sslstrip'd/HTTP traffic if that's possible.
they stored a static login key generated by md5(strtolower($username).'::'.strtolower($password)); - so they could crack the md5 part easly and bypass the bcrypt encryption
Completely agree, Match.com does the same thing. Not so long ago a user signed up to their site using my email address (never figured out why).
They were able to create an account and subscribe to the site without ever verifying the email, so for a week or so I was getting notifications sent to me without any way to unsubscribe from the email.
Clicking any of the links in the email signed me in as the user and gave me full access to their account and billing information. I ended up going into their account and turning off all email notifications to make the emails stop.
Edit: Just checked my trash folder and an email sent on the 8th of August still contained valid login keys to access the account.
What's the risk of using plaintext passwords if we assume every user is employing long, random, unique passwords? This has always seemed like a non-issue to me because I've been using a password manager for a half-decade.
e: Downvoting questions is mean. FWIW I always use bcrypt.
What's the risk of using plaintext passwords if we assume every user is employing long, random, unique passwords?
This assumption is known to be false. We should not design systems around this assumption. If we do, popping a random startup will give up Gmail accounts, by the thousands to tens of thousands, and since we've settled on email accounts as The One Ring To Your Identity that imperils their brokerages, domain registrars, employers, World of Warcraft characters, physical safety, privacy, cat photos, etc.
Long, random password stored in plaintext: as soon as the user database is compromised, the attacker can log into your account and do whatever they want. This may result in additional exposure of information that wasn't part of the original compromise. The attacker can also impersonate you and cause other kinds of damage.
Long, random password hashed with bcrypt/scrypt/etc: if the user database is compromised, the attacker gets the user database and nothing else.
If I breach your environment and get access to bcrypt hashes, they are useless to me as-is.
If I have enough processing power to brute-force compare them, I can eventually get the original password back, but that isn't a zero-cost effort in terms of time. As soon as you realise you have been breached, I would expect you would have initiated a lockdown of some kind, either preventing access to accounts until the owner can confirm identity, or forcing a password reset for all users.
If you store passwords in plaintext, I can copy the passwords, and impersonate users even while they continue using their accounts, unknown to them.
that is a ridiculous assumption that only leads to really silly "if the 8 planets are aligned just so" kind of justifications that make people feel fine with awful security practices.
Like protecting your business with an industrial grade door locks on a building made of hay. Just a whole lot of cheating going on over there, ouch.
edit: I don't know if this came up before, but based on how they stupidly tried to cache the login session tokens with md5, instead of running through the 12 work factor bcrypt, I can assume that they saw this as a bottleneck.
Instead of dropping the work factor or doing this caching baloney, could a service be made that runs on extravagantly fast hardware, which provides an API for strong, high work factor bcrypt, pbkdf2 based authentication.
I can assume that at around 10 rounds, each attempt takes about 50 - 100 millis
One point is not clear to me: did the crackers know $username's already, or did they perform some kind of dictionary attack? Brute forcing both $username and $password out of millions of hashes seems a bit hard - even considering md5 trivial, not employing an hmac scheme.
[+] [-] djrogers|10 years ago|reply
AM used an insecure login token at one point, and 3 years ago they fixed it. They switched from an MD5 of lower(pass)+username to an MD5 of the bcrypted pass+username, which is no longer reversible.
Apparently they never updated all of the previous login tokens though, so anyone who had created an account before the new secure system was put in place still had a vulnerable token stored.
When it comes to security, when you fix something - fix it for everyone people! Even if it's hard.
The good news for these folks is that the passwords revealed appear to be over 3 years old, and we all chang our passwords more often than that, right????
[+] [-] heynk|10 years ago|reply
[+] [-] iolothebard|10 years ago|reply
Seems like a 10 minute fix at most to me to rehash the old password once the user was authenticated then put a flag whether they've been 'fixed' or not. After 3 months deactivate the old passwords and sent them an email reset.
Although AM was in the business of essentially blackmailing their customers. So ease of getting back in was of higher priority apparently.
[+] [-] aaron695|10 years ago|reply
Lets say they spent the time redoing the passwords, would Ashley Madison be better off right now?
This is a pimple on a elephant. And once you've killed the elephant it's kinda easy to find pimples.
If anything this would have been a distraction from the real issues of however they actually got hacked.
You might see it as a sign that they had bad security, but in hindsight it's all to easy to find signs.
[+] [-] onedev|10 years ago|reply
[+] [-] mizzao|10 years ago|reply
[+] [-] Osiris|10 years ago|reply
How do you verify that? Since bcrypt generates a random salt when you hash a value, if you MD5 the resulting hash, you lose the salt. So, are they storing the bcrypt work factor and salt but doing an MD5 only on the hash portion? Seems like a needless extra step. Storing the bcrypt work factor, salt, and hash should be sufficiently secure.
Unless you meant bcrypt(md5(pass+username)).
[+] [-] artursapek|10 years ago|reply
[+] [-] redml|10 years ago|reply
[+] [-] jand|10 years ago|reply
1. They attacked some login/api-token unrelated to bcrypt.
2. If I use bcrypt-validate for logins and only temporarily associate rotating, random login/api-tokens with an account, I should not be prone to such attacks.
Thank you very much for your help.
[+] [-] lostcolony|10 years ago|reply
AM took the unencrypted password, lowercased it, and hashed it into an MD5 token that they then stored - conjecture is that it was used as a login token. That is what the article indicates was cracked, since MD5 is very weak, to get a lowercased password, then tried every permutation of capital letters on the bcrypted passwords, to get the actual passwords out.
To avoid similar issues, if you generate a token, don't use the unencrypted password as part of it. Random tokens are fine.
[+] [-] snowwolf|10 years ago|reply
Also, never ever roll your own encryption - it will be flawed (unless you employ at least 3 crypto experts and get it peer reviewed - and even then it's probably still flawed).
[+] [-] hardwaresofton|10 years ago|reply
They rolled their own session login stuff, used it for some sort of login-key (what I assume they passed with server sessions). Why they would do that instead of a simple session ID I will probably never know. Maybe they did it so they could have independent backends (instead of having to share session keys across load balanced api servers).
[+] [-] hellbanner|10 years ago|reply
But who makes encryption in the first place -- groups?
[+] [-] jszymborski|10 years ago|reply
They cracked millions of AM passwords. That's not an exaggerating, but the fact of the matter.... since when to titles need to be tl;dr's
[+] [-] rnovak|10 years ago|reply
[+] [-] sctb|10 years ago|reply
[+] [-] compbio|10 years ago|reply
Why use bcrypt over scrypt over pbkdf2? Because crypto experts told you? How could you know it is correct, if you are not able to inspect it? By the amount of people yelling "Use bcrypt"?
I know that in crypto you should expect an attacker to be able to read your source code. If you can keep secrets, while your source is out in the open, then it is good crypto. But does that mean you do not need a script-based salt? An attacker which can get into your database, should be able to get code-read access too right? I don't think so... Databases are leaked on forums without any trace of the source code/app logic. When these people did not roll their own encryption, any attack which is able to beat modern crypto (you will never hear of this, as you are not an expert), could now attack you. They fingerprint the hashes, try to find out which expert roll you used, open their suitcase of crypto breaking tools written by the same expert when she was working for the NSA, under cover of doing a PhD at MIT, and go to town.
Don't listen to me, because I am not an crypto authority, but do roll your own encryption: Give your own twist to it. That is security by obfuscation, and would not put all eggs in the same basket. An attacker has to be able to break your custom scheme now, for every different site/database attacked. It could be simple, it could be near perfect, but it won't be as simple as pressing a button on the "break modern crypto"-toolkits.
If you are one of the few doing this: People will move to less arcane targets in the never-roll-your-own-basket. If you are one of the many doing this, breaking crypto would become an unmanageable field of eggs.
If I was a state actor in charge of keeping secrets and breaking crypto, these two memes: "Never roll your own encryption" and "just use bcrypt" are exactly the memes I would propagate to the tech crowd. Even moreso when you can already break bcrypt (or expect to in 5 years and just store everything that looks encrypted with bcrypt) and want to keep your task manageable.
AM would be harder to crack if they'd ROT-13'd the hashes in the source code.
[+] [-] dsp1234|10 years ago|reply
If you want to provide a one-click automatic login to Piwik for your users, you can use the ‘logme’ mechanism, and pass their login & the md5 string of their password in the URL parameters:
https://stats.example.org/index.php?module=Login&action=logm...
[0] - http://piwik.org/faq/how-to/#faq_30
[+] [-] acveilleux|10 years ago|reply
And the cracking of the MD5 hash back to original password is fully amenable to rainbow tables. All you need is hashes which you can extract from DB or webserver logs... Or sslstrip'd/HTTP traffic if that's possible.
[+] [-] notfoss|10 years ago|reply
[+] [-] nly|10 years ago|reply
Nevermind then, let's go back to berating sysadmins for implementing crypto improperly.
[+] [-] flipp3r|10 years ago|reply
[+] [-] ins0|10 years ago|reply
[+] [-] chinathrow|10 years ago|reply
I know, password reset keys are as bad as login keys, but usually they expire after a certain time frame.
F*ck login keys.
[+] [-] asadhaider|10 years ago|reply
They were able to create an account and subscribe to the site without ever verifying the email, so for a week or so I was getting notifications sent to me without any way to unsubscribe from the email.
Clicking any of the links in the email signed me in as the user and gave me full access to their account and billing information. I ended up going into their account and turning off all email notifications to make the emails stop.
Edit: Just checked my trash folder and an email sent on the 8th of August still contained valid login keys to access the account.
[+] [-] unknown|10 years ago|reply
[deleted]
[+] [-] m0v_eax|10 years ago|reply
[+] [-] nilved|10 years ago|reply
e: Downvoting questions is mean. FWIW I always use bcrypt.
[+] [-] patio11|10 years ago|reply
This assumption is known to be false. We should not design systems around this assumption. If we do, popping a random startup will give up Gmail accounts, by the thousands to tens of thousands, and since we've settled on email accounts as The One Ring To Your Identity that imperils their brokerages, domain registrars, employers, World of Warcraft characters, physical safety, privacy, cat photos, etc.
[+] [-] sillysaurus3|10 years ago|reply
[+] [-] kijin|10 years ago|reply
Long, random password hashed with bcrypt/scrypt/etc: if the user database is compromised, the attacker gets the user database and nothing else.
[+] [-] stephenr|10 years ago|reply
If I have enough processing power to brute-force compare them, I can eventually get the original password back, but that isn't a zero-cost effort in terms of time. As soon as you realise you have been breached, I would expect you would have initiated a lockdown of some kind, either preventing access to accounts until the owner can confirm identity, or forcing a password reset for all users.
If you store passwords in plaintext, I can copy the passwords, and impersonate users even while they continue using their accounts, unknown to them.
[+] [-] lostcolony|10 years ago|reply
[+] [-] valarauca1|10 years ago|reply
[+] [-] throwaway2048|10 years ago|reply
[+] [-] unknown|10 years ago|reply
[deleted]
[+] [-] lostgame|10 years ago|reply
Glad this happened to them. 'bout time Karma came a'knocking.
Oh, p.s. can confirm all women (at least 90%) are bots.
[+] [-] tempVariable|10 years ago|reply
edit: I don't know if this came up before, but based on how they stupidly tried to cache the login session tokens with md5, instead of running through the 12 work factor bcrypt, I can assume that they saw this as a bottleneck.
Instead of dropping the work factor or doing this caching baloney, could a service be made that runs on extravagantly fast hardware, which provides an API for strong, high work factor bcrypt, pbkdf2 based authentication.
I can assume that at around 10 rounds, each attempt takes about 50 - 100 millis
Thoughts ?
[+] [-] grandalf|10 years ago|reply
This means that there was a decision not to force previously created accounts to update their passwords to make their accounts more secure.
Contrast this with the big Evernote vulnerability where all users were required to reset their passwords.
[+] [-] aruggirello|10 years ago|reply
[+] [-] wbhart|10 years ago|reply
[+] [-] sparkystacey|10 years ago|reply
[+] [-] amelius|10 years ago|reply
[+] [-] unknown|10 years ago|reply
[deleted]
[+] [-] anc84|10 years ago|reply