Java Notes : Pentester Lab

date
Mar 4, 2024
slug
Java deserialization
status
Published
tags
Java
WebSec
summary
Java questions from pentester lab
type
Post

Java deserialization Basics

Java Serialize - 02

The technique involving reflection in this context is integral to accessing and modifying the private field command of the AnotherClass object.
Reflection in Java allows code to inspect and manipulate classes, interfaces, fields, and methods at runtime. In this exploit:
  1. Accessing Private Field: The Field object commandField is obtained using reflection. This allows access to the private field command of the AnotherClass class, which is otherwise inaccessible directly due to its visibility modifier.
  1. Setting Field Value: The setAccessible(true) method is called on commandField to enable access to the private field. Then, the set() method is used to modify the value of the command field in the gadget object. This allows us to inject the desired command to be executed upon deserialization.
  1. Executing Arbitrary Code: By setting the command field to the desired command ,we leverage reflection to manipulate the internal state of the object.
  1. During deserialization, when the readObject() method is invoked, the injected command is executed via Runtime.getRuntime().exec(), enabling arbitrary code execution on the target system.
source code :
We have a clear target : readObject(ObjectInputStream stream)
solver :

Java Serialize - 03

In this challenge, we need to leverage a java.util.HashMap that will call the method hashCode() when it gets deserialized.
This works because the method readObject() of java.util.HashMap() calls the method hash() on key :
And the method hash() will call hashCode() on the Object key:

java Serialize - 04

In this challenge, you need to leverage a java.util.PriorityQueue that will call the method compare() when it gets deserialized. Your "object generator" should look something like:
This works because the method readObject() of java.util.PriorityQueue calls the method heapify():
The method heapify() calls siftDownUsingComparator() when a comparator is set. And this method calls the method compare() of the conparator (cmp):

Java Serialize - 05

in this challenge, you need to leverage a java.util.PriorityQueue that will call the method compare() when it gets deserialized.
 
There is a small difference with the previous challenge. Here the compare method throws a RuntimeException if the command fails during the creation of the gadget. There are two ways to bypass this:
  • You can create the right file on your system as a symbolic link for example
  • You can use Java to avoid running the command locally (the recommended way to increase how much you learn).
To do this in Java, clone the code of ysoserial and look at the following files: src/main/java/ysoserial/payloads/BeanShell1.java 
These files should give you everything we need to create a java.util.PriorityQueue with the malicious elements in it with running the compare() method locally. The AnotherClass is a custom comparator that implements both Comparator and Serializable interfaces. It has a compare(String a, String b) method that tries to execute the command provided in the string a and returns the exit value of the command. If the command execution fails, it throws a RuntimeException. The Exploit class creates a PriorityQueue with AnotherClass as the comparator, adds two String objects to the queue to ensure compare() is called during deserialization, serializes the queue to a byte array, and then encodes the byte array to a base64 string.

© Amine Elsassi 2021 - 2024