Showing posts with label flash. Show all posts
Showing posts with label flash. Show all posts

Friday, December 16, 2011

Doing Cross Page Communication Correctly


I haven't updated this blog in more than one year (woops), but it seems like I still have a couple of followers, so I was thinking on what to write about. I was originally planning to post this on August, but the fix was delayed more than expected.

I decided to choose a random target on the interwebs to find an interesting vuln, and since Facebook recently launched it's "Whitehat Program", which rewards people that report them security vulnerabilities (kinda the same as Google's Vulnerability Reward Program), I chose them.

(Note: As of  December 15, Facebook says they have fixed the vulnerability, and awarded a $2,500 USD bounty).

So, I took a look at their "main JS file": http://connect.facebook.net/en_US/all.js

And well, first thing that came to my mind was RPC. Mostly, because I worked implementing the Apache Shindig's version of the Flash RPC, and have helped reviewing easyXDM's implementation, I just knew this is too hard to get right.

A simple grep for ".swf" in their all.js file lead us to "/swf/XdComm.swf". And since I didn't know what domain that was on I tried:

https://www.facebook.com/swf/XdComm.swf

And that worked.

So let's see.. I sent it to showmycode.com and we get this:
http://www.showmycode.com/?e97c7f39457f9e1b1d5b2167e14b968e

There are several non-security-bugs in that code (some of which I decided to ignore for brevity and keep the WTF quota of this blog low).

In general the security problems found are not specific to FB at all, they are mostly, side effects of bad design decisions from either Flash or the browsers. However, this problems are widely known and can be abused by attackers to compromise information.

Calling security.allowDomain

The first thing I notice is that XdComm calls Security.allowDomain and Security.allowInsecureDomain. This allows to execute code in the context of https://www.facebook.com/ so it's an Flash-XSS, FAIL #1.

The way you exploit this is by loading the victim SWF inside the attacker's SWF. That's it. The problem here is that Adobe provides only one API for enabling two very different functionalities. In this case, what Facebook wants is just allow an HTML container to call whitelisted 'callbacks' from the SWF, but inadvertently it is also allowing anyone to load the SWF inside another SWF and access all methods and variables, which can result in code execution.

Adobe actually acknowledges this is a problem, and they will make changes to support this two different use cases. The reason I don't provide a PoC is because there are several applications out there that depend on this behavior and can't easily deploy any fixes, and Adobe is working on fixing this at Flash (which is where it should be fixed). When there's a viable alternative or a good solution I'll post a PoC.
What FB should have done is keep this SWF out of www.facebook.com.
Getting the embedding page location


The second thing I notice is that it's getting the origin of the page hosting the SWF calling:
this.currentDomain = ExternalInterface.call("self.document.domain.toString");
And as any Flash developer should know, ExternalInterface.call isn't something you can actually trust, so now you can "cheat" XdComm.swf into thinking it's being embedded by a page it isn't by simply overriding __flash__toXML.

So, by abusing this vulnerable check, we can actually, listen and send messages on any LocalConnection channel. This doesn't only mean we just defeated the security of the transport, but that also, if any other SWF file uses LocalConnection in facebook.com (or fbcdn.net), we can sniff into that as well. So, FAIL #2.

It is hard, for a movie (or a plugin whatsoever) to know with certainty where it's being hosted. A SWF can be sure it's being hosted same domain, by requiring the hosting page to call a method in the Movie (added by ExternalInterface.addCallback), since by default, Flash only allows movies hosted in the same domain to call callback methods of a movie (this is what we do in Shindig for example), but besides that it's not so simple.

Some insecure methods exist and are widely used to know the hosting page, such as calling:
ExternalInterface.call("window.location.toString")
There are some variations of that code, such as calling window.location.href.toString, which is also simple to bypass by rewriting the String.toString method, and works on all browsers.

It's futile to try to "protect" those scripts, because of the way Flash handles ExternalInterface, it's possible to modify every single call made by the plugin, since when you call ExternalInterface.call, what really happens is that the plugin injects a script to the window with:
ExecScript('try { __flash__toXML(' + yourCode + ') ; } catch (e) { "<undefined;>"; }');

And, __flash__toXML is a global function injected by Flash, which can be modified to return whatever we want.
(function(){
    var o;
    window.__flash__toXML = function () { return o("potato") };
    window.__defineSetter__("__flash__toXML", function(x) {o = x;});
})();
It's worth noting that Flash also bases some of it's security decisions on the value of window.location (such as, if a movie is allowed to be scripted from a website or not), and while this check is more difficult to tamper (and browsers actively fix it), it's still possible to do it, and it's even easier on other browsers such as Safari (in Mac OS) where you can just replace the function "__flash_getWindowLocation" and "__flash_getTopLocation".

Luckily, it seems like we might be able to get at least the right Origin in future versions of Flash, as Mozilla is proposing a new NPAPI call just for this. Let's just hope that Adobe makes this available to the SWF application via some API.

What FB should have done is namespace the channel names, and use some other way of verifying the page embedding the SWF (like easyXDM or Shindig does).

It is also possible for an attacker to specify what transport it wishes to use, so we might be able to force a page to use the Flash transport even when it might also support postMessage.

postMessage should be used cautiously

There's one last thing I found. Facebook has a file which seems to allow an attacker to forge (postMessage) messages as coming from https://www.facebook.com/ into another page that allows framing arbitrary pages.

The Proof of Concept is located at http://r.i.elhacker.net/fbpwn

As you can see the page will allow an attacker to send messages and will also allow the attacker to specify the target origin. The attack seems to be hard to do since the "parent" seems to be hard coded. So this is FAIL #3.

This is a good demonstration why the existing implementation of postMessage is fundamentally broken, it's really easy for two different scripts to interfere with each other. I can't actually blame FB for that, it's more like a design problem in postMessage.

Luckily there's a new mechanism to use postMessage (called channel messaging), which partly solves this problem (or at least makes it harder to happen). You can read more about it here:

Random fact.. This is what Chrome uses internally to communicate with other components like the Web Inspector.

Vendor Response

I reported these issues from https://www.facebook.com/whitehat on Tuesday Aug 16 2011 at 2 PM (PST), with the draft of this blogpost, and got a human acknowledgement at 7PM. The issue was finally fixed on December 15 2011.

Conclusion

So well, this was my first post of 2011 (it's December!), and I actually made it because there was a few "de facto" knowledge about Flash that I wanted to put in writing somewhere, and because I had a look at Facebook regarding something not strictly related to work!

In general I am impressed on the security of Facebook applications. While doing this I got locked out of my account like 5 or 6 times (maybe they detected strange behavior?), I noticed several security protections in their API (api.facebook.com/graph.facebook.com), and they actually do protect against other security vulnerabilities that most websites don't know about (such as ExternalInterface.call escaping bugs, content type sniffing, etc).

I was awarded a $2,500.00 USD bounty for this report (not sure how it was calculated), and I'm considering donating it to charity (it can become 5k!). Any suggestions?

Tuesday, October 21, 2008

About CSS Attacks

Gareth, David and I went to Microsoft Bluehat v8, it was pretty fun meeting everyone.

Gareth described the talk pretty well in here: http://www.thespanner.co.uk/2008/10/20/bluehat/, (slides) anyway I want to show the stuff we didn't showed at Bluehat because of their no-zeroday policy (even if the vendor wasn't willing to patch).

So well we have the following clickjacking PoCs, that show different attack techniques.

Ghost Mirror - GMail PoC

http://www.sirdarckcat.net/gmailclickjacking.html

Sends an email when you click [Send] (check your sent mails folder).

This technique works like this:

You get a copy of the generated HTML code of the target webpage, then you simply hide everything, except for the button you want to overlay.. you could draw other things using absolute positioning, but this is enough for most scenarios.

You can checkout the "ghost page" here: http://www.sirdarckcat.net/dad.html

This attack has it's pros and it's cons.. the most important pro is that it's the best way of doing cross-browser exploits.. since you don't depend on the sizes, margins, overflow rules etc.. that different browsers use.

This attack (and PoC) was reported to Google Security Team on Sat, Sep 27, 2008 at 11:37 PM, the response was that it won't be fixed (I'm sure they have more serious issues to take care about).

Frame Cropping - Twitter PoC

http://www.sirdarckcat.net/coconuterror.html

This one uses another technique, that is usefull for selecting a specific section of a webpage, this specific PoC is Firefox only, not because the technique is not posible on other browsers, but because you have to make a different exploit for each different browser.

The way it works is using 2 iframes with a fixed height/width and possition, you only have to positionate the iframe using negative left/top coordinates, once you have that, you crop to the height and width of the button.


If that's not possible due to styling specific issues, then you have to use a second iframe that will have a height/width of the size of the button to be overlayed.

Both iframes must have the CSS properties overflow:hidden; and border: 0 (or their HTML attribute equivalent {like frameborder instead of border}).

This one is sexy :)

We also have the.. javascript ones.

Pixel Window - Adobe Flash Webcam PoC

http://ha.ckers.org/weird/cjdivtest.html



This one overlays 4 divs leaving a window where the mouse will be clicked.


Update to the latest Adobe Flash Player to be protected against this vulnerability.
http://get.adobe.com/flash/


Mouse Chase - Adobe Flash Webcam PoC

http://grack.com/record/


The same principle of Pixel Window..but now with the overlay chasing the mouse position.


CSS Attribute Reader Source Code


http://eaea.sirdarckcat.net/cssar/v2/?source

The first version of the reader wont be released yet, maybe later.. sorry.

This type of attack is relevant, because this could start a new type of attack based on XSS, that could be called Cross Site Styling (since we are not really using a scripting language).

There's another version, made by Wisec that is also pretty cool, based on meta refreshes, it calculates 1 char per second, he'll be presenting it soon at ruxcon.

By the way, I also want to say thanks to the guys that attended bunkent0r for their feedback on the presentation.

Greetz!!

Thursday, January 03, 2008

Exploiting XSS vulnerabilities on cookies

Well, after talking with David Ross about the last post (bypassing content-disposition), I found out that it's exploitation wasn't as easy as it appears since IE has done some updates on the last couple of months.. so well.. sorry about that.

Anyway, I guess it's time to say the world a little way of exploiting XSS vulnerabilities that echoes the value of a cookie.

This is based on majohn trick (setting headers via flash post), and well, I remembered about that when I saw kuza's talk.

This is done via flash:


class defconxss {
static function main(mc) {
var req = new LoadVars();
req.addRequestHeader("Cookie:bblastactivity=%3Cscript%3Ealert(document.cookie)%3C%2Fscript%3E", " ");
req["1"]="1";
req.send("https://pics.defcon.org/misc.php?action=cookies", "_self", "POST");
}
}

This is a PoC for a XSS at pics.defcon.org you can read more about it here: http://whk.h4ck1ng.net/2007-12.22/xss-en-defconorg/ but it's on spanish.

An important thing to say is that the cookies sent this way are not persistent by default, anyway, some codes make force them to be persistent.

So this works for me with the latest player: http://www.adobe.com/shockwave/download/

Anyway, internet explorer is not vulnerable.. damn..

You can download kuza's talk here: http://outpost.h3q.com/fnord/24c3-torrents/24c3-2212-en-unusual_web_bugs.mp4.torrent

Greetz!!