0


Weblogic安全漫谈(四)

黑名单机制必然会推动两种研究方向的发展:一是挖掘不在黑名单的新组件,是为绕过规则;二是发掘检查的盲区,是为绕过逻辑。

CVE-2020-14756

二次反序列化具有对抗检查逻辑的天生丽质,在CVE-2018-2893中就有利用字节数组和反射重建类两种方式。找找还有没有

readObject

Class.forName

的路子:

图片

readUnsignedByte

读到的

nType

为9或10时会进入

readXmlSerializable

readExternalizableLite

分支。

图片

上述两个方法均通过自身

loadClass

方法加载类,最终由

Class.forName

获取类并返回。

图片

图片

  • readXmlSerializable方法获取类后继续进行XML解析,是另一个XXE漏洞。
readExternalizableLite

方法获取类后继续调用

readExternal

反序列化,不受黑名单限制,进而引出两个问题:

  1. ExternalizableHelper自身没有实现Serializable接口,一定有什么地方调用它的readObject
  2. loadClass加载后强转为了ExternalizableLite类型,它哪些满足readExternal参数要求的子类可以被用作sink

图片

找到

PermissionInfo#readExternal

会调用

ExternalizableHelper#readCollection

进而调用

readObject

作为链首。

图片

继续找到

TopNAggregator$PartialResult

及其父类

SortedBag

图片

readExternal

方法会调用父类的

instantiateInternalMap

方法将

comparator

封装进

TreeMap

,随后在

add

方法中调用

map.put

时就会触发

compare

,进而连上以前的链尾。与

PriorityQueue

的作用相同,只是绕这么一圈过掉了黑名单。

图片

重写

PermissionInfo#writeExternal

按照以前的套路一步步构造payload打出去就行。

图片

extract:95, MvelExtractor (com.tangosol.coherence.rest.util.extractor)

extract:112, ReflectionExtractor (com.tangosol.util.extractor)
extract:105, ChainedExtractor (com.tangosol.util.extractor)

// extract:96, MultiExtractor (com.tangosol.util.extractor)

compare:143, AbstractExtractor (com.tangosol.util.extractor)
compare:416, SortedBag$WrapperComparator (com.tangosol.util)
compare:1295, TreeMap (java.util)
put:538, TreeMap (java.util)
add:152, SortedBag (com.tangosol.util)
add:270, TopNAggregator$PartialResult (com.tangosol.util.aggregator)
readExternal:299, TopNAggregator$PartialResult (com.tangosol.util.aggregator)
readExternalizableLite:2345, ExternalizableHelper (com.tangosol.util)
readObjectInternal:2661, ExternalizableHelper (com.tangosol.util)
readObject:2606, ExternalizableHelper (com.tangosol.util)
readCollection:2131, ExternalizableHelper (com.tangosol.util)
readExternal:190, PermissionInfo (com.tangosol.net.security)
readExternalData:2118, ObjectInputStream (java.io)
readOrdinaryObject:2067, ObjectInputStream (java.io)
readObject0:1573, ObjectInputStream (java.io)

漏洞作者用了

AttributeHolder

作为链首,主要是

writeExternal

的逻辑友好,不用重写构造起来更加方便。

图片

CVE-2020-14644

按照同样的思路找

ClassLoader.defineClass

的路子:

图片

com.tangosol.internal.util.invoke.RemoteConstructor#readResolve

会触发

newInstance

并调用

com.tangosol.internal.util.invoke.RemotableSupport#realize

图片

随后会经过多个方法处理后最终进入

ClassLoader.defineClass

,可以看到关键是最开始传入

RemoteConstructor

构造方法的

ClassDefinition

对象。

图片

对于字节码相关的处理函数就是获取构造方法,之后会被用于创建实例化对象,真正的关键变为了

ClassDefinition

构造方法的

ClassIdentity

对象。

图片

图片

图片

看到

ClassIdentity

构造函数会将包名、类名、以及md5哈希分别存入三个属性,上文中

RemotableSupport

加载字节码时,会以这个

getName

方法获取到的类名为准。

图片

梳理一下整体逻辑:

  1. 将要加载的类喂给ClassIdentity构造函数
  2. ClassDefinition构造函数接收第一步创建的ClassIdentity对象、以及要加载的类字节码
  3. RemoteConstructor构造函数接收第二步创建的ClassDefinition对象、以及要加载的类构造函数的参数类型数组

反序列化时就会触发类加载,要解决的核心问题是

ClassIdentity

构造函数把传给

ClassLoader.defineClass

的类名作了变化,我们也要对字节码中的类名作相应的格式变化,用asm或者javassist或者手动创建类对象都行。

图片

defineClass:181, RemotableSupport (com.tangosol.internal.util.invoke)
realize:137, RemotableSupport (com.tangosol.internal.util.invoke)
newInstance:120, RemoteConstructor (com.tangosol.internal.util.invoke)
readResolve:231, RemoteConstructor (com.tangosol.internal.util.invoke)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
invokeReadResolve:1260, ObjectStreamClass (java.io)
readOrdinaryObject:2078, ObjectInputStream (java.io)
readObject0:1573, ObjectInputStream (java.io)

CVE-2021-2135

早期对于14756的修复方法之一就是在

ExternalizableHelper#readExternalizableLite

loadClass

后,判断输入流属于

ObjectInputStream

就进入检查流程。这就是把找一条非

ObjectInputStream

输入流就能绕过写在脸上了。

图片

extract:95, MvelExtractor (com.tangosol.coherence.rest.util.extractor)

extract:112, ReflectionExtractor (com.tangosol.util.extractor)
extract:105, ChainedExtractor (com.tangosol.util.extractor)

// extract:96, MultiExtractor (com.tangosol.util.extractor)

compare:79, AbstractExtractor (com.tangosol.util.extractor)
compare:416, SortedBag$WrapperComparator (com.tangosol.util)
compare:1295, TreeMap (java.util)
put:538, TreeMap (java.util)
add:152, SortedBag (com.tangosol.util)
add:268, TopNAggregator$PartialResult (com.tangosol.util.aggregator)
readExternal:297, TopNAggregator$PartialResult (com.tangosol.util.aggregator)
readExternalizableLite:2265, ExternalizableHelper (com.tangosol.util)
readObjectInternal:2579, ExternalizableHelper (com.tangosol.util)
deserializeInternal:3098, ExternalizableHelper (com.tangosol.util)
fromBinary:334, ExternalizableHelper (com.tangosol.util)
getKey:56, SimpleBinaryEntry (com.tangosol.internal.util)
toString:153, SimpleBinaryEntry (com.tangosol.internal.util)
equals:392, XString (com.sun.org.apache.xpath.internal.objects)
equals:3415, Base (com.tangosol.util)
put:213, LiteMap (com.tangosol.util)
readMap:1900, ExternalizableHelper (com.tangosol.util)
readExternal:190, ConditionalPutAll (com.tangosol.util.processor)
readExternalizableLite:2265, ExternalizableHelper (com.tangosol.util)
readObjectInternal:2579, ExternalizableHelper (com.tangosol.util)
readObject:2524, ExternalizableHelper (com.tangosol.util)
readObject:2502, ExternalizableHelper (com.tangosol.util)
readExternal:406, AttributeHolder (com.tangosol.coherence.servlet)
readExternal:371, AttributeHolder (com.tangosol.coherence.servlet)
readExternalData:2118, ObjectInputStream (java.io)
readOrdinaryObject:2067, ObjectInputStream (java.io)
readObject0:1573, ObjectInputStream (java.io)

本文转载自: https://blog.csdn.net/moresec/article/details/135403193
版权归原作者 杭州默安科技 所有, 如有侵权,请联系我们删除。

“Weblogic安全漫谈(四)”的评论:

还没有评论