Showing posts with label hacking. Show all posts
Showing posts with label hacking. Show all posts

May 9, 2010

Dumbjacking

One of my Facebook buddies got hit with an attack today that spammed his entire friends list with a link to a "fan page". The page promises "LOOK AT HIS COMMENT.. IM STILL IN SHOCK!!" and gives you a button to "see the worst status update ever". When you click it, you are given a series of commands: hit Ctrl-C, then hit Alt-D, then hit Enter.

Unbeknownst to the user, there is a hidden textfield on this page containing Javascript code. Upon clicking the button these contents are automatically selected. The instructions, when followed, result in the user copying the code and pasting it into their address bar, where it runs like a bookmarklet. You can see a deconstruction of the code in question in this blog post. The Javascript is obfuscated, but there's no technical need for that - probably just a scammer trying to protect his secret.

Having the user copy and paste the Javascript into their address bar breaks out of the sandbox for third-party content, allowing full control over the user's account. The code uses this power to silently mark the user as "liking" the offending page, and sends a message to all their friends "suggesting" the page.

The Facebook page in question has been taken down, but at the end of the process the user is linked to this URL to see the promised status update (I don't recommend visiting it):
http://facebook-lmao.blogspot.com/2010/05/shocking-status-update-guy-needs.html

There is some invasive Javascript going on that tries to con you into taking a survey. Presumably this is the motivation behind this attack - get people to this site and then relieve them of their money through a venerable internet scam of one type or another. Interestingly, if you can make it past the survey (thanks, Firebug), there's a link to this post, which seems to be a legitimate and unaffiliated blog.

Lord knows Facebook has had their share of security fails in the past, but this particular technique seems to have surfaced only recently. I am christening it Dumbjacking, because it's like Clickjacking, but dumber. It relies on tricking the user into doing something dumb, like pasting Javascript into their address bar.

But here's the problem: this technique is nothing if not effective. As of writing this, the page I investigated had 15,571 people who "liked" it. It seems dumb, but for someone who has no idea about "Javascript" or "URLs" or "the address bar", the shady sequence of keypresses means nothing and raises no red flags. In fact, a decade of awful usability in web apps has trained people to find arcane instructions like "Press CTRL and C" mundane, a normal part of using websites.

Dumbjacking is never going to be completely preventable. There will always be gullible, confused people who will blindly follow any number of steps (remember the old IRC Alt-F4 gag?) and somehow compromise their accounts or other information. We can't prevent all of it.

But a large part of the responsibility lies with Facebook's awful app model. The idea of allowing third-party HTML (and worse, sandboxed JS) to sit right inside pages on the official Facebook site is just terrible. I don't think they have accurately assessed the threat of "native styling" - that is, third-party widgets that look exactly like real Facebook widgets. There's no indication of where Facebook-sanctioned content ends and third-party code begins. Give users a button that looks like a Facebook button, and they will click it. Give users incomprehensible instructions on a Facebook page with the promise of something outrageous at the end, and they will follow them to the letter.

Can a site prevent every instance of users doing something stupid? Of course not. But the Facebook app system is just making it easy for scammers. Embedded content means you can launch your attack from the cozy confines of Facebook itself, and Facebook's mission to plaster those stupid "Suggest this to a friend" buttons across every corner of the earth means there will be no shortage of new attack vectors.

The technical decisions coming out of Facebook are the decisions of a company interested in monetizing as much as possible instead of doing right by their customers. There will be no end of security and privacy problems surfacing on Facebook. As far as I'm concerned, it should be treated as a site that is always compromised, where all information is public, and no content is trusted. Want to stay safe on Facebook? Use it as little as possible.

April 22, 2010

Facebook Hates Old People

So I was on Facebook, inspired by their latest round of privacy fail to clean out the last vestiges of personal profile information on my account. I decided that altering my birthday to give myself a bit more age might lend me a certain air of respectability. But to my surprise, upon setting my birthday to 1901, I saved my changes only to be informed that I had in fact been born April 22nd, 2010.





Cue "Born Yesterday."

"That's funny," says I. "December 14th 1901 works fine, but the 13th is no good at all, nor anything earlier than that!"





So if you're 109 years old and join Facebook, they won't let you show your birthday! Same goes for anyone older (I bet that 122-year-old is pissed). Seems pretty ageist, don't you think? And what's so bad about December 13th, eh? I mean, Ted Nugent was born on December 13th, but you can't hold that against the day itself...

Hang on, what's December 13th in Unix time?

$ date --date '1901-12-13' +%s
-2147536800

Well, I say! That's just a bit past -2147483648, which is... ah, that's right, -(2^31), or the lowest number that can be represented by a signed 32 bit integer. Guess we know how Facebook is storing their dates, eh? Too bad they didn't bother limiting the options on their date picker to match their technological limitations.

They must have some validation in place to prevent you from having a birthday in the future, so when the integer rolls over to a positive number, it just gets cut down to the current day. Pity, really. I was looking forward to being born on January 18th, 2038.

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.

March 22, 2009

Enacting my own Terms of Service

I currently have a couple web crawlers running that periodically request content from a couple websites and store it in databases. It struck me as strange that these websites deigned to stipulate certain "Terms of Service" (ToS) over my use of their content and believed that these terms formed a contractual agreement, even though there had been no negotiation over these terms, and I had never signaled my assent (I haven't clicked any little "I agree" buttons on any of these sites). So I decided to bring the art of negotiation back into the formation of these previously one-sided agreements.

So, when one of my spiders makes a request, it adds a name/value pair to the query string of the URL, like so:

http://server.contentprovider.com/requested/1234567?tos=http://static.iangreenleaf.com/TermsOfService.md
This parameter directs the content provider to my own Terms of Service for the transaction. My terms start out by making clear how a content provide may accept or decline them:

By serving the content I requested, you are agreeing to all the terms and conditions set forth in this document, without reservation. If you do not wish to agree to these terms, do not serve your content in response to this request.

They go on to detail how I may use the content I am requesting. My favorite part is this:
By serving the requested content, you agree to hereby waive any and all restrictions on use of your service that you may stipulate in your own Terms of Service, Terms of Use, or other legal document...
So if the content provider responds to my request, they have agreed to my ToS and waived any terms that they may subsequently try to stipulate on my use of their content.

Now, you might think this is stupid or absurd. You might even think that this is totally unenforceable, seeing as how all I have done is provide access to the terms I am stipulating and take continued participation as consent. And I would tend to agree with you.

However, I claim that if my terms are unenforceable, so are those stipulated by the content provider. How is my request any different than providing a tiny link to the Terms of Service way down at the bottom of the page?

Example of Terms of Service link

I have as much right to place limitations on the transaction as they do. My limitations just happen to nullify all of their limitations. They're welcome to stop serving me content if they don't want to accept my terms.

Think I'm wrong? Tell me why.

October 28, 2008

How Bulk Political Mailing Should Be Done

A few days ago, I came across a real gem of a political mailing from the Republican Party of Minnesota. To a casual observer, it might just look like a sad smear attempt by a party hijacked by reactionaries and lacking any real substance. But I saw beyond the partisan hackery, and realized that this mailing had far more potential. It could be something truly great. And behold, with some scissors and glue, I made it so.

Before
Before
After
After

For best results, read in your best Dan LaFontaine voice (and watch a preview or two in his memory).

August 1, 2008

Hacking Grinnell Laundry

Disclaimer: I am giving you the knowledge, I am not dictating how it should be used. That's up to you to decide.

Easy steps to being a Grinnell outlaw:
  1. Put your laundry into a dryer. Pay with your P-card.
  2. Hit "Delicates" or the other option that isn't "Colors/Whites". Your dryer should fire up with something like 70 minutes on it.
  3. Open the dryer door. Close it again. The dryer will start blinking Select Cycle.
  4. Hit "Colors/Whites". The dryer display indicates that it is using the Colors setting (i.e. higher heat) but with all 70 minutes or whatever you got out of step 2.

For the record, I haven't actually checked to see if the dryer is doing what it claims to be doing. It could be so dumb that it is displaying one setting while giving you lower heat. I don't know. I do know that Grinnell laundry machines are crap.