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 — Dê os primeiros passos no CodeQL para Python escrevendo uma consulta para encontrar o CVE-2024-32022 | Kitploit
Ferramentas/GitHubGitHub/sylwia-budzynska/codeql-workshop
Análise EstáticaAnálise de VulnerabilidadesAnálise de CódigoAprendizado e EducaçãoRecursos CuradosTrilhas e CursosLabs e Prática
GitHubsylwia-budzynska/codeql-workshop

codeql-workshop

Dê os primeiros passos no CodeQL para Python escrevendo uma consulta para encontrar o CVE-2024-32022

Ver Repositório
128há 1 mêsAinda não revisado

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 →
Compartilhar

Encontrando vulnerabilidades com CodeQL

Workshop original por Sylwia Budzynska

Pré-requisitos • Recursos • Workshop

  • Para quem é: Engenheiros de Segurança, Pesquisadores de Segurança, Desenvolvedores.
  • O que você vai aprender: Aprenda a usar o CodeQL para exploração de código e para encontrar problemas de segurança.
  • O que você vai construir: Crie uma consulta CodeQL baseada em um advisory de segurança para encontrar uma injeção de comando.

📣 Pré-requisitos

Você pode escolher entre duas opções para executar os exercícios do workshop:

  • Opção A: Instalação local (Usando o VS Code - o CodeQL é executado localmente na sua máquina)
  • Opção B: GitHub Codespace (Usando um navegador ou o VS Code - o CodeQL é executado remotamente em um GitHub Codespace baseado em Linux na nuvem)

Opção A: Instalação local

Use uma instalação local do CodeQL para trabalhar nos exercícios do workshop.

Pré-requisitos

  • Visual Studio Code (VS Code) e git instalados na sua máquina local.

Instruções

  1. Instale a extensão do CodeQL para VS Code
  2. Execute no terminal:```bash git clone https://github.com/sylwia-budzynska/codeql-workshop cd codeql-workshop git submodule init git submodule update --recursive --depth 1

Download CodeQL databases

curl -L -O "https://github.com/sylwia-budzynska/codeql-workshop/releases/download/v1/test-app-db.zip" curl -L -O "https://github.com/sylwia-budzynska/codeql-workshop/releases/download/v1/kohya_ss-db.zip"

root@kitploit:~
3. No VS Code: Arquivo -> **Abrir workspace a partir de arquivo...** `vscode-codeql-starter.code-workspace`
4. Continue com [Selecionando um banco de dados do CodeQL](#select-codeql-database)
5. Em seguida, [Teste sua instalação](#test-your-installation)

### Opção B: GitHub Codespace

Use um Codespace remoto do GitHub para trabalhar nos exercícios do workshop.

#### Pré-requisitos

* Conta GitHub ([inscreva-se](https://github.com/) gratuitamente)
* Navegador (você pode fazer todo o workshop em um navegador — é a configuração mais rápida) ou [Visual Studio Code](https://code.visualstudio.com/download) (VS Code) com a extensão [GitHub Codespaces](https://marketplace.visualstudio.com/items?itemName=GitHub.codespaces) instalada em sua máquina local.

Nota: As primeiras 120 horas por núcleo de uso do Codespace são gratuitas por mês; usamos um codespace com 4 núcleos para este workshop, pois 4 núcleos é o máximo atual para contas gratuitas. (Se você tiver uma conta Pro, recomendamos mudar para uma máquina de 8 núcleos.)

#### Instruções

1. Faça login na sua conta do [GitHub](https://github.com/login)
2. Vá para o repositório https://github.com/sylwia-budzynska/codeql-workshop
3. Clique em Code -> Codespaces
4. Clique no sinal de mais (+) para criar um novo codespace.

<img src="https://assets.kitploit.com/production/public/readmes/33098/c86e537f9e7891fb6bdb5da727cae5b6ad0b2c9ac94f67854d48296f2dad89cb.png"  width="439" alt="Captura de tela: Criar Codespace, clique em +">

O VS Code será iniciado no seu navegador e um Codespace remoto será criado. Isso pode levar alguns minutos.
Se for solicitado a abrir o workspace `vscode-codeql-starter.code-workspace`, clique em "Abrir Workspace".

5. Se você quiser usar o VS Code localmente, pressione o botão de três linhas no canto superior esquerdo e selecione "Abrir no VS Code Desktop". A opção pode levar alguns minutos para aparecer.

<img src="https://assets.kitploit.com/production/public/readmes/33098/f2c8c2fe6da80142344b17c208da31a23c3fa68a3917a124f0e2f7871b6a20f7.png" width="300" alt="Captura de tela: Pressione o botão de três linhas e Abrir no VS Code Desktop">

6. Continue com [Selecionando um banco de dados do CodeQL](#select-codeql-database)
7. Em seguida, [Teste sua instalação](#test-your-installation)

Você pode ver seus codespaces em [github.com/codespaces](https://github.com/codespaces). O codespace será desligado sozinho após algumas horas sem uso, mas para garantir que você não esteja usando horas adicionais das 120h gratuitas, lembre-se de ir para [github.com/codespaces](https://github.com/codespaces) > três pontos > "Parar codespace" após o workshop.

#### Solução de problemas da instalação

Caso você veja erros como:
* `Failed to run query: Could not resolve library path for [..]`
* `Could not resolve module [..]`
* `Could not resolve type [..]`

É muito provável que você tenha esquecido de clonar os submódulos do git (a saber, o repositório ql). Para corrigir isso, execute `git submodule init && git submodule update --recursive`.

### Selecionar banco de dados do CodeQL

1. Certifique-se de ter o workspace `vscode-codeql-starter.code-workspace` aberto no VS Code.
2. Clique no ícone "QL" no painel de abas à esquerda para ir para a visualização do CodeQL.
3. Clique em "Escolher banco de dados do arquivo" e selecione o arquivo `test-app-db.zip` na raiz do repositório.
   Nota: Neste ponto, você pode encontrar um erro no VSCode com uma mensagem pop-up pedindo para instalar o CodeQL CLI. Aceitar essa instalação deve corrigir o problema. Após a instalação do CLI terminar, você deve conseguir concluir a seleção de banco de dados acima.
   <img src="https://assets.kitploit.com/production/public/readmes/33098/65cc5790b8b49113623bc9a9b34a1be61575b05bea2428c46f83115e2271148b.png"  alt="Captura de tela: mensagem de erro do VSCode sobre CodeQL">
   <img src="https://assets.kitploit.com/production/public/readmes/33098/c3bf9c304d9c1f6199f591c9bcbf6e446ee4f5388ab209e30887326698129f84.png"  alt="Captura de tela: VSCode instalando o CodeQL CLI">

### Teste sua instalação

#### Pré-requisitos

Certifique-se de que o banco de dados do CodeQL escolhido anteriormente esteja selecionado na visualização do CodeQL. (Clique em "Selecionar" se não estiver)

Quando o banco de dados estiver selecionado, deve ficar assim (observe a marca de seleção):

<img src="https://assets.kitploit.com/production/public/readmes/33098/fee6e47c0d9b0754c7ac9e29e2f0b3a721093aa5ce882615b3839a99f4862506.png"  alt="Captura de tela: Banco de dados do CodeQL selecionado">

#### Instruções

1. No VS Code: vá para a pasta do workspace: `codeql-custom-queries-python`
2. Crie um novo arquivo `test.ql`
3. adicione o seguinte conteúdo: `select "Hello World!"`
4. Salve o arquivo, clique com o botão direito na área do arquivo e escolha "CodeQL: Executar consulta no banco de dados selecionado"
5. Você deve ver uma nova guia abrir com o resultado "Hello World!"

## :books: Recursos

- [Tutoriais de QL](https://codeql.github.com/docs/writing-codeql-queries/ql-tutorials/)
- [Guia da linguagem CodeQL para Python](https://codeql.github.com/docs/codeql-language-guides/codeql-for-python/)
- [Documentação do CodeQL](https://codeql.github.com/docs/)
- [Referência da linguagem QL](https://codeql.github.com/docs/ql-language-reference/)
- [Biblioteca CodeQL para Python](https://codeql.github.com/codeql-standard-libraries/python/)
- [Consulta básica para código Python](https://codeql.github.com/docs/codeql-language-guides/basic-query-for-python-code/)
- [Classes QL](https://codeql.github.com/docs/ql-language-reference/types/#classes)
- [CodeQL do zero ao herói parte 1: fundamentos da análise estática para pesquisa de vulnerabilidades](https://github.blog/2023-03-31-codeql-zero-to-hero-part-1-the-fundamentals-of-static-analysis-for-vulnerability-research/)
- [CodeQL do zero ao herói parte 2: começando com o CodeQL](https://github.blog/2023-06-15-codeql-zero-to-hero-part-2-getting-started-with-codeql/)
- [CodeQL do zero ao herói parte 3: pesquisa de segurança](https://github.blog/2024-04-29-codeql-zero-to-hero-part-3-security-research-with-codeql/)
- [CodeQL do zero ao herói parte 4: estudo de caso do Gradio](https://github.blog/security/vulnerability-research/codeql-zero-to-hero-part-4-gradio-framework-case-study/)
- [CodeQL do zero ao herói parte 5: depurando consultas](https://github.blog/security/vulnerability-research/codeql-zero-to-hero-part-5-debugging-queries/)

## Workshop

Bem-vindo ao workshop "Encontrando vulnerabilidades com CodeQL"!

Esta sessão apresentará os fundamentos da pesquisa de segurança e da análise estática usados na busca por vulnerabilidades em software. Usaremos um exemplo de vulnerabilidade simples, percorreremos como o CodeQL poderia detectá-la e forneceremos exemplos de como o público pode usar o CodeQL para encontrar vulnerabilidades por conta própria.

Antes de começarmos, é importante que todos os pré-requisitos sejam atendidos para que você possa participar do workshop.

O workshop é dividido em várias seções e cada seção consiste em exercícios que se acumulam até a consulta final.
Para cada seção, fornecemos *diretrizes* que ajudam você a concluir o exercício, fornecendo referências a classes QL e predicados de membro que você pode usar.

### Visão geral

Neste workshop, procuraremos por *vulnerabilidades de injeção de comando* conhecidas no [kohya_ss](https://securitylab.github.com/advisories/GHSL-2024-019_GHSL-2024-024_kohya_ss/). Essas vulnerabilidades podem ocorrer quando informações controladas por um usuário chegam a um código de aplicação que constrói um comando de forma insegura e o executa. O comando construído de forma insegura a partir da entrada do usuário pode ser reescrito para executar ações não intencionais, como execução arbitrária de comandos e divulgação de informações sensíveis.

As injeções de comando discutidas neste workshop são [CVE-2024-32022, CVE-2024-32026, CVE-2024-32025, CVE-2024-32027](https://securitylab.github.com/advisories/GHSL-2024-019_GHSL-2024-024_kohya_ss/).

## Teoria

### Fontes e sinks

Pense em uma das vulnerabilidades mais conhecidas: injeção de comando. Ela acontece se a entrada do usuário for usada em funções que permitem executar comandos em um shell diretamente no servidor. Isso permite que um atacante execute comandos do sistema operacional (SO) no servidor que está executando um aplicativo e, normalmente, comprometa totalmente o aplicativo e seus dados.

A principal causa das vulnerabilidades de injeção é o uso de entrada não confiável e controlada pelo usuário em funções sensíveis ou perigosas do programa. Para representar isso na análise estática, usamos termos como fluxo de dados, fontes e sinks.

A entrada do usuário geralmente vem de pontos de entrada de um aplicativo — a origem dos dados. Esses incluem parâmetros em métodos HTTP, como GET e POST, ou argumentos de linha de comando para um programa. Esses pontos de entrada são chamados de “**fontes**.”

Continuando com nossa injeção de comando, um exemplo de função perigosa que não deve ser chamada com dados não confiáveis e não higienizados poderia ser `os.system`. Essas funções perigosas são chamadas de “**sinks**”. Observe que o fato de uma função ser potencialmente perigosa não significa que ela seja imediatamente uma vulnerabilidade explorável e precise ser removida. Muitos sinks têm maneiras de serem usados com segurança. Outros exemplos de sinks que não devem ser usados com entrada do usuário são MySQLCursor.execute() da biblioteca MySQLdb em Python (causando injeção de SQL) ou a função embutida eval() do Python, que avalia expressões arbitrárias (causando injeção de código).

Para que uma vulnerabilidade esteja presente, a entrada não segura e controlada pelo usuário precisa ser usada sem sanitização adequada ou validação de entrada em uma função perigosa. Em outras palavras, tem que haver um caminho de código entre a fonte e o sink; nesse caso, dizemos que os dados fluem de uma fonte para um sink — há um “**fluxo de dados**” da fonte para o sink.

<img src="https://assets.kitploit.com/production/public/readmes/33098/ff60a1649737805a71bd27710209dba66203a77159cc72ae435c165353e56491.png">

### Folha de dicas do CodeQL
A estrutura básica de consulta```codeql
import python

from <type> <name> 		//variables used in the query

where <conditions for variables>

select <output>			//results, referring to the variables

Encontre referências a chamadas `os.system()````codeql import python import semmle.python.ApiGraphs

from API::CallNode call where call = API::moduleImport("os") .getMember("system") .getACall() select call, "Call to os.system"

root@kitploit:~
Encontre referências a chamadas `os.system()`, desta vez com um predicado```codeql
predicate isOsSystemSink(API::CallNode call) {
	call = API::moduleImport("os")
	.getMember("system").getACall()
  }


from API::CallNode call
where isOsSystemSink(call)
select call, "Call to os.system"

Encontre referências a chamadas de os.system(), desta vez com uma classe```codeql class OsSystemSink extends API::CallNode { OsSystemSink() { this = API::moduleImport("os") .getMember("system").getACall() } }

from API::CallNode call where call instanceof OsSystemSink select call, "Call to os.system"

root@kitploit:~
Encontre referências a chamadas `os.system()`, desta vez com uma classe.
Especifique que o tipo com o qual estamos começando é `OsSystemSink`.```codeql
class OsSystemSink extends API::CallNode {
  OsSystemSink() {
    this = API::moduleImport("os")
    .getMember("system").getACall()
	}
}


from OsSystemSink s
select s, "Call to os.system"

Workshop parte I - banco de dados de teste

Neste workshop, vamos encontrar injeções de comando, nas quais a entrada do usuário acaba em uma chamada os.system.

Na primeira parte do workshop, escreveremos consultas CodeQL para encontrar fontes e sumidouros, chamadas os.system, em uma base de código intencionalmente vulnerável. Na segunda parte do workshop, vamos usar essas consultas para encontrar uma injeção de comando de uma fonte a um sumidouro em um software de código aberto, kohya_ss v22.6.1.

Com a consulta CodeQL que escrevermos, poderemos encontrar injeções de comando como a abaixo.

A entrada do usuário vem de um componente interativo Gradio (framework web para aplicações de aprendizado de máquina) gr.Textbox em #1. gr.Button.click em #2 vincula o clique do botão à função execute_cmd, passando os valores de folder. Isso significa que quando o gr.Button é clicado, folder é passado para execute_cmd, onde folder é concatenado em um comando e executado no sistema em uma chamada os.system em #3.```python import gradio as gr import os

def execute_cmd(folder): cmd = f"python caption.py --dir={folder}" os.system(cmd) #3

with gr.Blocks() as demo: gr.Markdown("Create caption files for images in a directory") with gr.Row(): folder = gr.Textbox(placeholder="Directory to caption") #1 logs = gr.Checkbox(label="Add verbose logs")

root@kitploit:~
btn = gr.Button("Run")
btn.click(fn=execute_cmd, inputs=[folder]) #2

if name == "main": demo.launch(debug=True)

root@kitploit:~
Você também notará outro exemplo de injeção de comandos no workshop, em um aplicativo criado usando o framework `Flask`. Nesse caso, a entrada do usuário vem de um parâmetro GET de uma requisição do Flask (framework web popular em Python), que é armazenada na variável `files` (veja #1). `files` é então passada para a chamada `os.system` e concatenada com `ls`, levando à injeção de comandos (veja #2).```python
import os
from flask import Flask, request

app = Flask(__name__)

@app.route("/command1")
def command_injection1():
    files = request.args.get('files', '')   #1
    os.system("ls " + files)                #2

Vamos começar construindo gradualmente uma query para detectar chamadas os.system e depois uma query para fontes.

1. Encontrar todas as chamadas a funções de bibliotecas externas

Podemos encontrar todas as chamadas a funções de bibliotecas externas (não definidas no código-base) utilizando o módulo ApiGraphs do CodeQL.

Use o template abaixo:```codeql import python import semmle.python.ApiGraphs

from //TODO: fill me in. Start typing API:: and press Ctrl+Space to see a list of available types. Name your variable call select //TODO: fill me in

root@kitploit:~
Clique com o botão direito na área do arquivo e escolha "CodeQL: Run Query on Selected Database" para executar a consulta.

<details>
<summary>Diretrizes</summary>

- Na cláusula `from`, comece com `API::` e pressione `Ctrl + Space` para ver os tipos disponíveis no módulo API Graphs.
- Uma chamada é representada pelo tipo `API::CallNode`. Crie uma variável com esse tipo e o nome `call`.
- Para limitar os resultados apenas às chamadas na pasta raiz do aplicativo (chamada `test-app`), adicione uma cláusula `where` com a condição `where call.getLocation().getFile().getRelativePath().regexpMatch("test-app/.*")`.

</details>
<details>
<summary>Solução</summary>```codeql
import python
import semmle.python.ApiGraphs

from API::CallNode call
where call.getLocation().getFile().getRelativePath().regexpMatch("test-app/.*")
select call, "A call"

2. Encontre todas as chamadas a os.system

Diretrizes
  • Na cláusula from, crie uma variável call do tipo API::CallNode.
  • Na cláusula where, use o operador de igualdade = para afirmar que call é igual às chamadas os.system. Use o operador lógico and para especificar várias condições.
  • Para encontrar nós correspondentes à biblioteca os, use o método API::moduleImport() com os como argumento. Para acessar a função system da biblioteca os, use o predicado getMember() em . Por fim, obtenha quaisquer chamadas com o predicado .

3. Encontrar os primeiros argumentos para chamadas a os.system

Queremos encontrar os primeiros argumentos para chamadas a os.system, para que depois possamos ver se alguma entrada do usuário flui para os primeiros argumentos (ou seja, para o comando que será executado).

Diretrizes
  • Preencha o template:```codeql import python import semmle.python.ApiGraphs

from API::CallNode call where call = API::moduleImport("os").getMember("system").getACall() and call.getLocation().getFile().getRelativePath().regexpMatch("test-app/.*") select call // TODO: fill me in. Type a dot . right after call and press Ctrl+Space to see available predicates.

root@kitploit:~
</details>
<details>
<summary>Solução</summary>```codeql
import python
import semmle.python.ApiGraphs

from API::CallNode call
where call = API::moduleImport("os").getMember("system").getACall() and
call.getLocation().getFile().getRelativePath().regexpMatch("test-app/.*")
select call.getArg(0), "First argument of an `os.system` call"

4. Transforme sua consulta que encontra as chamadas a os.system em uma classe CodeQL

classes em CodeQL podem ser usadas para encapsular porções reutilizáveis de lógica. Classes representam conjuntos únicos de valores, e também podem incluir operações (conhecidas como member predicates) específicas a esse conjunto de valores. Você já viu inúmeros exemplos de classes do CodeQL (API::CallNode) e member predicates (getLocation(), etc.)

Diretrizes
  • Para criar um novo tipo, temos que estender um supertipo, aqui API::CallNode, dar a ele um nome e um predicado característico com o mesmo nome. Nomearemos nossa classe de OsSystemSink.

Preencha o template:```codeql import python import semmle.python.ApiGraphs

class OsSystemSink extends API::CallNode { OsSystemSink() { //TODO: fill me in } }

from API::CallNode call where // TODO: fill me in and call.getLocation().getFile().getRelativePath().regexpMatch("test-app/.*") select call.getArg(0), "Call to os.system"

root@kitploit:~
Use a palavra-chave mágica `this`, que se refere às instâncias dos nós de chamada (`API::CallNode`s) que estamos descrevendo na classe. Use `this` para encontrar as chamadas para `os.system` da mesma forma que você fez anteriormente com `API::moduleImport`.
- Altere a cláusula `where` para fazer sua variável `call` ser um `instanceof` da sua nova classe `OsSystemSink`.

</details>
<details>
<summary>Solução</summary>```codeql
import python
import semmle.python.ApiGraphs

class OsSystemSink extends API::CallNode {
	OsSystemSink() {
		this = API::moduleImport("os").getMember("system").getACall()
	}
}


from API::CallNode call
where call instanceof OsSystemSink
and call.getLocation().getFile().getRelativePath().regexpMatch("test-app/.*")
select call.getArg(0), "First argument of an `os.system` call"

5. Encontre todas as fontes com a classe RemoteFlowSource

Agora mudamos para a busca de fontes.

A maioria das fontes já está modelada no CodeQL e possui o tipo RemoteFlowSource. Podemos usar esse tipo para encontrar quaisquer fontes em uma base de código.

Diretrizes
  • Importe semmle.python.dataflow.new.RemoteFlowSources para usar o tipo RemoteFlowSource.
  • Na cláusula from, pressione Ctrl + Space para ver todos os tipos disponíveis.

Preencha o modelo:```codeql import python import semmle.python.dataflow.new.RemoteFlowSources

from //TODO: fill me in where //TODO: fill me in select //TODO: fill me in

root@kitploit:~
</details>
<details>
<summary>Solução</summary>```codeql
import python
import semmle.python.dataflow.new.RemoteFlowSources

from RemoteFlowSource rfs
where rfs.getLocation().getFile().getRelativePath().regexpMatch("test-app/.*")
select rfs

Workshop parte II - encontrar injeções de comandos no kohya_ss

Kohya_ss é uma GUI para os scripts do Kohya para Stable Diffusion para treinamento, geração e utilitários para Stable Diffusion.

Na segunda parte do workshop, vamos alternar a base de código que estamos consultando para kohya_ss e encontrar os fluxos de dados das fontes até os sumidouros em kohya_ss, que levam a injeções de comandos: CVE-2024-32022, CVE-2024-32026, CVE-2024-32025, CVE-2024-32027

Antes de começar o próximo exercício:

  • Vá para a aba CodeQL no VSCode, seção Databases, clique em "Choose Database from Archive" e selecione o arquivo kohya_ss-db.zip na raiz do repositório. Uma marca de verificação deve aparecer. Isso selecionará o banco de dados CodeQL no qual você está trabalhando.

6. Encontre fluxos de dados das fontes até o primeiro argumento de chamadas a os.system

Diretrizes
  • Use o modelo abaixo e observe:
  • no predicado isSource, refine a variável source para ser do tipo RemoteFlowSource.
  • no predicado isSink, refine a variável sink para ser o primeiro argumento de uma chamada a os.system. Faça isso usando o mecanismo exists e sua classe OsSystemSink.
    • exists é um mecanismo para introduzir variáveis temporárias com escopo restrito. Você pode pensar nelas como um from-where-select próprio. Neste caso, use exists para introduzir a variável call com o tipo OsSystemSink e então refine sink para ser o primeiro argumento da .```codeql /**

Exercícios bônus, se o tempo permitir

7. Consultar o codebase com as consultas padrão

As consultas do CodeQL para Python residem na pasta ql/python/ql/src/Security. Já existem consultas para as vulnerabilidades mais populares: injeção de SQL, injeção de comandos, injeção de código, etc. Execute a consulta de injeção de SQL (CWE-089) no banco de dados de teste (você precisará selecioná-lo na extensão do CodeQL > Databases. Observe a marca de verificação).

💡 Isso é muito interessante para pesquisadores de segurança — usando as consultas padrão, podemos ter uma ideia geral de quais vulnerabilidades potenciais podem existir em um determinado projeto.

8. Execute suas próprias consultas usando a análise de variantes multirrepositório (MRVA)

O poder do CodeQL está em poder reutilizar as consultas e os modelos do CodeQL para executá-los em qualquer codebase no mesmo idioma. Podemos executar consultas do CodeQL em até 1000 repositórios de uma só vez usando a análise de variantes multirrepositório (MRVA). Os projetos precisam estar hospedados no GitHub.

💡 Isso é muito interessante para pesquisadores de segurança — se você encontrou um sink ou uma fonte potencialmente perigosa, pode adicioná-los ao CodeQL (ou executar como uma consulta) e fazer sua pesquisa contra mil repositórios de uma só vez.

  • Siga a configuração na documentação.
  • Observe que o MRVA é executado usando fluxos de trabalho do GitHub Actions. Os fluxos de trabalho do Actions são gratuitos em repositórios públicos e pagos em repositórios privados.
  • Após a configuração, clique com o botão direito e escolha "CodeQL: Run Variant Analysis"

Considerações finais

Hoje, você aprendeu como explorar um codebase usando CodeQL e como usar CodeQL em seu próprio fluxo de trabalho de pesquisa de segurança.

Confira estes recursos se quiser saber mais sobre:

  • análise estática e como ela funciona:
    • CodeQL zero to hero parte 1: os fundamentos da análise estática para pesquisa de vulnerabilidades.
  • fundamentos do uso do CodeQL e da sua linguagem de consulta:
    • CodeQL zero to hero parte 2: começando com CodeQL.
  • pesquisa de segurança com CodeQL:
    • CodeQL zero to hero parte 3: pesquisa de segurança.
  • Como modelar o CodeQL para um framework web no exemplo do Gradio
    • CodeQL zero to hero parte 4: estudo de caso do Gradio.
  • Depuração de por que uma consulta pode não estar funcionando:
    • CodeQL zero to hero parte 5: depurando consultas

Se você acabar encontrando uma vulnerabilidade usando CodeQL, sinta-se à vontade para adicioná-la ao CodeQL Wall of Fame.

Baixar ferramenta
API::moduleImport()
os.system
getACall()

Preencha o modelo:```codeql import python import semmle.python.ApiGraphs

from API::CallNode call where call //TODO: fill me in and call.getLocation().getFile().getRelativePath().regexpMatch("test-app/.*") select call, "Call to os.system"

root@kitploit:~
</details>
<details>
<summary>Solução</summary>```codeql
import python
import semmle.python.ApiGraphs

from API::CallNode call
where call = API::moduleImport("os").getMember("system").getACall() and
call.getLocation().getFile().getRelativePath().regexpMatch("test-app/.*")
select call, "Call to `os.system`"
call
  • @name Command injection in os.system sink
  • @kind path-problem
  • @id codeql-ws/dataflow-query */

import python import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import semmle.python.ApiGraphs import MyFlow::PathGraph import semmle.python.dataflow.new.RemoteFlowSources

//TODO: add previous class definition here

private module MyConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { // TODO: fill me in }

predicate isSink(DataFlow::Node sink) { // TODO: fill me in. Use the exists mechanism exists( | sink = ... ) } }

module MyFlow = TaintTracking::Global;

from MyFlow::PathNode source, MyFlow::PathNode sink where MyFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Command injection"

root@kitploit:~
</details>
<details>
<summary>Solução</summary>```codeql
/**
 * @name Command injection in os.system sink
 * @kind path-problem
 * @id codeql-ws/dataflow-query
 */

import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
import semmle.python.ApiGraphs
import semmle.python.dataflow.new.RemoteFlowSources
import MyFlow::PathGraph

class OsSystemSink extends API::CallNode {
	OsSystemSink() {
		this = API::moduleImport("os").getMember("system").getACall()
	}
}

private module MyConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
	source instanceof RemoteFlowSource
}

predicate isSink(DataFlow::Node sink) {
	exists(OsSystemSink call |
	sink = call.getArg(0)
	)
}
}

module MyFlow = TaintTracking::Global<MyConfig>;

from MyFlow::PathNode source, MyFlow::PathNode sink
where MyFlow::flowPath(source, sink)
select sink.getNode(), source, sink, "Command injection"