Wednesday, April 28, 2010

Mutable InetAddress Socket Policy Violation (ZDI-10-055/CVE-2010-0095)

Relevant Identifiers:
ZDI-10-055, CVE-2010-0095


Impact:
Violation of Same Origin Policy, allowing unsigned applets to connect to any host.


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


Details:
This is a low-impact, but technically somewhat interesting vulnerability.

java.net.InetAddress is a public, non-final, serializable class. It has a package-private constructor.

If one was to respect compiler errors, it would not be possible to create a subclass of InetAddress in another package, because creating a legal constructor for the subclass is impossible. But it turns out one does not need a legal constructor. As the superclass is serializable, the subclass constructor never gets called and never gets verified by the run-time. No tricks are required for creating the subclass. For example, Eclipse compiler will compile the rest of the class normally and create a constructor that just throws an exception.

In the case of InetAddress this allows us to create a subclass which is a mutable InetAddress. In other words, give the same origin policy check one value, and use another value when doing the actual connection. Nothing as complicated as timing is required as the SOP check uses the getHostAddress() method, while the actual connection uses the private address field, which can be deserialized into having any desirable value.

The Fix:
Update 19 added a readObject method to the InetAddress class, which throws a SecurityException if the instance being read was not loaded by the null ClassLoader.

Tuesday, April 27, 2010

Symantec on ZDI-10-051 and ZDI-10-056

An interesting piece on the Symantec blog by Adrian Pisarczyk on ZDI-10-051 (CVE-2010-0094) and ZDI-10-056 (CVE-2010-0840).

"Perfect" Client-Side Vulnerabilities
The first property, which makes such issues attractive for attackers, stems from the fact that they do not rely on any memory-corruption conditions; hence, the exploits are extremely reliable and do not have to cope with memory protection mechanisms. ASLR and DEP-based protections will not protect against the exploits.

...

Another uncommon vulnerability feature sought after by attackers is platform and browser independence.
Not to take absolutely anything away from it, but Adrian's analysis makes much of the same, valid points as Julien Tinnes' post from about a year back on the calendar deserialization issue:

Write Once, Own Everyone
...most other client-side vulnerabilities that can lead to arbitrary code execution, including other Java vulnerabilities are memory corruption vulnerabilities in a component written in native code. Exploiting those reliably can be hard. Especially if you have to deal with multiple operating system versions or with PaX-like protections such as DEP and ASLR.
This one is a pure Java vulnerability. This means you can write a 100% reliable exploit in pure Java. This exploit will work on all the platforms, all the architectures and all the browsers!

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.

Thursday, April 08, 2010

Java Trusted Method Chaining (CVE-2010-0840/ZDI-10-056)

Relevant Identifiers:
ZDI-10-056, CVE-2010-0840


Impact:
Privilege escalation of the Java security sandbox. The most obvious target would be 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:
Java code originating from the Java core classes in the JRE/lib directory is considered trusted.

Java code originating from an unsigned Java applet is considered untrusted.

When Java evaluates privileges for any given operation, it considers the whole method call stack.

For each item on the stack, the privileges of the class that defined the method in question are considered. Thus, if class Foo defines method call() and class Bar is a subclass of Foo, and an instance of Bar is on the stack, and the method is call(), the privileges of Foo, not Bar, are considered.

It is possible to implement interface methods with methods inherited from a superclass; For example, if interface CacheItem has void method delete() and class Folder, which implements no interfaces, has a method with a compatible signature, it is possible to create a concrete class FolderPosingAsACacheItem which extends the Folder class, and implements the CacheItem (with the inherited method) without defining any methods of its own.

There are hundreds (thousands?) of trusted classes in the Java core that call methods on objects which can be defined by untrusted code either directly, via sub-classing or via deserialization.

These methods can be arranged in such a way that a trusted thread (such as one of the event threads) may be chained into calling method A which calls method B which calls method C ... which calls method Z. As only trusted code will be on the calling stack, the privileged context of the trusted thread is maintained. If one finds a method Z that does something interesting, such as a parameterizable method invocation via reflection, that invocation will take place in a privileged context.

This is very bad because it means that security relies that there not exist harmful combinations of methods signatures; something that is not feasible to control, as opposed to the very controlled model of having a number of doPrivileged blocks which are known to be dangerous, but relatively easy to control.

ZDI-10-056/CVE-2010-0840 leverages this by creating a trusted chain as follows:

- instantiate a vuln.Link (subclass of java.beans.Expression) pointing the invoke params to class: java.lang.System, method setSecurityManager, args: null
- instantiate a new java.util.HashSet and put the vuln.Link (which is also a Map.Entry) in the Set
- instantiate an anonymous subclass of HashMap where the entrySet method returns the instance defined above
- instantiate a javax.swing.JList object, passing the HashMap instance defined above as the list contents
- add the JList on any visible component (such as the applet itself)

And here's what happens when the digital Rube Goldberg machine is set into motion:

- the GUI thread wants to draw the JList and calls JList.paint(Graphics)
- JList while drawing itself, calls toString on the list contents, including said anonymous subclass of HashMap
- HashMap inherits AbstractMap's toString method which calls entrySet().iterator() and iterates the resulting Set, calling getValue on each Entry
- one of the Entry objects returned by the implementation is a subclass of Statement, which implements the Entry interface's getValue() method with the Statement.getValue()
- Expression.getValue() calls Statement.invoke()
- Statement.invoke() has been parametrized to call System.setSecurityManager(null) via reflection

...and Java security gets switched off.

Safety First:
The vuln.Link class cannot be created with a normal Java compiler. Hopefully that'll keep the virus writers at bay, while the details enlighten the security community.

The Fix:
Based on my very brief analysis, Java 6 update fixes this problem by altering the Statement.invoke() to use the AccessControlContext captured at the moment of instantiation when it uses the reflection.

Monday, April 05, 2010

Java Security Updates

Zero Day Initiative has released three Advisories relating to vulnerabilities I discovered last year. Here are the original advisories, more details to follow shortly.

Sun Java Runtime RMIConnectionImpl Privileged Context Remote Code Execution Vulnerability

ZDI-10-051: April 5th, 2010

CVE ID

Affected Vendors

Affected Products

TippingPoint™ IPS Customer Protection

TippingPoint IPS customers are protected against this vulnerability by Digital Vaccine protection filter ID 9591. For further product information on the TippingPoint IPS:

Vulnerability Details

This vulnerability allows remote attackers to execute arbitrary code on vulnerable installations of the Sun Java Runtime Environment. User interaction is required to exploit this vulnerability in that the target must visit a malicious website.

The specific flaw exists within the deserialization of RMIConnectionImpl objects. Due to a lack of privilege checks during deserialization it is possible to supply privileged code in the ClassLoader of a constructor being deserialized. This allows for a remote attacker to call system level Java functions without proper sandboxing. Exploitation of this can lead to remote system compromise under the context of the currently logged in user.

Vendor Response

Sun Microsystems has issued an update to correct this vulnerability. More details can be found at:

Disclosure Timeline

    2009-10-21 - Vulnerability reported to vendor
    2010-04-05 - Coordinated public release of advisory

Credit

This vulnerability was discovered by: Sami Koivu




Sun Java Runtime Environment Mutable InetAddress Socket Policy Violation Vulnerability

ZDI-10-055: April 5th, 2010

CVE ID

Affected Vendors

Affected Products

Vulnerability Details

This vulnerability allows remote attackers to violate security policies on vulnerable installations of Sun Java Runtime. User interaction is required to exploit this vulnerability in that the target must run a malicious applet.

The specific flaw allows malicious applets to connect to network addresses other than the originating applet and client IPs. A handcrafted applet can override compile time checks to prevent compilation of a mutable InetAddress subclass. This results in the ability to circumvent the Applet SecurityManager restictions.

Vendor Response

Sun Microsystems has issued an update to correct this vulnerability. More details can be found at:

Disclosure Timeline

    2009-10-21 - Vulnerability reported to vendor
    2010-04-05 - Coordinated public release of advisory

Credit

This vulnerability was discovered by: Sami Koivu




Sun Java Runtime Environment Trusted Methods Chaining Remote Code Execution Vulnerability

ZDI-10-056: April 5th, 2010

CVE ID

Affected Vendors

Affected Products

Vulnerability Details

This vulnerability allows remote attackers to execute arbitrary code on vulnerable installations of Sun Java Runtime. Authentication is not required to exploit this vulnerability.

The specific flaw exists within the code responsible for ensuring proper privileged execution of methods. If an untrusted method in an applet attempts to call a method that requires privileges, Java will walk the call stack and for each entry verify that the method called is defined within a class that has that privilege. However, this does not take into account an untrusted object that has extended the trusted class without overwriting the target method. Additionally, this can be bypassed by abusing a similar trust issue with interfaces. An attacker can leverage these insecurities to execute vulnerable code under the context of the user invoking the JRE.

Vendor Response

Sun Microsystems has issued an update to correct this vulnerability. More details can be found at:

Disclosure Timeline

    2009-11-24 - Vulnerability reported to vendor
    2010-04-05 - Coordinated public release of advisory

Credit

This vulnerability was discovered by: Sami Koivu