Wednesday, April 14, 2010

Java RMIConnectionImpl Deserialization Privilige Escalation (ZDI-10-051/CVE-2010-0094)

Relevant Identifiers:
ZDI-10-051, CVE-2010-0094


Impact:
Privilege escalation of the Java security sandbox. The most obvious target is the Java Runtime running Java Applets, JavaFX and Java Web Start applications in a web browser. Untrusted code will gain full privileges of the user executing the browser process.


Oracle Java Patch:
http://www.oracle.com/technology/deploy/security/critical-patch-updates/javacpumar2010.html


Steps to remedy:
Update to Java 6 update 19


Details:
Deserialization of untrusted data from a privileged context has been established as a security vulnerability (Sami Koivu, Julien Tinnes, securecoding.cert.org).

javax.management.remote.rmi.RMIConnectionImpl does privileged deserialization of objects from user supplied data.

More specifically;

-The public createMBean method calls the private unwrap method
-The unwrap method has a doPrivileged block which calls the get method of a java.rmi.MarshalledObject instance
-The get method deserializes an object from an internal byte array
-The byte array can be made to contain a serialized custom ClassLoader (ClassLoader subclass)
-The custom ClassLoader can create classes with full privileges

As with CVE-2008-5353, the trick is that ClassLoader is not Serializable, but the subclass can be made Serializable and in the deserialization process, the first non-serializable superclass constructor is called with the security context of the code doing the deserialization. Even though the subclass is untrusted, the context is privileged, so the security checks of the ClassLoader constructor are passed. Immediately after the deserialization, a ClassCastException is thrown because the code assumes the read object to be an Object array, but this is irrelevant, because an instance to the ClassLoader can be obtained during the deserialization process, by defining a readObject method.

A Brief History of Privileged Deserialization:
August, 2008:
The first known instance of Privileged Deserialization was found in the Calendar class.

December, 2008:
Java 6 update 11 fixes the Calendar Deserialization vulnerability.

March, 2009:
Java 6 update 13 fixes a Privileged Deserialization issue that is not attributed to anyone:

CR 6646860: A security vulnerability in the Java Plug-in with deserializing applets may allow an untrusted applet to escalate privileges. For example, an untrusted applet may grant itself permissions to read and write local files or execute local applications that are accessible to the user running the untrusted applet.
This had to do with a little used option in the APPLET tag. The object parameter can be used to specify a serialized (saved) representation of the applet. Turns out this deserialization used to take place in a privileged context prior to Java 6 update 13.

March, 2010:
Java 6 update 19 fixes a Privileged Deserialization issue in RMIConnectionImpl

The Fix:
The RMIConnectionImpl class was altered to leave the deserialization outside of the privileged block. Only setting current context classloader is done in a privileged block. This eliminates this particular privileged deserialization instance.

2 comments:

Adam Boulton said...

Nicely done, sir. I think there is a lot of interesting vulnerabilities to be covered by exploring RMI. I did some work on it in the past -

http://aboulton.blogspot.com/2009/04/security-assessing-java-rmi-slides.html

Keep up the great work.

Cheers

Sami Koivu said...

Thanks Adam! Thanks for the slides, too, interesting stuff!