September 23, 2009

Worse than Nothing

Want to get phished? Don't worry, it won't hurt.

If you have an account with Vanguard, the investment firm, you can experience it for yourself right here (works on IE7, IE8, or FF3). If not, you can watch a quick screencast of me phishing myself. Note that this is clearly not the Vanguard site, and yet after I enter my username, I'm shown my personal image (mine's a canoe! what's yours?). I didn't answer any security questions, and yet that's my personal image that only my bank and I are supposed to know. And here it is on some scammer's site. That's the unique part of my attack, and the most dangerous.

By the way, that screen at the end is where the scammer has just obtained your password and is happily emptying your bank account (since I'm nice, I just display a hash and don't save it).

I don't mean to pick on Vanguard, I just happened to have an account with them. A similar attack should be quite possible on Bank of America, HSA Bank, or anyone else who uses the SiteKey system. SiteKey is a scheme banks came up with in response to the large and largely-intractable problem posed by phishing. It's sometimes labeled as a "multi-factor authentication" system, but I think that's incorrect - it's more of a "mutual authentication" system. The site proves that they are legitimate by showing you a picture that you selected when you sign up. Since no one else could know what picture you have set, this proves that the site is who you think it is. At least, that's the theory.

My attack is simple. The first page is just a static page that looks exactly like Vanguard's home page - standard phishing fare. When you submit the form with your username, I build a page with an iframe pointing to the Vanguard site, passing it the username. As long as you've logged in from this computer before, the Vanguard site happily shows your personal image. Then I create a form outside of the iframe with a password field and a submit button, and float those elements over the iframe. So while you're seeing the Vanguard site in the background, you're entering your password into a form I control, and the submit button you click submits to my page. And just like that, I have your password.

I have your password. I did this with a freakin' Bachelor of Arts degree. It took me about three hours of messing around to get the basics set up, and another few hours to spit and polish. It's a couple of dumb HTML pages with a few snippets of PHP, and a pinch of Javascript thrown in. There is nothing sophisticated here. I don't think this even qualifies as a "hack." I think you should be concerned. This attack has been possible as long as SiteKey has been in existence, and I see no reason why I would be the only person to think this up. In all likelihood, some smart phisher out there is already doing this.

I learned retroactively that this technique is called UI Redressing, more commonly referred to as Clickjacking. It's behind a number of attacks, of which perhaps the most publicly visible (although not the most dangerous) was the Twitter "Don't Click" infection. Even worse, since my attack requires no clicking on the actual hidden elements, even NoScript's vaunted ClearClick technology doesn't detect it (NoScript does offer an opt-in to disable iframe content, which sounds like it should stop the attack, but it didn't work for me).

SiteKey was weak to begin with. It's bad enough that a vast majority of site users don't notice if the image is missing. And a weaker man-in-the-middle attack that involved asking security questions was demonstrated 3 years ago[pdf]. But this is worse. A malicious site that shows you your own handpicked image will lull you into a false sense of security. Who would think twice about providing personal information when that mountain stream or étouffée or whatever you picked is staring you right in the face? The banks have worked hard to train users to look for that image, and that very training can be turned against them to make phishing attacks even more successful than before. SiteKey is not just useless - it's worse than nothing at all.

I have been in contact with RSA Security, the vendors of SiteKey, about this attack. To their credit, they were very professional about the whole thing. They treated the matter seriously (I was surprised to get a response at all), and did not try to bullshit or bully me. So they get points for understanding how to make the vulnerability reporting process a productive one. They told me they have notified their clients about the problem and suggested corrective action. I imagine this action will consist of frame-busting Javascript and a proprietary IE8 header. I can only speculate because as of this posting, neither Vanguard nor HSA Bank have done anything to prevent the attack, even though it has been two months since I reported it. These changes will help, but the headers are opt-in and only work on newer browsers, and the Javascript isn't necessarily immune to circumvention. Besides, recall what I said about my qualifications as a security researcher. If I came up with this in a few hours of spare time, don't try to tell me there aren't similar attacks that could be discovered by a motivated person - say, someone who makes a living managing a phishing operation.

There's another reason I think SiteKey is worse than nothing. It's not just users who get a false sense of security from it - banks are biting on these supposed panaceas instead of facing up to the very difficult problem of performing real security. It's all too easy for companies to set arcane password rules and shell out money for "solutions" like SiteKey, and convince themselves that they've tried hard enough. Wrong. SiteKey is like a Mickey Mouse band aid on the wrong knee. Maybe it gets the three year old to stop crying, but it's not actually doing any good.

Epilogue

I know, I know, I'm such a negative person. Always bringing other people down. Complaining about what exists without offering any suggestions of my own. What would I propose to guard against phishing? Huh, tough guy?

I have to be honest - I don't see a silver bullet. Phishing is a serious threat, and one that preys on our inescapably human failings - inattention, belief that our perceptions are accurate, and willingness to adapt our actions to what we are presented with. I don't see it going anywhere any time soon. However, I think the Firefox address bar is a great start:
Firefox address bar
If we have to train users to look for something, it should be this. Benefits:
  • It's client-side. No man-in-the-middle. No UI redressing. Short of a serious Firefox exploit or SSL vulnerability, there's no faking this part of the address bar.
  • It comes (I assume) from the SSL certificate, which is a pretty okay security measure, and one that any respectable site dealing with sensitive information already uses.
  • It's friendly and distinctive - it's big and green and it tells you the name of the company.
  • It's right next to the address bar, which encourages one to also check the URL. This is the original best security measure, and one that eBay and others have been advocating for years. I should point out that the pretty little Locationbar² plugin is helping here as well by highlighting the domain name so it stands out against the rest of the URL.
Still, this only works if you think to look. The danger of phishing is that you get caught at the end of a long day, or when you're in a hurry, or when fucking PayPal actually has deactivated your account three times in the past and you're so annoyed by the prospect of a fourth that you get careless and don't check.

I've got another suggestion, but this one is a lot further from reality. This is what I think could be, if we would spend less time on fake security and more time on real security.

Imagine, if you will, a world where PGP is commonplace. That's right, I'm evangelizing again. Imagine every email you receive is signed, and you have an extensive trust network. When you open an account at a new bank, the rep hands you a piece of paper with instructions on downloading the bank's public key and a fingerprint to verify it. Because PGP is so common, your email client actually throws up a big red warning saying "Hey! This signature is untrusted!" whenever you get email from someone whose key you haven't imported. Suddenly you have a proactive warning on every phishing email that comes through. Nobody is going to click through a message from their bank that is labeled as "untrusted." You could teach your grandparents that.

Is this a pipe dream? For now, yeah. But it's a good one - it's a world where email phishing is essentially solved.

Until then, keep checking your address bar.

Update (12/03/09): Looks like at some point in the past few months, Vanguard updated their site with some frame-busting Javascript, and now hides the pages if Javascript is disabled (bad news for accessibility, but arguably more secure). However, let me reiterate: the fact that they have stuck their finger in this leak doesn't mean there aren't other holes in the dike.

Another update: I sent this article to Jim Youll, the author of the original paper on SiteKey vulnerabilities. He emailed me back, and in his response was a remark that stuck with me: "they always say that the undisclosed back-end systems are the fail-safe for the front-end attacks. I don't think they're lying." At some point, it hit me: what if SiteKey is nothing more than security theater? Maybe they do know that it's useless. Maybe they don't expect it to stop anything. Maybe whatever fee they're shelling out isn't coming from the security budget, but from the marketing budget. If this is the case, I just hope the marketing spiel isn't working on the people who need to be doing the real security.

August 7, 2009

Making Chroma-Hash Less Leaky

Prologue

Recently, Jakob Nielsen yelled at everyone that password masking is a usability problem. When that man yells, people listen, and so were planted the seeds for some interesting experiments in providing password hints. The sexiest of these so far is Mattt Thompson's Chroma-Hash.

Some valid security concerns were raised over this widget. Mattt has solved several of these already with his recent improvements. I'd like to examine one of the remaining issues and suggest a solution. You can view my fork on Github for the source code.

The problem

The scenario goes something like this: a user takes and shares a screenshot or screencast of their login screen with password typed in. Someone malicious views this and can garner information about the hashed password from the color bars. From here, I'm going to assume that you understand the basics of how MD5 is a one-way function and why that's important.
Chroma-Hash password box
In the standard operating mode, Chroma-Hash is pulling number values right from the MD5 hash. We can get the colors with an eyedropper, and look - they match up (in reverse order) to the first part of the hash of the salted password.

$ echo -n "hooray12:7be82b35cb0199120eea35a4507c9acf" | md5sum
4ea16c514a6697bce642ee2250aa92f6 -

If we were using five color bars, we would have disclosed almost the whole hash.

People keep bringing up the fact that MD5 is not considered a secure hash function any more. These concerns are misplaced. MD5 is considered broken because it's too easy to find collisions - things that hash to the same MD5 sum. This is useful indeed if you are wanting to forge a digitally signed certificate or tamper with transferred data. But unless the authentication server is using the exact same salt and hash algorithm as Chroma-Hash, creating a collision with someone's color bar hash is useless - you'll be able to get the same colors, but you won't be able to log in.

The real concern here is this: we've allowed an attacker to move the computational load onto their own hardware. When you control the password oracle, it's easy to limit the rate at which login attempts may be made. This makes a brute force attack or even a dictionary attack infeasible. The attacker can't try passwords fast enough to have a reasonable chance of guessing the right one within years. But when an attacker has a hashed result of your password, they can run a dictionary attack as fast as their hardware allows, and a matching MD5 from a dictionary attack is likely to be the right password, because let's face it, people in general don't choose secure passwords.

An aside: at the leading edge of server-side security, the equivalent threat of a stolen database is dealt with by bcrypt, a hashing scheme that can be tuned to be computationally intensive. So maybe the password check takes a tenth of a second instead of a thousandth - it's no big deal in the course of regular business, but it will significantly slow down an attacker trying to test a lot of passwords against stolen hashes. This strikes me as impractical for our purposes, and not only because we would need to implement bcrypt in Javascript. Tune it too strong, and a user running on slow hardware could suffer a bad performance hit when trying to type in their password. Tune it too weak, and an attacker with a couple dedicated cores could crank through at a fair clip.

My solution

In this case, I say collisions are actually our friends. If we can limit the information available to an attacker, we can leave them with a very large set of possible matches that they can only check by attempting to log in to the server. The point here is to make them verify against the server, rather than doing it at their own pace.

This is where another convenient fact comes into play. In his blog entry, Mattt points out that over-the-shoulder attacks won't be effective against Chroma-Hash.
As a color expressed in Hex, there are 16,777,215 possible colors for each bar. Eye-balling it wouldn’t be enough to get an exact color value—the difference between #952A08 and #952A09 is nearly imperceptible...
Those millions of possible colors come from 24 bits used to represent each color, which in turn is 24 bits of our hash leaked for every color bar. If we don't leak the information in some of those bits, our attacker cannot be as precise about identifying matches. And since humans cannot really differentiate all those colors anyways, we're losing almost nothing by eliminating some of the possibilities.

The best way to do this is to redact the low-order bits, so that we keep the entire color range and lose only the fine distinctions between shades. You can think of this like counting in multiples. Instead of every number being an option, we round to the nearest even number, or multiple of 16, or whatever we like. The more we round, the more information we can withhold from an attacker.

Let's see it in action.
Chroma-Hash password box
In this version, rgbStepSize is 2. You can see that the color values are very close to the original, but each 2-character hex number is even (0x96 = 150, 0xbc = 188, 0xe6 = 230, and so on). And since we're rounding, the attacker cannot know if the original hash contained "96" or "97", "bc" or "bd", etc.
Chroma-Hash password box
In this one rgbStepSize is 16. Looking at the color values, you can see that the second character of each pair is 0. We've eliminated half of the bits leaked by Chroma-Hash, and the colors are still remarkably close to the exact values as far as the human eye is concerned. In fact, quick experimentation shows that we can go with a step size of 64 or so without affecting user experience too drastically.

Did it work?

Now, how much does this help us? I'm a little out of my depth here, so I can only provide some back-of-the-napkin estimates. The small version of Openwall's word lists, which consists of various words and word combinations, has about 300,000 entries. For a six-digit password consisting of lowercase letters and numbers, there are about 2 billion total possibilities. A 64 bit hash can have about 18 quintillion different values, so if a dictionary attack finds a match against all bits, it's almost certainly the true password.

Let's say we're showing three color bars with a step size of 64. This means that 6 of each 24 bits per color is leaked. So an attacker is working with 18 bits, a space of about 260,000. Assuming the distribution through this space is even (it should be), each possible combination of these 6 bits will match up with roughly 34 million possibilities in the six-digit password space. This is good, as the attacker cannot test 34 million passwords against the server in a reasonable amount of time. However, working with the small word list, we can expect an almost one-to-one correspondence, which is not good. If we were to drop to two color bars, we could expect 73 matches per colorset. If we were to use a step size of 128 instead of 64, we could bring it up to 585 matches per colorset. If we did both of these, 4,688 (but at some point, usability drops off).

Regaining perspective

By dead reckoning, I would guess that most passwords used in a reasonably computer-literate community are stronger than the small dictionary list, containing non-words, numbers and hopefully capital letters or even symbols. But humans do like phonetic constructions and show a strong aversion to random combinations of letters and symbols. And a not-inconsequential number of people are still using dangerously weak passwords, unaware of the dangers of computer security.

So, is it worth it? Assess the risks. A user must leak their password information through a screenshot or similarly exact reproduction. This must either be initiated by the user or social-engineered out of them - someone with direct access to the user's computer could just install a keylogger instead. Additionally, that user must have a weak password. An attacker must take the time to launch a dictionary attack against the gathered information, then test all resulting possibilities against the server until one works. Unlikely, but not implausible. Put this in context with the more mundane but oh-so-effective threats like phishing, email password reset, compromise from another site, and general password carelessness. And finally weigh your perceived threat against the usability benefits Chroma-Hash offers.

Is it worth it? That's up to you.

June 26, 2009

Movies I Hate: I, Robot and S.W.A.T

I have only one "Top Ten List" on Netflix, and it is titled Movies I Hate. The description reads, "Not just movies I strongly dislike. Movies I wouldn't piss on to put out a fire." Here are two more from that list. Enjoy.

S.W.A.T.

0.5 out of 5 stars

I'm actually not entirely sure I've seen this movie. It's hard to tell if I was somehow strapped down and forced to watch it, or if I just ate a bad chicken salad sandwich, went catatonic for a couple hours, and woke up to a preview showing on TV. I'm pretty sure the two experiences are comparable, right down to the taste of expired chicken left in my mouth by the end. All that I can come up with is vague recollections of explosions, shooting, and guns. I assume there were some protagonists and antagonists involved, but they were so forgettable the movie would likely have gone up in quality without them. Sometimes I worry that it's not normal to be missing such a large chunk of time from my memory like this. But mostly I just worry that I actually got tricked into watching this movie. Given the choice, I think I'd take food poisoning.


I, Robot

0.5 out of 5 stars

Well, here it is. The stinkiest stinker. The crappiest crapfest. The travesty of all travesties. If movies were animals, this would be the tapeworm. How not to make a successful movie: First, take the work of a greatly respected science fiction author. Next, spew vomit all over it. Now, feed that mess to your dog and hire some two-bit hack to make up a script that is, in fact, a disgrace not only to Isaac Asimov's collection of short stories, but to all writers everywhere. Finally, to add insult to injury, plaster blatant product placement everywhere, just to make clear exactly how little you respect the moviegoers who have made the unfortunate mistake of wandering into your film. And there you have it! I, Robot. If there is a convincing argument for why humanity will not survive another millenium, this is it. And that's not because we will design killer robots that will turn on us, it's because a society that actually condones sewage like this is in moral decline. Heck, the robots would be doing us a favor. Look for an exciting matchup sometime later this year, as I, Robot's right to the title of "worst movie ever" is challenged by a newcomer, I Am Legend, also starring who else but Will Smith.

May 26, 2009

Radio Sucks

Radio programming is just that!
-- Saul Williams, "Penny for a Thought"
Radio sucks! The same fucking songs over and over again! All the weak ones, all that disposable crap that isn't gonna matter in 3 months, it's just shit!
-- Matt Pinfield, Significant Other hidden track
Turn on the radio, nah, fuck it, turn it off!
-- Rage Against the Machine, "Vietnow"

When I posted my analysis of The Current's playlist a while back, I mused about how it might stack up against a station run by the mainstream corporate borg that is ClearChannel. The problem is that no other stations make their full playlists publicly available, so I had no data to work from. Most of them offer the 10 most recent songs played, and that's it.

I dropped the idea for a while, but when I got myself a cheapo hosting plan, suddenly I had an always-on box that could, say, run a cron every ten minutes, perhaps a cron that scraped some radio sites for their recent songs. And even better, since every ClearChannel subsidiary uses the same template, I only had to build one scraper and I could collect data on half the music stations in the Twin Cities. Score! A little later, I discovered Yes.com, a cool service that even provides an API, and worked out a way to scrape the other major stations in Minneapolis.

The code is available here. The data you see below is the averages for the period of 3/22/09-5/22/09. If you'd like more discussion of my analysis techniques, check out my original post. Don't worry, this post will not contain any sad kitten pictures. Without further ado, the results:
Unique Song Ratio
I went into this expecting KDWB (Today's Best Music) to suck, and they did not disappoint. They come out swinging with an absolutely abysmal level of uniqueness per week - which only gets worse when we measure over a month. However, they're facing some heavy competition from KS95 (Variety...80's, 90's and Today!). Those people seem to be rather confused about what constitutes "variety." Apparently the 80s, 90s, and today just didn't have that much to offer.

Most of the other stations muddle along between 0.2 and 0.3 - not as bad as they could be, but if you've spent any significant amount of time listening to Cities 97, you'll know that's still bad enough to drive a person to murder.

There are a couple notable standouts at the week level - KQRS and Love 105 (the latest owners of what was once Rev105's signal) do respectably. And Jack FM, who brags constantly that they are Playing what we want!, actually beats the Current for uniqueness at the week level. All these stations suffer significantly in the month-long measurements. To me, it looks like these stations have fairly large playlists, but simply rotate the same playlist over and over again. This isn't entirely a bad trait, especially for KQRS (Minnesota's Classic Rock), who doesn't have a growing field to work with.

Still, this demonstrates to me the importance of not only playing good songs, but playing different songs. Sure, it's fun to sing along with "Dirty Deeds" once and a while. But we've been singing along with it for decades now. And yeah, it's quirky when JackFM plays The Bangles right after Linkin Park, but it's a quirkyness that's manufactured by CBS Radio and shipped out to countless identically-named stations nationwide, and I don't think I'm the only one who starts to notice the cracks in the veneer after a while. So, hooray for The Current! Hooray for quirkyness that's actually just Mary Lucia being wacky and saying whatever goes through her head. Yes, Mary, I was listening that one day when you suggested that Mark Wheat take up cocaine.
Highest Playcount
Interesting. You'll notice The Current is definitely not ahead in this race. Jack FM, KQRS, and Love 105 again all put up very impressive numbers, and KOOL 108 isn't bad either. It makes a fair amount of sense - these are the stations that are drawing from several decades of music and shying away from new releases. So they're not under pressure to spin the latest single that some manufactured star just released. Good for them.

The Current, of course, is still a long, long way from the real offenders here. KS95 again manages to compress three decades of music into playing one song almost 50 times per week. And B96 pulls out a surprise win over KDWB here, playing the top song for a given week roughly 85 times in that week. I just threw up a little in my mouth.

Radio sucks, people. It sucks, sucks, sucks. Some stations suck more than others, but I can't lionize anyone here. The best we can ask for in playlist variety, it seems, is mediocrity. Listen to WLTE, who's completely unremarkable in every degree. Or, listen to Rage. Turn it off. There is no guerilla radio. The war was lost to the strains of Howie Day's simpering falsetto.

Epilogue

I've got one last graph for you all because, well, I still have an agenda. Here's the uniqueness graph again, but with one new data point: values from The Current for the same two-month period in 2006 as opposed to 2009.
Unique Song Ratio Redux
This is what I had hoped to see in the earlier charts. It's completely dwarfing the other stations. The scale is all off. It's not even worth debating how one conglomerate scores compared to the others, because The Current is embarrassing all of them. That's what it looks like when one station is single-handedly saving radio. That's where I want us to be.