A recent analysis by Foxglove Security of a talk "AppSecCali: Marshalling Pickles" (video, slides) given by @frohoff and @gebl in January 2015, has confirmed multiple zero day, remotely executable exploits, for Java applications that deserialize objects from untrusted network sources and use libraries such as Apache Commons Collections, Groovy or Spring. Since a number of application servers transparently support deserialization of objects from data streams or through cookie values, it is trivial to pass exploit code through an HTTP request to a server which may be behind a firewall or scanners.

The proof of concept code against Apache Commons Collections 3.x is alleged to work against JBoss, Jenkins, Weblogic and WebSphere. Although this is not as trivial to exploit as the Apache Struts vulnerability in 2014, the code is as powerful and is likely to be found in many more places than currently detected.

The vulnerability stems from the fact that deserializing a Java object can instantiate any arbitrary classname with arbitrary data. In the case of Apache Commons Collections 3.x, this includes a Transformer class that allows conversion of an input object to another object type. This is called automatically by the deserialization routines, which allows the implementation to supply a completely different object. This is combined with the ChainedTransformer and ConstantTransformer to instantiate an object that creates an iConstant field in the serialized form that in turn uses an InvokerTransfomer instance to execute a single arbitrary method.

The proof of concept code has been tested by the author and verifies that with Apache Commons Collections 3.2.1 the vulnerability is real. The proof of concept is specifically developed for Unix systems (as it creates a file by executing Runtime.exec("touch /tmp/pwned" ); but in principle any command can be run on any operating system. The proof of concept is also specifically targeted at Apache Commons Collections 3.x; this is because Apache Commons Collections 4.x uses a different package namespace ( org.apache.commons.collections4 ). There are alternative exploits against Apache Commons Collections 4.x from the upstream repository along with Groovy 2.x (less than 2.4.4) and Spring 4.x.

Update: Guillaume Laforge contacted InfoQ to confirm that the exploit in Groovy was fixed in 2.4.4 under CVE-2015-3253 in GROOVY-7504 earlier this year, as its first release from the Apache Foundation. Since the issue is present in all older versions of Groovy, users are advised to upgrade to the current release from Apache to avoid this specific issue.

In all cases, the data supplied by the end user allows an arbitrary chain of objects to be constructed, which ultimately results in a sequence of bytes being deserialized resulting in code execution. By creating a payload class that has a class initialzier including a Runtime.exec() with a user-supplied command, and then wrapping that in a series of objects which when executed will result in the payload being given. Although the proof-of-concept uses a simple Runtime.exec() for the Apache Collections classes, an alternative attack against a JDK copy of com.​sun.​org.​apache.​xalan.​internal.​​xsltc.​trax.​TemplatesImpl (which is present in even the latest versions of OpenJDK 8) can also be exploited; this is demonstrated against the Spring attack through an auto-wiring mechanism and a type provider.

Unfortunately these vulnerabilities cannot be effectively protected against in an easy way. As well as being applicable to large numbers of Java applications (using or having Groovy on the class path, or Spring 4.x or Apache Commons Collections 3.x or 4.x), there is no easy way to prevent Object serialization from being used in a JVM, since it is used by potentially many Java operations.

As the proof of exploits show, a large number of Java application servers are vulnerable to remote code execution through the ability to send data via a network port; Jenkins, for example, uses Object serialization though the Jenkins CLI interface, and so is remotely vulnerable to anyone who can reach that port. CloudBees, one of the primary sponsors of Jenkins, have issued a security advisory recommending the immediate disablement of the Jenkins remote CLI service to prevent this vulnerability, and note that all CloudBees Jenkins on-premise installations are vulnerable. In the case of WebSphere, the attack is demonstrated through a SOAP request to the AdminService; and in fact, any javax.management port (which uses remote object serialization and has the buggy libraries) is potentially vulnerable. This is the same route used for the JBoss exploit, which posts a request to the JMXInvoker service. Any server running RMI is also potentially vulnerable - though in practice, RMI ports open to the internet are themselves a security smell.

As Foxglove Security notes, there isn't an effective way of determining what the objects are when being passed over the wire. Java serialized objects will start with 0xaced0005 , or if they are base64 encoded, rO0 . Looking for strings for classes used in the exploits can also be used to create signatures, since the class names are represented in UTF-8 strings in the classes:

org/​apache/​commons/​collections/​Transformer

org.​apache.​commons.​collections.​Transformer

org.​apache.​commons.​collections.​functors.​InvokerTransformer

org/​apache/​commons/​collections4/​functors/​InvokerTransformer

org.​apache.​commons.​collections4.​functors.​InvokerTransformer

org/​codehaus/​groovy/​runtime/​ConvertedClosure

org.​codehaus.​groovy.​runtime.​ConvertedClosure

com/​sun/​org/​apache/​xalan/​internal/​xsltc/​trax/​TemplatesImpl

com.​sun.​org.​apache.​xalan.​internal.​xsltc.​trax.​TemplatesImpl

There is no practical reason why any of these classes should be coming in through a serialized object through cookies or any other binary stream; it may be the case that these classes can't be deleted without affecting real functionality, but network monitoring software could examine the content of HTTP headers and cookies to look for sequences of these strings inside base64 encoded objects that are identified with rO0 . Unfortunately since responses may be compressed, or if using HTTP/2 may be coming through different pipelined requests.

Due to the number of places object deserialization can occur from networked data (or through custom network protocols) the vulnerabilities may be difficult to close. As with all security mechanisms, validating input is the key way of preventing exploits; in the case of Java Object deserialisation, it should not be used, instead preferring custom serialisation formats such as encoding through JSON or XML, or a specific library such as Protobuf or Thrift. Note that the SOAP WebSphere exploit uses XML to pass in a Base64 encoded payload which is then subject to serialization; so even using known protocols for data transfer does not avoid the potential for exploits.

Additional Update - November 10th

The Apache Commons team is using the ticket Collections-580 to address the issue in the 3.2 and 4.0 branches of commons-collection by disabling de-serialization of the class InvokerTransformer. Bernd Eckenfels, Committer, and Gary Gregory, Vice President of Apache Commons have published a blog post in which they state that "A to-do item being discussed is whether to provide programmatic enabling of the feature on a per-transformer basis." They also note that