During my research into the Java Remote Method Invocation (RMI) protocol, the most common RMI service that I came across was Adobe ColdFusion’s Flex integration service which is used to support integration between Flash applications and ColdFusion components. A quick look at this service led to the discovery of two Java deserialization vulnerabilities, both leading to unauthenticated RCE in a service that runs under the local SYSTEM account by default.
Adobe released a security update on the 12th September 2017 for ColdFusion 11 and ColdFusion 2016 which can be installed through the ColdFusion Administrator application, however this update alone is not sufficient. Adobe ColdFusion comes bundled with its own Java runtime environment (JRE), which must be manually updated for the update to be effective.
The end-of-life ColdFusion 9 is also known to be affected, however no supported fix was available at the time of writing.
Update (13/10/2017): To clarify, this vulnerability affects the Java RMI service and does not affect HTTP(S) services exposed by ColdFusion.
The Vulnerability: RMI and java.lang.Object
The first thing I did when I started researching RMI was to write some code to enumerate RMI endpoints (which eventually became BaRMIe). The goal was to identify software that used RMI which I could investigate further.
I used Shodan to find targets for enumeration, then enumerated those targets using BaRMIe. The following class was the most commonly exposed:
The problem with RMI services is that we can’t interact with them without access to the relevant Java interface or stub class, so I downloaded a trial version of Adobe ColdFusion 2016 and installed it in a virtual machine. With ColdFusion installed I did a recursive grep over the installation directory for the above class name “DataServicesCFProxy” which guided me to the file “lib/cfusion.jar”. I opened this file up in JD-GUI to find the class (interface) listed above.
public abstract interface DataServicesCFProxy extends Remote
public abstract List fill(String paramString, Object paramArrayOfObject, Map paramMap) throws RemoteException;
public abstract List sync(String paramString, List paramList, Map paramMap) throws RemoteException;
public abstract Object get(String paramString, Map paramMap1, Map paramMap2) throws RemoteException;
public abstract Integer count(String paramString, Object paramArrayOfObject, Map paramMap) throws RemoteException;
public abstract boolean fillContains(String paramString, Object paramArrayOfObject, Object paramObject, Boolean paramBoolean, Map paramMap) throws RemoteException;
Each of the five methods of this interface accept arbitrary Java objects as parameters either directly or indirectly (List and Map can both contain arbitrary Java objects). The RMI protocol uses Java serialization for method parameters so each of these five methods can be used as an entry point for a Java deserialization attack by passing a specially crafted object to the method.
For a complete Java deserialization exploit we need two key components – the entry point (detailed above) and a payload. The payload consists of one or more classes with properties configured in such a way that some useful code is executed when the object is deserialized. For those not familiar with Java deserialization attacks, there’s an awesome tool called ysoserial which generates Java deserialization payloads using classes found in common Java libraries. Unfortunately the version of ColdFusion I had installed was not affected by any of the ysoserial payloads, and in fact Adobe released a security update in May 2016 which updated the bundled Apache Commons Collections library from version 3.2.1 to version 3.2.2, protecting ColdFusion against what is probably the best known Java deserialization payload.
A “java.io.InvalidClassException” stating that the local class was incompatible and listing the “serialVersionUID” of both the local and remote classes. Helpful! The serialVersionUID field of a class is usually generated automatically by Java and is updated whenever certain “incompatible” changes are made to the class. Depending on usage, however, it is entirely possible for these changes to be made without introducing an incompatibility.
I fired up a hex editor, loaded up the Mozilla Rhino payload bytes that I had generated using ysoserial, and searched for the local serialVersionUID listed in the exception. I modified the value to match the remote serialVersionUID and fired the payload off again whilst monitoring the network traffic with Wireshark. I had to repeat this process several times to fix all of the serialVersionUID values, but eventually I got this:
The other of the two vulnerabilities is simply that ColdFusion comes bundled with an outdated version of Java. The bundled Java version does not attempt to validate the type of objects received in an RMI Registry.bind() request before deserializing them. It also fails to check that the bind request came from localhost prior to deserializing the object. This presents another entry point for Java deserialization attacks.
- Security update for ColdFusion 11 and ColdFusion 2016 (https://helpx.adobe.com/security/products/coldfusion/apsb17-30.html)
- Further information for ColdFusion 11 (https://helpx.adobe.com/coldfusion/kb/coldfusion-11-update-13.html)
- Further information for ColdFusion 2016 (https://helpx.adobe.com/coldfusion/kb/coldfusion-2016-update-5.html)
- Adobe ColdFusion trial version download (https://www.adobe.com/support/coldfusion/downloads.html)
- BaRMIe RMI enumeration and attack tool (https://github.com/NickstaDB/BaRMIe)
- JD-GUI Java decompiler (http://jd.benow.ca/)
- ysoserial Java deserialization payload generator (https://github.com/frohoff/ysoserial)
- Shodan search engine for Internet-connected devices (https://www.shodan.io/)
- Attacking Java deserialization (https://nickbloor.co.uk/2017/08/13/attacking-java-deserialization/)
- ColdFusion May 2016 Commons Collections hotfix (https://helpx.adobe.com/uk/security/products/coldfusion/apsb16-16.html)
- Apache Commons Collections deserialization vulnerability (https://commons.apache.org/proper/commons-collections/security-reports.html)
- Versioning of serialized objects documentation (http://docs.oracle.com/javase/6/docs/platform/serialization/spec/version.html#6678)