A “gadget” is a snippet of code that exists in the application that can help an attacker to achieve a particular goal.
The attacker’s goal might simply be to invoke a method that will pass their input into another gadget. By chaining multiple gadgets together in this way, an attacker can potentially pass their input into a dangerous “sink gadget”, where it can cause maximum damage.
In the wild, many insecure deserialization vulnerabilities will only be exploitable through the use of gadget chains. Therefore, being able to construct gadget chains is one of the key aspects of successfully exploiting insecure deserialization.
Working with Pre-built Gadget Chains
There are several tools available that provide a range of pre-discovered chains that have been successfully exploited on other websites. Use these tools to both identify and exploit insecure deserialization vulnerabilities with relatively little effort.
One such tool for Java deserialization is ysoserial.
Note
In Java versions 16 and above, you need to set a series of command-line arguments for Java to run ysoserial. For example:
Not all gadget chains in ysoserial allow you to execute arbitrary code; some serve other purposes:
The URLDNS chain triggers a DNS lookup for a provided URL. It does not depend on a specific vulnerable library and works with any Java version, making it ideal for detection.
The JRMPClient chain also helps with detection by making the server attempt a TCP connection to a given IP address (not a hostname). This chain is useful in environments where all outbound traffic, including DNS, is blocked. You can test this by using both a local and an external IP address: if the response is quick for the local IP but delayed for the external one, it means the gadget chain triggered an attempted connection to the external, firewalled address.
Most languages that frequently suffer from insecure deserialization vulnerabilities have equivalent proof-of-concept tools. For example, for PHP-based sites you can use “PHP Generic Gadget Chains” (phpggc).
Lab: Exploiting Java Deserialization with Apache Commons
The original session cookie has the following format:
As we can see, it starts with rO0 so this is a serialized Java object.
First, try to use ysoserial within a Docker container:
URL-encode the output and add to any request as session cookie. Then, send the request and the response has the following error message:
This answer is not accepted.
After that, download sdk and install Java 11. Then, run the ysoserial-all.jar file with the following command:
The output is totally different from the one generated from Docker command.
URL-encode the output, place in any request and then send request.
Error message in response is different:
But this is the accepted answer.
Lab: Exploiting PHP Deserialization with a Pre-built Gadget Chain
Original decoded cookie:
The token field is the serialized object:
Try to change username to carlos and update the token field (without changing the signature):
The response has this error message:
It indicates that the framework is “Symfony Version: 4.3.6”.
Setup phpggc (build Docker image) and find the gadget chains:
Try to generate the serialized object with Symfony/RCE4’s gadget chain (and also encode it):
Next, we need to find the secret key for signing. Find the following code snippet from /my-account endpoint:
Access that page and found a secret key as a PHP variable:
Then, sign the encoded payload:
Build the cookie:
URL-encode, place into the request and then send it.
Working with Documented Gadget Chains
There may not always be a dedicated tool available for exploiting known gadget chains in the framework used by the target application. In this case, it’s always worth looking online to see if there are any documented exploits that you can adapt manually.
Lab: Exploiting Ruby Deserialization Using a Documented Gadget Chain