CVE-2020-26217/26259 Xstream远程代码执行/任意文件删除漏洞分析
字数 2065 2025-08-19 12:42:04

XStream远程代码执行与任意文件删除漏洞分析教学文档

1. 漏洞概述

XStream是一个基于Java的库,可以将Java对象序列化为XML,反之亦然。2020年曝出的两个高危漏洞:

  • CVE-2020-26217: 远程代码执行漏洞
  • CVE-2020-26259: 任意文件删除漏洞

这两个漏洞在机制上极其相似,都是通过精心构造的XML payload触发XStream反序列化过程中的不安全操作。

2. 漏洞原理分析

2.1 XStream XML结构基础

XStream将Map对象序列化为XML时:

  • 每个Entry对象生成一个<entry>...</entry>元素
  • Entry中的key和value作为其子元素依次放置
  • Java对象的属性成为该对象节点的子元素

示例结构:

<entry>
  <key-class> <!-- key对象类型 -->
    <property1>value1</property1> <!-- key对象的属性 -->
    <property2>value2</property2>
  </key-class>
  <value-class>value</value-class> <!-- value值 -->
</entry>

2.2 漏洞触发流程

  1. 初始触发点:

    • XStream解析XML时遇到Map结构,会取出key-value对并put入Map
    • 在put操作时需要获取key的hash值,触发hashCode()方法调用
  2. 关键调用链:

    • 当key为jdk.nashorn.internal.objects.NativeString对象时
    • 调用NativeString.hashCode()getStringValue()this.value.toString()
    • this.value可控(通过XML中的value子元素设置)
  3. POC中构造的value:

    • 设置为com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data
    • 触发Base64Data.toString()get()
  4. Base64Data.get()中的两个利用点:

    baos.readFrom(is);  // 第一个利用点(CVE-2020-26217)
    is.close();         // 第二个利用点(CVE-2020-26259)
    

2.3 CVE-2020-26217 RCE漏洞分析

利用链:

  1. 设置DataSourceis属性为java.io.SequenceInputStream
  2. SequenceInputStream.read()nextStream()
  3. nextStream()中调用e.nextElement()
    • e设置为javax.swing.MultiUIDefaults$MultiUIDefaultsEnumerator
  4. MultiUIDefaultsEnumerator.nextElement()iterator.next().getKey()
    • iterator设置为javax.imageio.spi.FilterIterator
  5. FilterIterator.next()advance()iter.next()
    • iter设置为java.lang.ProcessBuilder
  6. filter.filter(elt)method.invoke(elt)
    • filter设置为javax.imageio.ImageIO$ContainsFilter
    • method设置为ProcessBuilder.start()

最终效果: 通过反射调用ProcessBuilder.start()实现任意命令执行。

2.4 CVE-2020-26259 任意文件删除漏洞分析

利用链:

  1. 设置DataSourceis属性为com.sun.xml.internal.ws.util.ReadAllStream$FileStream
  2. Base64Data.get()方法执行完readFrom(is)后调用is.close()
  3. ReadAllStream$FileStream.close()方法中:
    if (tempFile != null) {
        tempFile.delete();
    }
    
    • tempFile通过XML可控

最终效果: 删除服务器上任意指定文件。

3. POC对比分析

3.1 CVE-2020-26217 POC关键部分

<is class="java.io.SequenceInputStream">
  <e class="javax.swing.MultiUIDefaults$MultiUIDefaultsEnumerator">
    <iterator class="javax.imageio.spi.FilterIterator">
      <iter class="java.lang.ProcessBuilder">
        <command>
          <string>calc.exe</string>
        </command>
      </iter>
      <filter class="javax.imageio.ImageIO$ContainsFilter">
        <method>
          <name>start</name>
        </method>
      </filter>
    </iterator>
  </e>
</is>

3.2 CVE-2020-26259 POC关键部分

<is class="com.sun.xml.internal.ws.util.ReadAllStream$FileStream">
  <tempFile>/path/to/file</tempFile>
</is>

4. 漏洞修复建议

  1. 升级XStream到修复版本:

    • 1.4.15及以上版本修复了这两个漏洞
  2. 临时缓解措施:

    • 使用XStream的安全框架配置,禁止相关危险类的反序列化
    • 示例安全配置:
      XStream xstream = new XStream();
      xstream.denyTypes(new Class[]{
          java.io.SequenceInputStream.class,
          com.sun.xml.internal.ws.util.ReadAllStream$FileStream.class,
          javax.swing.MultiUIDefaults$MultiUIDefaultsEnumerator.class,
          javax.imageio.spi.FilterIterator.class,
          javax.imageio.ImageIO$ContainsFilter.class
      });
      

5. 漏洞挖掘思路

  1. 从反序列化过程中的可控点入手:

    • 对象属性可控
    • 方法调用链可控
  2. 寻找可利用的"终点":

    • 文件操作(删除、读写)
    • 命令执行
    • 反射调用
  3. 构造连接可控点到终点的调用链

  4. 这两个漏洞展示了同一漏洞点的不同利用方式:

    • baos.readFrom(is) → RCE
    • is.close() → 文件删除
    • 理论上其他类似的可控点也可能存在利用可能

6. 总结

这两个漏洞的关键在于:

  1. XStream在反序列化时完全信任XML输入
  2. 通过精心构造的XML可以控制反序列化过程和对象属性
  3. 利用Java内置类中的危险方法形成攻击链

防御此类漏洞的根本方法是:

  1. 不信任反序列化输入
  2. 严格限制可反序列化的类
  3. 及时更新依赖库到安全版本
XStream远程代码执行与任意文件删除漏洞分析教学文档 1. 漏洞概述 XStream是一个基于Java的库,可以将Java对象序列化为XML,反之亦然。2020年曝出的两个高危漏洞: CVE-2020-26217 : 远程代码执行漏洞 CVE-2020-26259 : 任意文件删除漏洞 这两个漏洞在机制上极其相似,都是通过精心构造的XML payload触发XStream反序列化过程中的不安全操作。 2. 漏洞原理分析 2.1 XStream XML结构基础 XStream将Map对象序列化为XML时: 每个Entry对象生成一个 <entry>...</entry> 元素 Entry中的key和value作为其子元素依次放置 Java对象的属性成为该对象节点的子元素 示例结构: 2.2 漏洞触发流程 初始触发点 : XStream解析XML时遇到Map结构,会取出key-value对并put入Map 在put操作时需要获取key的hash值,触发 hashCode() 方法调用 关键调用链 : 当key为 jdk.nashorn.internal.objects.NativeString 对象时 调用 NativeString.hashCode() → getStringValue() → this.value.toString() this.value 可控(通过XML中的value子元素设置) POC中构造的value : 设置为 com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data 类 触发 Base64Data.toString() → get() Base64Data.get()中的两个利用点 : 2.3 CVE-2020-26217 RCE漏洞分析 利用链 : 设置 DataSource 的 is 属性为 java.io.SequenceInputStream SequenceInputStream.read() → nextStream() nextStream() 中调用 e.nextElement() e 设置为 javax.swing.MultiUIDefaults$MultiUIDefaultsEnumerator MultiUIDefaultsEnumerator.nextElement() → iterator.next().getKey() iterator 设置为 javax.imageio.spi.FilterIterator FilterIterator.next() → advance() → iter.next() iter 设置为 java.lang.ProcessBuilder filter.filter(elt) → method.invoke(elt) filter 设置为 javax.imageio.ImageIO$ContainsFilter method 设置为 ProcessBuilder.start() 最终效果 : 通过反射调用 ProcessBuilder.start() 实现任意命令执行。 2.4 CVE-2020-26259 任意文件删除漏洞分析 利用链 : 设置 DataSource 的 is 属性为 com.sun.xml.internal.ws.util.ReadAllStream$FileStream 在 Base64Data.get() 方法执行完 readFrom(is) 后调用 is.close() ReadAllStream$FileStream.close() 方法中: tempFile 通过XML可控 最终效果 : 删除服务器上任意指定文件。 3. POC对比分析 3.1 CVE-2020-26217 POC关键部分 3.2 CVE-2020-26259 POC关键部分 4. 漏洞修复建议 升级XStream到修复版本: 1.4.15及以上版本修复了这两个漏洞 临时缓解措施: 使用XStream的安全框架配置,禁止相关危险类的反序列化 示例安全配置: 5. 漏洞挖掘思路 从反序列化过程中的可控点入手: 对象属性可控 方法调用链可控 寻找可利用的"终点": 文件操作(删除、读写) 命令执行 反射调用 构造连接可控点到终点的调用链 这两个漏洞展示了同一漏洞点的不同利用方式: baos.readFrom(is) → RCE is.close() → 文件删除 理论上其他类似的可控点也可能存在利用可能 6. 总结 这两个漏洞的关键在于: XStream在反序列化时完全信任XML输入 通过精心构造的XML可以控制反序列化过程和对象属性 利用Java内置类中的危险方法形成攻击链 防御此类漏洞的根本方法是: 不信任反序列化输入 严格限制可反序列化的类 及时更新依赖库到安全版本