The Same Origin Policy is one of the guiding principles that seek to protect our browsing experience. The Same Origin Policy was originally released with Netscape Navigator 2.0 and has been incorporated in one form or another in every major browser since. The concept has additionally been extended to protect such technologies as the Java Virtual Machine, Flash (they're still working on it), and Silverlight (yet to be put to the real test).
Same Origin Policy's goal is to prevent a document, script, applet, etc. loaded from one site of origin from manipulating properties of or communicating with another site of origin. Unfortunately, the Same Origin Policy has been the victim of some brutal attacks as anti-DNS Pinning and DNS Rebinding attacks have come into full scope.
Why is this important? Well, there's a number of reasons as there are a number of technologies that Same Origin Policy protects, but let's focus on one example that really exemplifies the danger of bypassing the Same Origin Policy, Java Applets.
Java Applets have been traditionally protected by the Java Virtual Machine's DNS pinning mechanisms. These protections simply state if an applet is loaded from abc.com (whether through an HTML page or the codebase parameter of the applet tag), it is allowed only to communicate with abc.com and not with def.com (unless it is a signed-applet). Billy Rios (shown in the top image above) and I presented at Hack in the Box Malaysia in 2007 on how this pinning could be broken. There's a nice excerpt on Billy's XS-Sniper blog, which I used to post on, that covers the subject in depth. The basics of it were as follows:
- Attacker forces victim to load an cache a Java Applet (this might be done through XSS)
- This applet would be pinned to the attacker's site where it was loaded from, say xs-sniper.com.
- The attacker controls the domain the applet was loaded from, as he owns the domain; therefore, he can change the IP Address that xs-sniper.com is associated to.
- The victim is forced to load the applet again, this time in a new JVM instance
- In our example at Hack in the Box Malaysia, this was done by forcing the victim's IE browser to load Firefox through the firefoxurl:// protocol handler, which we could point to our site and applet like firefoxurl://xs-sniper.com/appletpage.html.
- This can be done in a couple other ways which we mentioned in the powerpoint presentation we gave.
- Since the applet has already been loaded and cached, there's no need for the victim to download the applet again, which is good since xs-sniper.com is no longer pointing to our IP Address, it's pointing to an IP Address internal to the victim's network.
- As the applet has been loaded in a separate JVM (IE and Firefox will each have their own instance of the JVM), the applet will become pinned to the IP Address now associated with xs-sniper.com.
- We can now use the full power of Java applets against the Internal IP Address. In our example, we used a Java applet to connect to an oracle database server, dictionary attack the username/password to gain access to the server, and then allow us to run arbitrary SQL queries.
The ramifications here are clear, and quite devastating. Fortunately, Sun patched this issue quite quickly, protecting the unsuspecting. That is until John Heasman (shown in the second image above) of NGSSoftware came around. When Billy and I published the attack that we used against Java Applets, John emailed us about something he was working on, which was even easier and accomplished the same results. Here's a summary of that flaw:
By specifying a codebase URI prefixed by “verbatim:” it is possible to load an applet from a remote location but have the browser plugin believe it has been loaded from the local host. This allows an untrusted applet to connect to and attempt to exploit network services running on the local host. It should be noted that unlike binary sockets in Flash 9, an applet can connect to any port, not just those greater than 1024.
At the time of reporting this issue, NGS provided Sun with a demonstration applet that exploited MS06-040 (”Vulnerability in Server Service could allow remote code execution”) on a vulnerable XP SP1 system.
Well, again, Sun came and patched John's verbatim attack, which is great news. Then just recently we had this Sun advisory come out, which we blogged about here on ZDNet. As soon as I read some of the shady attack vectors that were involved, I knew it had to be Heasman. I contacted John about this, and he mentioned he would be making a few postings as demos of the bugs he was involved with on his blog, which you can now see here.
The first attack John covers is against Java Web Start. I'll cut out pieces of John's blog posting here to paraphrase the attack:
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:
This constructor has an interesting property, namely:
public URL(URL context, String spec) throws MalformedURLException
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" />
What happens next may be obvious, but to recap, basically it will load the foo applet from the baz website, but report it as loaded from bar, so we've effectively broken Java's same origin policy. Of course, things are never that simple, so there's some complications that John had to get around, as John mentions below:
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="http://baz.com/foo" codebase="http://bar" />
then an internal canonicalisation routine is triggered, converting '/' characters into '.' so we end up with a URL looking like "http:..baz.com.foo" 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).
AHA, now we've broken Same Origin Policy! Of course, it doesn't end there, John has an attack that will actually break us out of the Java sandbox! I'll cover that here as well, and I'll also be covering a few more attack vectors against Same Origin Policy over the next week or so, so stay tuned!