Analysis of CVE-2017-12628

This morning I spotted a tweet mentioning an “Apache James 3.0.1 JMX Server Deserialization” vulnerability, CVE-2017-12628, which caught my eye because I wrote a generic JMX deserialization exploit which is included in my RMI attack tool BaRMIe. A quick search for more details led to the security release announcement which states that the vulnerability can only be used for local privilege escalation and mentions an upgrade to a library. This sparked further interest because JMX uses RMI and RMI objects can be accessed remotely even when they are bound to localhost because Java binds the object reference to “”. BaRMIe exploits this using local port forwarding to attack objects that otherwise appear to be bound to local or internal IP addresses.


I span up a VM to run Apache James 3.0.0 (3.0.1 fixes the issue) and the first thing I noticed was the file “libs\commons-collections-3.2.1.jar”. We can use ysoserial to generate a POP gadget chain using this library to achieve arbitrary command execution through deserialization.

I started the James server by running “bin/run.sh”, then used netstat on the VM and nmap from my host machine to find that there was one Java RMI port listening externally on the VM.

Using BaRMIe to enumerate this service showed that it was an RMI object service rather than an RMI registry service, so BaRMIe couldn’t attack the service remotely.

Running nmap locally on the VM revealed that the Apache James RMI registry service was bound to I copied BaRMIe to the VM to enumerate this RMI registry and found that the externally facing RMI service was in fact the RMI object service for the JMX object.

Using BaRMIe’s attack mode with the generic JMX exploit and Commons Collections 3.2.1 payload it was possible to exploit this service to execute arbitrary commands leading to a local privilege escalation as advertised. In addition to this it’s also worth noting that, if the server uses an outdated Java runtime environment (<= 6u131, 7u121, or 8u112) then it is also vulnerable to the ysoserial RMI registry exploit.

Remote Exploit

The security release announcement states that this is a local privilege escalation vulnerability only, however, given that the JMX object is exposed externally, I figured this must be remotely exploitable.

Before I continue, I want to make it clear that this is remotely exploitable, however the remote exploit involves a significant network-based brute force attack.

For a quick and dirty proof of concept I used tcpdump on the VM to capture the traffic to the JMX object service whilst running the BaRMIe JMX exploit with the command “touch fooobaaar”.

Back on my host machine I used a quick and dirty Python script to replay the exploit packets.

Replaying the local attack remotely from my host machine was successful, proving that a remote exploit is possible.

As I suspected however, after restarting the Apache James service, this quick and dirty PoC no longer worked. I generated more packet captures for comparison and did some further testing and it appears to come down to some differences in the third outbound packet of the exploit. The following is the first 27 bytes of this packet:


The sections highlighted in blue were dynamic, however their values could be extracted from the previous response packet returned by the server. The orange highlighted section is the RMI object identifier which is generated when the server starts up. This value comes from the RMI registry service, which does only listen locally on the server. If an attacker can brute force or otherwise acquire this 8-byte value then a remote root command execution exploit is possible.


Adobe ColdFusion Deserialization RCE (CVE-2017-11283, CVE-2017-11238)

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.

Continue Reading


When Parameterized Queries Won’t Help

The usual recommendation for vulnerabilities that enable us to manipulate database queries (SQL injection) is to use a method such as prepared statements (parameterized queries) to query the database. Correct use of prepared statements prevents SQL injection attacks by ensuring that user input is properly handled by the database management system.

This post is about an edge case where a ‘safe’ database query was manipulated to attack an application.

Continue Reading


Java’s BaRMIe Back Door

A week ago I released a tool that I have been working on to enable security professionals to interact with applications that utilise Java’s Remote Method Invocation (RMI). This is the first in a series of blog posts covering RMI security and the tool I released, BaRMIe.

Source code for the tool can be found over at GitHub, along with binary releases. Slides for my talk at 44CON 2017 where I presented the results of my research can be found on SlideShare.


“RMI is outdated”

“Is that still a thing?”

“No one uses RMI anymore”

I first came across RMI during a pentest when nmap reported an “rmiregistry” service. I thought Remote Method Invocation alone sounded like something worth investigating further, but this service turned out to be really easy to attack. A few lines of code compiled against the RMI client’s JAR files was all it took and the service gave me unauthenticated access to the server’s file system (list, read, write, and delete files). Surprised by how easy that was, I wanted to find out how often RMI is used so insecurely and what else I could do with it.

RMI Security

My initial research quickly led to the discovery of many more instances of RMI being used insecurely. A key part of the problem seems to be that RMI was built to serve a specific purpose: invoking Java methods within another Java Virtual Machine (JVM). It was not built with security in mind. We can liken this to HTTP, except that HTTP is far more mature with a much larger user base. Over time a demand for security has led to HTTP evolving to support security. Modern web developers don’t even need to be particularly security aware because application frameworks bake security features in by default. RMI has none of this. Furthermore, the implementation of RMI is so simple and transparent that developers need not even be aware that they are interacting with a remote server.

The RMI protocol has no standard security features. Additional effort is required to incorporate security features like authentication and session management in front of classes/objects that are exposed over RMI.

Attacking RMI

My first attack against an RMI service required code compiled against the JAR files for the original client application. I wasn’t satisfied with that, I really wanted a zero-knowledge attack, which was one of the reasons I started researching the protocol. I later came across Adam Boulton’s presentation from AppSec USA 2008 – Security Assessing Java RMI – where he spoke about a zero-knowledge attack against RMI services. Unfortunately that attack relies on significant brute forcing over the network.

In the absence of a practical zero-knowledge attack, we need details of remote classes including method names, parameter types, and return types, in order to interact with an RMI service. The goal of BaRMIe is to build a set of common classes and methods that are exposed over RMI. Using these, we can enumerate an RMI endpoint to identify known classes and use them to attack the service.

BaRMIe supports three types of attacks against RMI services:

  1. Insecure Methods: RMI services often expose dangerous functionality that can be called directly provided the class/method details are known. Examples include unauthenticated file reading and writing.
  2. Deserialization via Object-type Parameters: RMI uses Java serialization making it a target for deserialization attacks. If a remote method accepts a parameter of the type ‘java.lang.Object’ then it can be used to deliver a deserialization payload.
  3. Deserialization via Illegal Method Invocation: Java does not verify that supplied method parameters are compatible with the actual method parameter type before deserializing the supplied method parameter. This weakness means that any non-primitive remote method parameter can be replaced with an arbitrary object using a TCP proxy, effectively triggering an illegal method call except that a deserialization payload is triggered before Java fails to execute the illegal method call.

Each of these attacks is facilitated using minimal RMI stub classes and interfaces that allow BaRMIe to call the target remote methods. BaRMIe also includes TCP proxying code to support deserialization attacks by enabling payloads to be injected at the network level.

In the next blog post on BaRMIe I’ll look at the technical aspects in more detail and cover some of the code and techniques used by BaRMIe to enumerate and attack RMI services. In the meantime, check it out!


Attacking Java Deserialization

Deserialization vulnerabilities are far from new, but exploiting them is more involved than other common vulnerability classes. During a recent client engagement I was able to take advantage of Java deserialization to gain a foothold on a server from where I was able to obtain root access to tens of servers spanning pre-production and production environments across multiple data centres. The vulnerability I discovered had previously survived multiple pentests and I would have missed it too if I hadn’t had prior exposure to Java (de)serialization.

Continue Reading