Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
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.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
codeql-workshop-cve-2021-21380 — Um workshop de CodeQL abordando CVE-2021-21380 | Kitploit
Ferramentas/GitHubGitHub/rvermeulen/codeql-workshop-cve-2021-21380
Análise EstáticaAnálise de VulnerabilidadesAnálise de CódigoSegurança WebAprendizado e EducaçãoLabs e Prática
GitHubrvermeulen/codeql-workshop-cve-2021-21380

codeql-workshop-cve-2021-21380

Um workshop de CodeQL abordando CVE-2021-21380

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 →
Ver Repositório
125há 1 anoAinda não revisado
Compartilhar

Workshop CodeQL para Java: Encontrando uma injeção de SQL

Neste workshop, usaremos raciocínio sintático e semântico para encontrar uma injeção de SQL no componente de avaliação da plataforma XWiki documentada pela CVE-2021-21380

Conteúdo

  • Workshop CodeQL para Java: Encontrando uma injeção de SQL
    • Conteúdo
    • Pré-requisitos e instruções de configuração
      • Na sua máquina local
        • Instalação
        • Etapas de configuração
    • Workshop
      • Aprendizados
      • Enunciado do problema
      • Exercícios
        • Exercício 1
        • Intermezzo 1
        • Exercício 2
        • Exercício 3
        • Intermezzo 2
        • Exercício 4
        • Exercício 5
        • Intermezzo 3
        • Exercício 6
        • Exercício 7
        • Exercício 8
    • O que vem a seguir?

Pré-requisitos e instruções de configuração

Na sua máquina local

Complete esta seção antes do workshop, se possível.

Instalação

  • Instale o Visual Studio Code.

  • Instale a extensão CodeQL para Visual Studio Code.

  • Você não precisa instalar o CLI do CodeQL: a extensão cuidará disso para você.

  • Clone este repositório:

    root@kitploit:~
    git clone https://github.com/advanced-security/codeql-workshop-cve-2021-21380.git
    

Etapas de configuração

  • Importe o banco de dados CodeQL a ser usado no workshop:
    • Clique com o botão direito no arquivo xwiki-platform-CVE-2021-21380.zip na exibição do Explorer e selecione o comando CodeQL: Set Current Database.
    • O banco de dados aparecerá na exibição de bancos de dados CodeQL, acessível pelo ícone QL na Barra de Atividades.
  • Instale as dependências para analisar código Java e executar os testes dos exercícios e soluções.
    • Na Paleta de Comandos (Cmd/Ctrl+Shift+P), pesquise e execute o comando CodeQL: Install Pack Dependencies.
    • Na parte superior da janela do VS Code, digite github na caixa para filtrar a lista.
    • Marque a caixa ao lado de cve-2021-21380-exercises, cve-2021-21380-exercises-tests, cve-2021-21380-solutions e cve-2021-21380-solutions-tests.
    • Clique em OK/Enter.
  • Valide se tudo funciona como esperado executando os testes das soluções.
    • Abra a exibição de testes e pressione executar testes (o ícone de reprodução é exibido ao passar o mouse sobre as soluções) ao lado do item de soluções na árvore.

Workshop

Aprendizados

O workshop é dividido em vários exercícios que apresentam o suporte da linguagem QL para Java e termina com uma consulta final para encontrar a injeção de SQL conhecida. Nestes exercícios, você aprenderá:

  • Como raciocinar sobre informações sintáticas.
  • Como raciocinar sobre informações semânticas.
  • Explorar o suporte da linguagem QL para Java para expressar padrões.
  • Explorar como reutilizar e estender modelagens existentes.
  • Usar múltiplos blocos de construção para compor a consulta final.

Enunciado do problema

Neste workshop, procuraremos por vulnerabilidades de injeção de SQL conhecidas no componente da API de avaliações do XWiki Platform. Essas vulnerabilidades podem ocorrer em aplicações quando informações controladas por um usuário externo chegam ao código da aplicação que constrói e executa uma consulta SQL de forma insegura.

A injeção de SQL conhecida discutida neste workshop é revisada em GHSA-79rg-7mv3-jrr5 no GitHub Advisory Database. Para encontrar a injeção de SQL e possíveis variantes, vamos resolver os seguintes subproblemas:

  • Identificar a origem das informações não confiáveis e modelá-la em QL.
  • Identificar o sink, o método que executa consultas SQL, e modelá-lo em QL.
  • Combinar as soluções acima para determinar se há um fluxo de informações entre a fonte e o sink usando taint tracking.

Exercícios

Nos primeiros exercícios, raciocinaremos sobre informações sintáticas, usando a Árvore Sintática Abstrata (AST), para identificar:

  • o método descrito no aviso de segurança para construir entendimento sobre a vulnerabilidade
  • parâmetros que contêm dados não confiáveis, nossas fontes
  • chamadas de método que aceitam instruções SQL, nossos sinks

Exercício 1

Encontre todos os métodos com o nome getAverageRating e o tipo declarante no programa completando a consulta exercise1.ql

Dicas
  • O módulo java fornece uma classe Method para raciocinar sobre métodos em um programa.
  • A classe Method fornece os predicados membros getName e hasName para raciocinar sobre o nome de um método.
  • A classe Method fornece o membro getDeclaringType para raciocinar sobre o tipo que declara o método.

Uma solução pode ser encontrada na consulta exercise1.ql

Intermezzo 1

Uma solução para o exercício 1 retorna uma lista de métodos. Alguns são definidos em uma interface chamada RatingsManager e outros são definidos nas classes AbstractRatingsManager e RatingsScriptService.

A partir das informações retornadas pela consulta e da documentação de componentes do XWiki podemos deduzir que:

  • O XWiki usa um design orientado a componentes para permitir extensões e customizações.
  • O método vulnerável faz parte de um componente.
  • Um componente consiste em uma interface, anotada com Role, e uma implementação anotada com Component.
  • Um componente que estende ScriptService é tornado acessível a páginas wiki por meio de scripts.

Exercício 2

Encontre todas as classes anotadas com a anotação Component completando a consulta exercise2.ql. Observe que o nome totalmente qualificado do tipo da anotação é org.xwiki.component.annotation.Component.

Dicas
  • O /tipo de domínio da classe/, a interseção de seus supertipos, pode ser acessado usando a palavra-chave this no /predicado característico/.
  • A classe Class fornece um método getAnAnnotation para obter anotações associadas.
  • A classe Annotation fornece o predicado membro getType para raciocinar sobre seu tipo.
  • A classe Type fornece os predicados membros getName e hasName para raciocinar sobre o nome de um tipo.
  • A classe RefType, que representa classes e interfaces, fornece os predicados membros getQualifiedName e hasQualifiedName para raciocinar sobre o nome totalmente qualificado do reftype.

Uma solução pode ser encontrada na consulta exercise2.ql

Exercício 3

Encontre todos os componentes que implementam a interface ScriptService completando a consulta excercise3.ql

Dicas
  • O tipo Class fornece o predicado membro getASuperType para raciocinar sobre os supertipos de uma classe, ou seja, os tipos que ela extends ou implements.

Uma solução pode ser encontrada na consulta exercise3.ql

Intermezzo 2

Neste ponto, identificamos sintaticamente os métodos que podem ser chamados por um usuário e cujos parâmetros consideraremos como fontes de dados não confiáveis mais adiante no workshop.

No próximo exercício, vamos investigar e identificar possíveis sinks. A partir dos resultados do exercício 1, podemos deduzir que uma das implementações chama o método getAverageRatingFromQuery. Usando uma consulta semelhante, podemos encontrar os tipos declarantes de getAverageRatingFromQuery, o que nos permite estabelecer que a implementação na classe AbstractRatingsManager constrói uma instrução SQL que é passada para o método search.

O método search é implementado em uma dependência e, portanto, sua implementação não está disponível. Nos próximos exercícios, usaremos as informações de tipo disponíveis para identificar essa chamada ao método search e seu tipo declarante.

Exercício 4

Encontre todas as chamadas de método para o método search e identifique seu tipo declarante completando a consulta exercise4.ql

Dicas
  • O tipo MethodCall nos fornece os meios para raciocinar sobre chamadas de método.
  • O tipo MethodAcccess fornece o predicado membro getMethod para raciocinar sobre o alvo de uma chamada de método.

Uma solução pode ser encontrada na consulta exercise4.ql

Exercício 5

Encontre todas as chamadas de método para métodos declarados pela interface XWikiStorageInterface (com o nome qualificado com.xpn.xwiki.store.XWikiStoreInterface) completando a consulta exercise5.ql

Dicas
  • A palavra-chave instanceof pode ser usada para declarar que um valor pertence ao conjunto de valores representados por um tipo. Por exemplo, para identificar todas as chamadas a métodos de interface:

    root@kitploit:~
    import java
    
    from MethodCall ma
    where ma.getMethod.getDeclaringType() instanceof Interface
    select ma
    

Uma solução pode ser encontrada na consulta exercise5.ql

Intermezzo 3

Neste ponto, descrevemos sintaticamente possíveis fontes e sinks usando QL. Para determinar se as informações fluem entre esses pontos no programa, vamos analisar semanticamente o programa usando taint tracking. As bibliotecas padrão das linguagens que suportamos fornecem dois mecanismos de fluxo de dados:

  1. O módulo DataFlow suporta fluxo de informações com preservação de valores.
  2. O módulo TaintTracking suporta fluxo de informações mesmo que os valores sejam modificados.

Este último é de interesse, pois em vulnerabilidades de injeção, como injeção de SQL, é comum que dados não confiáveis se tornem parte de uma instrução maior sobre a qual uma ação é executada.

Neste workshop, vamos reutilizar uma configuração existente de taint tracking para injeção de SQL e estendê-la com nossas fontes e sinks modelados para encontrar a injeção de SQL. Para entender como podemos estender a configuração, começamos observando a definição da configuração abaixo.

root@kitploit:~
class QueryInjectionFlowConfig extends TaintTracking::Configuration {
  QueryInjectionFlowConfig() { this = "SqlInjectionLib::QueryInjectionFlowConfig" }

  override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }

  override predicate isSink(DataFlow::Node sink) { sink instanceof QueryInjectionSink }

  override predicate isSanitizer(DataFlow::Node node) {
    node.getType() instanceof PrimitiveType or
    node.getType() instanceof BoxedType or
    node.getType() instanceof NumberType
  }

  override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
    any(AdditionalQueryInjectionTaintStep s).step(node1, node2)
  }
}

Tanto o predicado isSource quanto o isSink usados pela configuração para identificar esses locais do programa usam a palavra-chave instanceof que vimos antes. Tanto a classe RemoteFlowSource quanto a QueryInjectionSink são classes abstract. Este é um padrão comum que você encontrará nas bibliotecas padrão, e esse padrão nos permite estender o conjunto de valores representados pelas classes RemoteFlowSource e QueryInjectionSink.

Uma class QL que estende uma abstract class não refina o conjunto de valores representados pela superclasse, mas adiciona os valores representados pela subclasse à superclasse. Nos próximos exercícios, vamos implementar essas subclasses e construir nossa consulta final.

Exercício 6

Estenda o conjunto de valores de RemoteFlowSource com os parâmetros dos métodos públicos das classes de componente identificadas no exercício 3, completando a consulta exercise6.ql.

Dicas
  • A palavra-chave instanceof pode ser usada para declarar que um valor pertence ao conjunto de valores representados por um tipo. Por exemplo, para identificar todas as chamadas a métodos de interface:

    root@kitploit:~
    import java
    
    from MethodCall ma
    where ma.getMethod.getDeclaringType() instanceof Interface
    select ma
    

Uma solução pode ser encontrada na consulta exercise6.ql

Exercício 7

Estenda o conjunto de valores de QueryInjectionSink com os argumentos das chamadas aos métodos da interface de armazenamento identificada no exercício 5, completando a consulta exercise7.ql

Dicas
  • A fórmula exists permite a introdução de variáveis temporárias sobre as quais se pode raciocinar no escopo do exists.

    O exemplo a seguir usa a expressão exists para reduzir o conjunto de métodos aos métodos que são chamados.

    root@kitploit:~
    from Method m
    where m.hasName("foo") and exists(MethodCall ma | ma.getMethod() = m)
    select m
    
  • A classe MethodCall fornece o predicado membro getQualifer para raciocinar sobre o qualificador do acesso ao método.

Uma solução pode ser encontrada na consulta exercise7.ql

Exercício 8

Combine suas soluções do exercício anterior em uma solução final completando a consulta exercise8.ql.

Uma solução pode ser encontrada na consulta exercise8.ql

O que vem a seguir?

  • A consulta inclui um módulo para modelar partes do framework XWiki. Refatore isso para um arquivo de módulo próprio e use-o em sua consulta.
  • Limitamos nossa fonte de dados não confiáveis a componentes de script service. Veja como expandir isso com outras fontes.
  • Para o sink, nos limitamos ao uso direto do XWikiStoreInterface. Expanda o sink para incluir usos diretos de implementações da interface. A classe Class fornece o predicado membro extendsOrImplements e a classe Method fornece o predicado membro overridesOrInstantiates que podem ser úteis.
  • Use a definição de fontes para encontrar usos interessantes de dados não confiáveis com a consulta 'Untrusted data passed to external API'
Baixar ferramenta