Insecure Deserialization
Last updated
Last updated
Serialization is a method of creating binary form from objects. (Useful for transportation and storing information)
Serialized data can be deserialized - transformed from binary form to object which can cause unexpected bahaviours in some cases.
order to better understand deserialization I recommend the following exercise on Pentester Lab:
Among many other functions Java uses ObjectInputStream.readObject() in order to deserialize objects.
readObject() alone is just responsible for creating (instantiating) the serialized object and not for checking what kind of object it is.
Not checked object / Invalid object check = Insecure Deserialization
In order to be able to serialize and then de-serialize an object, some conditions have to be met:
An object to be serialized has to implement Serializable interaface
All the classes to be deserialized have to be present on deserializing classpath. Serialization concerns state of an object, but the definition has to be already present on the deserializing side.
Application below serializes and deserializes Java Objects. It is created by me - I highly encourage you to create your own version of this application since in order to be the best in finding this type of vulnerability we have to create strong fundamentals of this topic in our minds.
Deserialization exploits work like a method which is executed upon instantiating an object.
Look for readObject() functions. They are potential sinks of deserialization vulnerability (of course, if you are able to deliver user-controlled data to them). Even if someone calls a serie of checks after the object is “read”, it’s already too late.
Often software vendors build own wrappers for readObject, e.g. consider a function vendorDeserialize() being present in source code but using ois.readObject() under the hood.
In order to be able to test deserialization vulnerability, you have also to find a way to deliver the serialized data to the found insecure code during SAST.
Usually, easiest way to spot serialization being in use is to inspect application traffic.
Java serialized objects have a specific signature which easily allow to identify them, which is binary 0xaced0005. It translates to base64 rO0AB.
Serialized java object might be wrapped into any kind of encryption or encoding, thus when dealing with Java application it is worth to dig deeply into any encoded data being sent. That involves e.g. TCP traffic, or HTTP channels like POST parameters, Cookies and Headers.
One of the fields is SerialUID which is an unique class version identifier. This is something that might cause your payloads to fail, and it’s described later on in “troubleshooting” section along with another issues.
YsoSerial consists of modules named payloads. Each payload generates a serialized object which once instantiated, invokes some kind of action.
The classes that have some specific features making them usable as gadgets are rarely native java classes. They are often more sophisticated objects, which are parts of some commonly used libraries.
Existence of serialized objects in communication does not mean that application is vulnerable - this can be as well properly designed serialization.
Source: https://afine.com/testing-and-exploiting-java-deserialization-in-2021
Useful resource:
If there’s any data you suspect of being a serialized Java object, you can use tool named tool to inspect it.
If you look at source code in , you will find comments indicating proper usage of each payload module.
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 , 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:
There are two ysoserial payloads dedicated to exploitation of RMI Registries. However, after .
Also, JRMPListener can be used to host a payload ona rogue RMI Registry to be deserialized, and JRMPClient can be used against the target to connect back to attacker’s registry and deserialize the payload. This is used in e.g. Weblogic CVE-2018–2628 . The listener can be opened using command
Object Lookup is a Java feature related to . In short, it allows for retrieving (“”) 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.
A very powerful payload in terms of blind testing. DNS Lookup is a feature of Java when handling serialized URL object . It’s powerful because that payload also does not require any additional libraries to work. Use it as:
If you do not have Burp Pro, you can use to receive the DNS interaction. Note, that this payload is also designed just to detect arbitrary serialization, the DNS resolution does not add any significant impact (the most significant I can think of is revealing an internal host IP)
is supposed to work in a similar manner as FileUpload, with a difference — it also runs the uploaded script.
— It should rely on executing EL expression, however during experiments.
All other payloads, listed below, are designed for direct Code Execution. Note, that on modern Java you will have 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.
Native JDK DoS PoC relies on a recursive HashSet. You can find the original one , I just changed it a bit so it generates a serialized payload instead of deserializing itself instantly. You can download modified version of this . The serialized payload, when sent to vulnerable TCP Server, causes resource consumption to spike. We generate the dos payload: