2016년 1월 19일 화요일

Java Deserialization Vulnerability

* From IBM X-Force Exchange

Java Deserialization Vulnerability

In January of 2015, Christopher Frohoff and Gabriel Lawrence discovered vulnerabilities in the way some Java libraries deserialize objects.
Object serialization is where an object can be represented as a sequence of bytes that includes the object's data as well as information 
about the object's type and the types of data stored in the object. The vulnerabilities that these two researchers discovered can lead to
remote code execution on a number of systems. More recently Matthias Kaiser gave another, more detailed talk on how to exploit these 
types of vulnerabilities and Foxglove Security wrote a blog post covering five different attack scenarios/targets with proof-of-concept (poc)
code provided. 

Vulnerability Description

The vulnerability involves the InvokerTransformer class in the Apache Java library: 
org.apache.commons.collections 

The issue is that the InvokerTransformer class gets deserialized by default by the readObject() function, yet the class constructor does not 
perform any validation on the method being invoked when the class is instanced. This allows an attacker to nest InvokerTransformer
instances, with invalid invoke methods such as exec() function calls, within a handler like AnnotationInvocationHandler that then gets
serialized. When the serialized data reaches the server, the readObject() automatically deserializes the InvokerTransformer instances and 
that automatically invokes the invalid method(s), thus launching arbitrary commands.

In the code snipped below, we can see proof that there is no validation of the methods being called by InvokerTransformer:
    /**
     * Constructor that performs no validation.
     * Use <code>getInstance</code> if you want that.
     *
     * @param methodName  the method to call
     * @param paramTypes  the constructor parameter types, not cloned
     * @param args  the constructor arguments, not cloned
     */
    public InvokerTransformer(String methodName, Class[] paramTypes, Object[] args) {
        super();
        iMethodName = methodName;
        iParamTypes = paramTypes;
        iArgs = args;
    }

    /**
     * Transforms the input to result by invoking a method on the input.
     *
     * @param input  the input object to transform
     * @return the transformed result, null if null input
     */
    public Object transform(Object input) {
        if (input == null) {
            return null;
        }
        try {
            Class cls = input.getClass();
            Method method = cls.getMethod(iMethodName, iParamTypes);
            return method.invoke(input, iArgs);

        } catch (NoSuchMethodException ex) {
            throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' does not exist");
        } catch (IllegalAccessException ex) {
            throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' cannot be accessed");
        } catch (InvocationTargetException ex) {
            throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' threw an exception", ex);
        }
    }
The ysoserial tool allows for rolling serialized payloads that launch specific commands, such as executing calc.exe

Known Targets

Theoretically this vulnerability applies to any product that implements the InvokerTransformer class in a way consistent with that of the
Apache commons.collections library. Currently there is publically available proof of concept (poc) code samples for the following products:
Apache, WebSphere, WebLogic, JBoss AppServer, Jenkins continuous integration, and OpenNMS network management utilizing remote
method invocation (RMI) - such as in VMware's vCenter.

Business Impact

Compromise of a WebSphere server may lead to exposure of confidential information, loss of productivity and further network compromise.

Related Links