Demystify a Java gadget chain to exploit insecure deserialization
Site migration in process .. Drafting notes..
I was always curious about how the actual remote code execution occurs during the Insecure Deserialization process. So I thought of giving a try to understand the known harmful gadgets
from commons-collections-3.2.2.jar
and develop the entire chain from scratch.
We need to use property oriented programming
to build a RCE gadget
from the scratch.
Component / Classes Used to build the gadget
- Default JRE System Libraries: HashMap
commons-collections-3.2.2.jar
:- ChainedTransformer
- LazyMap
- TiedMapEntry
- HashBag
1. Command Execution using Runtime
object directly
We can use the Java Runtime
object and its exec()
method to execute any system
commands.
- for example, running the
mate-calculator
in linux.
2. Command Execution using Reflection API and Runtime
object
- Java
Reflection API
is used toexamine
ormodify
thebehavior
of methods, classes, interfaces atruntime
. - Through reflection API, we can invoke any method at
runtime
viainvoke()
function.- Here, we are trying to invoke
getRuntime()
method to get aRuntime
object.
- Here, we are trying to invoke
3. Command Execution using ConstantTransformer
and InvokerTransformer
together
Before directly jump into the Constant Transformer
and InvokerTransformer
, first understand the Transformer
class and the transform()
method.
Transformer
- It transforms an input object to an output object through
transform()
method. - It doesn’t change the input object.
- It is mainly used for:
type conversion
,extracting
parts of an object.
For example, we can create a class MyReverse
by implementing the Transformer
interface and transform()
method.
- Here, in
transform()
method, we specify how to reverse aString
type object.
When we call the transform()
method via passing the argument of a String
type object, it reverses the string.
The return type of the
transform()
method isObject
therefore it can return any type of object.
ConstantTransformer
In contrast to the Transformer
class, it always returns the same object
that specified during initialization
.
- If we Initialize a
ConstantTransformar
withRuntime.class
and can call thetransform()
method withany object
(for example,HashSet
), we will always get theRuntime.class
type object.
InvokerTransformer
- During initialization, it takes a
method name
with optional parameters. - On
transform
, it calls that method for the object provided with the parameters.