Yesterday at 4:44 am MST, a criminal organization used my Hotmail account to send emails to most (if not every) person in my online Hotmail address book. Sorry to everyone who received spam from me. I’m not sure how they accessed my account, but I have a good guess.
How I think the break-in happened
First, I doubt the criminals got in by breaking into my Hotmail account directly. I use a strong password, so they would unlikely be able to perform a successful dictionary attack. (For more on strong passwords and dictionary attacks, see this Jul 2010 blog entry.)
Second, I doubt they were able to get me to reveal my username and password to them directly by phishing. I’m pretty careful about what sites I register with. I don’t register unless it is required and I check to ensure the sites are legitimate. Most often, they are well-known media companies or data providers.
Instead, I think they obtained a list of email addresses and passwords stolen from a legitimate third-party website that requires registration with an email address and password. Being lazy and human, I use my main Hotmail account and password whenever a site requires both. I have since changed my Hotmail password to be unique. (More later on why that simple act should be enough to prevent a future breach.)
This implies that the compromised third-party site was probably storing my (and all other users) password in human-readable clear text format. Then a malicious user with admin privileges (e.g., an employee at the website who is probably not a member of the criminal group that sent the emails) made a copy of the database containing the list of usernames, email addresses, and passwords for the site. Many of those website’s passwords (like mine) were probably also being used as the password for the user’s email account. The malicious administrator then sold the list to the criminal group.
Storing passwords in a database as clear text is a big security no-no for the reason described above. To prevent a malicious user (or any user) from learning of a password, it should never be stored. Instead, when a user logs in to a website for the first time, the website should apply a cryptographic hashing function on the password to generate a new value, called a hash. This hash value can be stored in a database without worry (or with less worry, at least).
When a user logs into the website again in the future, she enters her username and password as usual. But instead of comparing the clear text password the user entered to a password stored on the server, the website applies the hashing function to the just entered password and compares the result to the hash value stored in a database. If they match, the authentication is complete.
Use of hashes increases security because good hashing functions have two desirable features. First, it is very fast to compute the hash value from the password, so it doesn’t cost much to implement. That is, the user doesn’t experience a delay waiting for the hash to be computed and the website doesn’t have to spend a lot for computing resources generating a hash each time a user logs in.
Second, although the hash is easy to compute, a good hashing function makes it very hard to discover the original password from the hash. Thus, even if someone has a database of usernames and password hashes, she cannot easily recover the passwords. Note that it is possible for two or more passwords to have the same hash value. Thus, related to the second item above, a good hashing function makes it is difficult to guess or calculate other passwords that have the same hash value as a given password.
To increase security even further, the website can add a few (or many) additional characters to the beginning or end of the password before calculating the hash. This salt value if selected randomly by each website and kept secret, will make it harder to recover the password from the hash. (As Homer Simpson might say, “Mmmm, hash with salt or spam. Can’t I have both?”) Even if the salt value and list of users and hash value for every site is revealed, it will ensure that the hash values for a given user will be different for each site, even if she uses the same password at each one.
What the malicious spam creator did
The criminal organization that sent spam from my account used several clever methods to avoid detection of their message by anti-spam software and increase the likelihood a recipient will click on the link in it.
First, all the messages came from me, so the recipients would be more likely to assume the message was legitimate.
Second, rather than sending a single message with all the names from my address book in the To: line, they sent 14 different emails. The names were selected in non-alphabetical blocks, so it looked like I manually selected a distribution of contacts.
Third, the recipient’s name was included in the To: line rather than the Bcc: line to avoid the recipient’s spam filter. Also, by including several names in the To: line, rather than hidden in the Bcc: line, it could potentially reassure a recipient that others she knows are also receiving this email.
Fourth, to reduce the number of characters that a recipient’s spam filter could use to check for patterns that identify spam, each email contained no subject line and the content was just a hyperlink to a php page.
Finally, to reduce the chance that a recipient’s spam filter would recognize the hyperlink as being associated with a malicious website, each email had a different link and the links pointed to a variety of top-level domains including .com, .br, .ca, .de, .it, etc.
One of the spam mails was sent to me, since my name is in my address book. By inspecting the message header I discovered the originating IP address is 126.96.36.199. Looking it up on Whois traces the IP address to UPC Polska Sp. z o.o. in Poland. I assume this is an ISP, not the criminal organization sending the emails.
What I did in response and why it should work
First, I logged into Windows Live and changed my compromised password to another strong password. The new password I created will be used only on sites that I know to use good security practices like Windows Live, Facebook, and Amazon.
Second, I created a new strong password for use on all noncritical websites. (Only one because I’m still lazy and human.) But, if my password for noncritical websites becomes compromised or I accidentally succumb to a phishing ploy, my critical password should not be revealed. In this way, I only have to remember two passwords. My memory should not be overly taxed while I still maintain pretty good security.
Finally, I contacted firstname.lastname@example.org and gave them details of the attack and copies of the emails. I was lucky that the malicious group didn’t change my password, my secret question, and my alternative contact information. If they had done this, I would have no way to maintain control of my account and prevent future breaches. Microsoft would have had to close my account.
Hopefully, these steps are sufficient to stop the problem. I hope I won’t ever again have to apologize to all my contacts for sending them spam.