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 漏洞触发流程
-
初始触发点:
- 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子元素设置)
- 当key为
-
POC中构造的value:
- 设置为
com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data类 - 触发
Base64Data.toString()→get()
- 设置为
-
Base64Data.get()中的两个利用点:
baos.readFrom(is); // 第一个利用点(CVE-2020-26217) is.close(); // 第二个利用点(CVE-2020-26259)
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$ContainsFiltermethod设置为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()方法中: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. 漏洞修复建议
-
升级XStream到修复版本:
- 1.4.15及以上版本修复了这两个漏洞
-
临时缓解措施:
- 使用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. 漏洞挖掘思路
-
从反序列化过程中的可控点入手:
- 对象属性可控
- 方法调用链可控
-
寻找可利用的"终点":
- 文件操作(删除、读写)
- 命令执行
- 反射调用
-
构造连接可控点到终点的调用链
-
这两个漏洞展示了同一漏洞点的不同利用方式:
baos.readFrom(is)→ RCEis.close()→ 文件删除- 理论上其他类似的可控点也可能存在利用可能
6. 总结
这两个漏洞的关键在于:
- XStream在反序列化时完全信任XML输入
- 通过精心构造的XML可以控制反序列化过程和对象属性
- 利用Java内置类中的危险方法形成攻击链
防御此类漏洞的根本方法是:
- 不信任反序列化输入
- 严格限制可反序列化的类
- 及时更新依赖库到安全版本