Friday Rundown – 9/24/2010

September 24, 2010

I’m starting a new thing- a weekly summary of what I’ve found interesting in the security world. Naturally, there’ll be a web app bias, because that’s what I follow. At any rate, here’s a few links and thoughts about what’s going on.

Samy Kamkar (the guy that wrote the Samy Worm) released the Evercookie, demonstrating how to track users based on many unique aspects of their web browers. Most users don’t clear their cookies often enough, but how many also clear their browser cache, their Flash LSOs, and their browser history? Oh, also, the Evercookie can persist across multiple browsers, and multiple sessions (due to Flash’s lack of boundaries, mostly). Wouldn’t be hard to make it work on multiple computers too, and that’d be neat. I’ve been saying for a while that the public fear of cookies is pointless- there are plenty of other ways to track users (and there’s a lot of valid ways to track people that the Evercookie is still missing, like SSL session IDs). At least cookies are easy to get rid of.

Twitter got hit by another XSS worm. That makes 4 this year, by my count. Trust me, this isn’t the last XSS hole in their app, and it surely won’t be the last worm.

At the same time, Stefano Di Paola was trying to report a DOM-based XSS hole in Twitter. They initially ignored it, assuming it was the same hole that was being actively exploited by the worm. When he persisted, they “fixed” it with a poor regular expression, which he quickly bypassed.They patched it again once he’d blogged about it, and still haven’t done a particularly great job of it. I don’t know if the lesson here is that Twitter is bad at security (we already knew this), or that it’s not really that easy to prevent XSS (we already knew this too), but it’s an interesting story at any rate.

It’s actually been a pretty slow week- more people talking about Facebook being down and Twitter being hacked than “serious” security stuff, but Rafal Los brought up some interesting points in a post on code vulnerability metrics. I don’t agree with everything there, so I’ll probably be putting together a full blog post on the subject next week. A lot of people were out at Source Barcelona and now Brucon this week, so there will likely be some good conversations coming from that.

Until then, here’s a tip of the week:

Subscribe to your local OWASP chapter‘s mailing list and go to one of their meetings. You’ll meet smart people, learn a few things, and have fun. If there’s no OWASP activity, find other security groups, or even Linux user groups.

McAf.ee is Stupid

September 21, 2010

McAfee just announced that they are releasing a URL shortener, and it’s currently in beta (well it actually says “This Site is a Beta.”). Honestly, I’m still trying to figure out what it’s actually useful for, and not coming up with much. Did somebody decide it was needed? Did somebody think it would be helpful? Is this just McAfee swinging wildly in the dark at things that vaguely sound security related in order to bloat their product portfolio and brand?

Yeah, that might be it.

At any rate, there’s a few issues I noticed with a quick inspection.

The server doesn’t appear to be prefetching the URL, so it can’t have any idea whether the URL is dangerous or not. Presumably it’s checking the URL against the (admittedly impressive) database of sites that they use for SiteAdvisor, another McAfee product.

It does have some basic Javascript/XSS filtering, but it’s only effective against specific vectors- it filters out some HTML characters (like < and >), but not other XSS vectors: " onload=alert(1)

Most URLs will be placed inside an iframe with some basic information about the target URL. If the URL is deemed harmless (or “green”), the user’s browser can be set to bypass the iframe and go directly to the page. Presumably this is just a convenience– there’s no way this could actually provide any browser security, but if a way to attack this iframe were found, or if the iframe needed to be disabled, an attacker could turn that feature on/off via CSRF:

http://mcaf.ee/api/config?bypass_frames=1
http://mcaf.ee/api/config?bypass_frames=0

The only real information McAfee provides somebody visiting a shortened URL is in the iframe, where it says what kind of website they think you’re visiting (in the case of skeptikal.org, it’s “Software/Hardware Blogs/Wiki”). Interestingly, if the link I provide throws a 302 or other redirect, it still thinks you’re looking at my site. Since they’re not prefetching the page, they have no idea whether I’m redirecting you elsewhere, or attacking you directly. If users are screening pages using McAf.ee, it’s trivial to bait-and-switch them onto another site.

The question I’m still asking is “who thought this would be useful?” It’s really not. First off, they claim to let people create “safe short URLs.” That’s not even close to true, based on what I’ve seen. Second, the whole thing is pointless unless users refuse to click on any other shortened URLs– a ridiculous proposition to begin with. Attackers will just use a different URL shortener. Users will keep clicking on anything, and it’s not the URL shortener’s job to keep them safe at any rate. Not to say that McAf.ee directly causes security issues, but it doesn’t appear to solve any security issues either.

/sigh

The Twitter XSS Post-Game Show

September 7, 2010

Since you’re here, you’ve probably already heard about the Twitter XSS shenanigans from the last few days. The short version: Somebody found a hole in Twitter, and I decided to write a proof of concept. There wasn’t really any motivation, other than the fact that I woke up earlier than usual and felt like coding an exploit. That said, a lot of interesting things came from it, and it spawned a series of related projects that I’ll be working on for months to come. Overall, it was fun.

What Happened

Monday, 4:00 AM: Woke up. Couldn’t sleep, so I logged on to see what was happening in the world. I saw an XSSed.com post for a hole in dev.twitter.com and slapped together the original proof of concept.

The exploit was pretty simple- I created a web page with a button that said “pwn me.” When you clicked it, your browser would be forwarded to the vulnerable page on dev.twitter.com, which would execute arbitrary Javascript, collecting your cookies from the browser and sending them back to my server.

My server would then use your cookies to make requests directly to Twitter, posting a tweet using your session (and by extension, from your account). That tweet, in turn, contained a link to the original exploit page, which all your followers would see. Essentially, this allowed it to spread like any other XSS worm, though as a proof of concept, it did provide ample warning to users about what was going to happen.

4:15: The exploit went live and I tweeted about it. I then went out for breakfast.

Throughout the day, my exploit page was viewed 1823 times. 221 individuals were kind enough to test it and send me unique session cookies. How many of those users didn’t read the warnings and were embarassed by essentially handing me the keys to their Twitter accounts, I can’t say, but only 34 of those tweets are still in the public Twitter feed. Many people tested the exploit, then deleted the resulting tweet. Many more tested the exploit from private accounts. A small group used temporary “test” accounts to play with it.

I wasn’t logging any personal data (I’m not Google, after all), so I only know how many unique, successful exploits took place, which ones are public, and which ones were public, but have disappeared from the timeline.

At some point during the day, a spammer released a “real” version of the same exploit, attacking primarily users in Brazil. Their attack code performed essentially the same cookie theft operation as I did- it is a pretty standard session theft attack, after all. The difference, of course, is that this one was automated, and contained no warning messages for the user. The numbers for this attack are even less reliable than mine, but the malicious bit.ly link currently has over 116 thousand hits. I’m betting the actual compromised sessions are less than half that, given that many users will click the link multiple times, many “clicks” will come from bots, people who aren’t logged into Twitter, etc. The only people who could really say are Twitter, the attacker, and maybe the folks at bit.ly. Regardless, this certainly speaks to the efficiency of automated exploits.

About 4:15 PM: Twitter fixed the original bug, and I took my proof of concept offline.

About 11:30 PM: @kinugawamasato tweeted a second variant of the same exploit. I didn’t see it till the next morning.

Tuesday, about 9:00 AM: I saw the new exploit, adapted my proof of concept, and put it back live. Over the next hour, I collected another dozen sessions, but it didn’t get enough time to pick up steam before things started acting strangely.

12:00 PM: Twitter appeared to have fixed the issue completely, replacing the search form with a standard Google search.

The Technical Details

The original vulnerability was exploited by passing double-urlencoded parameters to the search form on dev.twitter.com. Presumably, those parameters were not normalized properly before the filtering/validation phase, and so malicious Javascript characters could be inserted into the page. This isn’t a remarkably unique vector, or a difficult one to find. I’m surprised it took this long for somebody to look.

When this vulnerability was fixed, the second variant was a bit more arcane, but not really all that different. Parameters sent to the server included UTF-8 encoded characters, which again, were able to squeeze past the filtering/validation phase undetected. Kind of cool, actually.

The server side of how I performed the exploit really isn’t that interesting, but since several people asked to see the code, here it is, in all its bug-ridden, insecure glory. This script does not exist on my servers anymore. :)

My Analysis

The big question bouncing around the security media echochamber is “what does this mean?” Lots of people have lots of ideas, and most of them are wrong.

First off, Twitter doesn’t have a very good security track record. I doubt this is shocking to you, but it’s yet more evidence that you should be careful about how much trust you place in Twitter itself, and in the tweets of your friends. Something to keep in mind, at least. (As a side note, Twitter has been trying to hire security people for some time, so if you think you’re up to that particular challenge, I’m sure they’d be happy to talk to you). They’ve done impressive things with scalability, data management, and arguably, created a whole new way of communicating with people. Twitter is a very interesting company, but security isn’t something they do well.

The key to these attacks, of course, was faulty input sanitization. Input sanitization is extremely hard to get right, and there is no reason that Twitter should have been manually patching specific vulnerabilities. If they’d used a decent, standardized sanitization library, the issue could have been fixed once and for all, and probably prevented in the first place. I’m a big fan of OWASP’s ESAPI project, and it probably would have helped here.

It is important to note that Twitter’s session cookies are scoped for the entire *.twitter.com domain. This certainly makes it easier for users to stay logged in between, say, the mobile, static, and regular web sites, but it also opens them up to serious issues.

Another XSS hole on any subdomain of Twitter.com (there are many– subdomains, and XSS holes) can be exploited in the exact manner as these last two. If Twitter intends to keep the wide scope on their session cookies, they really should be much more careful about what other applications live on “twitter.com” domains– particularly domains pointed at third-party servers, such as apiwiki.twitter.com and status.twitter.com. In fact, one of these applications has its own XSS holes, and there’s nothing Twitter can do about it (more details will be coming when I’ve coordinated a fix with the vendor, presumably).

Twitter, by the way, is not alone in this problem- virtually every nontrivial site on the web has sessions scoped the same way, and is vulnerable to similar attacks. Web browsers make trust decisions based on domain names (flawed as that system is), and most website owners are far too blasé about the value of their namespace.

XSS is a massive problem. It’s really a pretty basic attack, which is why it’s not all that interesting to most researchers. It’s trivial to find, trivial to exploit, and we quickly move on to other things. The problem, though, has not gone away. As websites grow, scope widens, and browsers gain more functionality, the XSS problem continues to grow steadily worse.

There is absolutely no excuse for a major website like Twitter to not have gone through a serious application security review process, quarantined non-essential applications (such as this developer documentation site) with unique domains and tighter-scoped session controls, and then reviewed the remaining applications for security vulnerabilities. If you build a web property with this much attack surface exposed, trying to find and fix individual bugs is pretty much pointless.

I won’t make any judgment about how smart it was for people to use my exploit, despite the warnings. The fact is, you are vulnerable to these attacks unless you are taking specific measures to prevent them. I’ve seen comments from some people who feel clever about not clicking my (well-labeled) malicious link, but they’re still browsing with Javascript enabled. Trust me: You really can’t trust me. I don’t even browse my own website without both NoScript and RequestPolicy cranked up.

Interestingly, in the times when NoScript is most needed (critical or popular websites that you interact with regularly), you’re the most likely to have it disabled. If you use Twitter’s web interface at all, you have to disable NoScript for that domain– it’s simply not functional without Javascript. The exploit itself didn’t have to use Javascript at all outside the twitter.com domain, so odds are, it could have worked on you even with NoScript installed. Still, NoScript has quite a few other security features that work even when Javascript is enabled, so it’s still useful, even if you globally enable Javascript (though I hope you don’t). I’ve said it before, but for a secure-by-design browser, RequestPolicy is where it’s at.

Final Thoughts

  • You really shouldn’t click a link that says “I just got pwned” unless you really know what you’re doing
  • XSS attacks are incredibly easy to exploit, and difficult to prevent. This makes them extremely dangerous
  • You trust your web browser far too much
  • Your web browser trusts me far too much
  • NoScript is nice, but when you need it most, you’re probably not using it
  • Self-referential hacks are hilarious

–Mike Bailey

Another day, another Twitter XSS

September 6, 2010

It may surprise some, but I really haven’t been big on XSS lately, mostly because it’s a problem that hasn’t changed for years, and the most basic form of it is still brutally simple to exploit. Not a lot of excitement in it, I guess. But that doesn’t mean that it doesn’t deserve attention- in fact, that’s exactly why it does. So when a new Twitter XSS popped up on my feed reader this morning, I took the 10 minutes it takes to write a proof of concept, and put together an exploit.

You can check it out if you like (It won’t bite until you manually click the “pwn me” button, so the link is safe, but don’t take my word for it, use NoScript and RequestPolicy). Frankly, if I wanted to hack you, I’d be doing it silently on this page, not that one.

I’ll post a followup later. This example drives some pretty interesting points home.

Cross-subdomain Session Fixation

September 2, 2010

Last fall I wrote a bit about cross-subdomain cookie attacks. As often as I come across more uses for them, I think that they are a much more serious issue than most people (myself included) have made them sound. Today, I came across a variant which I’d theorized about in the past, but never bothered to find in the wild, and I think it merits some attention.

You may be familiar with Hack Is Wack- a stupid marketing campaign from Norton/Symantec. The premise is simple: users submit videos, which are voted on, and the winner gets to roll with Snoop Dogg…’s manager. You may not know it, but most of Snoop’s music is information security-related. “What’s My Name” is about AuthN, “Drop it like it’s Hot” is about SQL injection, not to mention constant references to cron, gzip, and other unix commands in his lyrics. It’s really a pretty natural match.

At any rate, the Hack is Wack site is chock full of holes. For example, there’s the publicly available, indexed cache directory with all that SQL, JSON and other data. There’s the XSS vulns (HTML5 only, though it should be simple enough to rewrite), CSRF holes, and the Flash upload issues in the video upload script (a Joomla module that appears to have been used without any quality control or review despite the fact that it’s currently in Alpha)

A security company using bad code in a marketing site? Shocking, I know. I’m really not here to harp on them though. I’m over security vendors being full of shit- they all are, it’s not news.

I just found a particular attack vector interesting.

The voting system for uploaded videos is grossly vulnerable to CSRF, and probably much more serious things, based on the format of the “vote” URL (unencoded, for ease of reading):

http://www.hackiswack.com/index.php/home/rate.html?videoid=\'.24.\'&rating=4

This means that I can create image tags in my own website to vote for a specific video and stuff the ballot box. Classic CSRF, right? It’s something I’ve talked about before, but unfortunately, this one isn’t quite so simple. You have to be logged into the site to vote, and they prevent a user from voting twice for the same video, so to manipulate this poll, we really need to create a whole bunch of user accounts. The user registration page is part of the main Joomla codebase, and it uses session-based tokens to prevent CSRF- the way they should.

The interesting thing here, is that the application doesn’t enforce the HTTP Host header. Instead of http://hackiswack.com, there’s no reason you can’t use the application from http://184.106.223.144, or more importantly, http://hackiswack.skeptikal.org (no, this doesn’t actually go there, but there’s no reason it can’t).

Once I have my own domain set up, I can easily force a visitor to skeptikal.org to assume arbitrary session cookies that will also be sent by his browser to hackiswack.skeptikal.org, and with a known session cookie, I can request the page myself and parse it for the CSRF token. I can then embed that token in any forms I force the user to send, bypassing the protections that Joomla so carefully puts in place.

All right, so this is a lot of work, and probably isn’t practical for stuffing ballot boxes, (especially since there are already much more serious vulnerabilities to take advantage of) but as a way of bypassing CSRF protections, it’s perfectly valid. There are plenty of times where a CSRF protection mechanism can be bypassed with a simple session fixation attack. A variation on this was described by RSnake last fall, using DNS rebinding instead of subdomains. It’s probably more potent with DNS rebinding, but a cross-subdomain attack tends to be much simpler to set up.

The key to remember is that in this case, you can’t take over an arbitrary session, so it is of limited use for, say, compromising an Admin. However, if you want to log a user into a website (with known credentials), or otherwise force him to do something on your behalf, it’s a very useful technique. Something to keep in mind, at least, and another reason why websites that don’t require specific Host headers should be considered vulnerable.

-Mike Bailey

Cross-posted from http://skeptikal.org.
Hat tips to The Harmony Guy and Packetwerks for pointing out some of the holes in the Hack is Wack site

Follow us on Facebook!
Follow us on Twitter!
Sign up for our E-mail List!

What they're saying: