Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
Outils/GitHubGitHub/sylwia-budzynska/codeql-workshop
Analyse StatiqueAnalyse des VulnérabilitésAnalyse de CodeApprentissage et ÉducationRessources OrganiséesParcours et CoursLabs et Pratique
GitHubsylwia-budzynska/codeql-workshop

codeql-workshop

Faites vos premiers pas dans CodeQL pour Python en écrivant une requête pour trouver CVE-2024-32022

Voir le dépôt
128il y a 1 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Trouver des vulnérabilités avec CodeQL

Atelier original par Sylwia Budzynska

Prérequis • Ressources • Atelier

  • À qui s'adresse cet atelier : Ingénieurs en sécurité, chercheurs en sécurité, développeurs.
  • Ce que vous apprendrez : Apprenez à utiliser CodeQL pour l'exploration de code et la recherche de problèmes de sécurité.
  • Ce que vous construirez : Construisez une requête CodeQL basée sur un avis de sécurité pour trouver une injection de commande.

📣 Prérequis

Vous pouvez choisir entre deux options pour réaliser les exercices de l'atelier :

  • Option A : Installation locale (Utilisation de VS Code - CodeQL s'exécute localement sur votre machine)
  • Option B : GitHub Codespace (Utilisation d'un navigateur ou de VS Code - CodeQL s'exécute à distance sur un Codespace GitHub basé sur Linux dans le cloud)

Option A : Installation locale

Utilisez une installation locale de CodeQL pour travailler sur les exercices de l'atelier.

Prérequis

  • Visual Studio Code (VS Code) et git installés sur votre machine locale.

Instructions

  1. Installez l'extension VS Code pour CodeQL
  2. Exécutez dans le 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. Dans VS Code : Fichier -> **Ouvrir un espace de travail à partir d'un fichier...** `vscode-codeql-starter.code-workspace`
4. Continuez avec [Sélection d'une base de données CodeQL](#select-codeql-database)
5. Ensuite [Testez votre installation](#test-your-installation)

### Option B : GitHub Codespace

Utilisez un Codespace GitHub à distance pour travailler sur les exercices de l'atelier.

#### Prérequis

* Compte GitHub ([inscription gratuite](https://github.com/)) 
* Navigateur (vous pouvez suivre tout l'atelier dans un navigateur - c'est la configuration la plus rapide) ou [Visual Studio Code](https://code.visualstudio.com/download) (VS Code) avec l'extension [GitHub Codespaces](https://marketplace.visualstudio.com/items?itemName=GitHub.codespaces) installée sur votre machine locale.

Remarque : Les 120 premières heures par cœur d'utilisation de Codespace sont gratuites par mois. Nous utilisons un Codespace avec 4 cœurs pour cet atelier car 4 cœurs est le maximum actuel pour les comptes gratuits. (Si vous avez un compte Pro, nous vous recommandons de passer à une machine à 8 cœurs.)

#### Instructions

1. Connectez-vous à votre compte [GitHub](https://github.com/login)
2. Allez sur le dépôt https://github.com/sylwia-budzynska/codeql-workshop
3. Cliquez sur Code -> Codespaces
4. Cliquez sur le signe plus (+) pour créer un nouveau Codespace.

<img src="https://assets.kitploit.com/production/public/readmes/33098/c86e537f9e7891fb6bdb5da727cae5b6ad0b2c9ac94f67854d48296f2dad89cb.png"  width="439" alt="Capture d'écran : Créez un Codespace, cliquez sur plus">

VS Code démarrera dans votre navigateur et un Codespace distant sera construit. Cela peut prendre quelques minutes.
Si on vous demande d'ouvrir l'espace de travail `vscode-codeql-starter.code-workspace`, cliquez sur « Ouvrir l'espace de travail ».

5. Si vous souhaitez utiliser VS Code localement, appuyez sur le bouton à trois lignes dans le coin supérieur gauche et sélectionnez « Ouvrir VS Code Desktop ». L'option peut prendre jusqu'à quelques minutes pour apparaître.

<img src="https://assets.kitploit.com/production/public/readmes/33098/f2c8c2fe6da80142344b17c208da31a23c3fa68a3917a124f0e2f7871b6a20f7.png" width="300" alt="Capture d'écran : Appuyez sur le bouton à trois lignes et Ouvrir dans VS Code Desktop">

6. Continuez avec [Sélection d'une base de données CodeQL](#select-codeql-database)
7. Ensuite [Testez votre installation](#test-your-installation)

Vous pouvez voir vos Codespaces sur [github.com/codespaces](https://github.com/codespaces). Le Codespace s'éteindra automatiquement après quelques heures d'inactivité, mais pour vous assurer de ne pas utiliser d'heures supplémentaires des 120h gratuites, n'oubliez pas d'aller sur [github.com/codespaces](https://github.com/codespaces) > trois points > « Arrêter le Codespace » après l'atelier.

#### Dépannage de l'installation

Si vous voyez des erreurs telles que :
* `Failed to run query: Could not resolve library path for [..]`
* `Could not resolve module [..]`
* `Could not resolve type [..]`

Il est très probable que vous ayez oublié de cloner les sous-modules git (notamment le dépôt ql). Pour résoudre ce problème, exécutez `git submodule init && git submodule update --recursive`.

### Sélectionner une base de données CodeQL

1. Assurez-vous d'avoir l'espace de travail `vscode-codeql-starter.code-workspace` ouvert dans VS Code.
2. Cliquez sur l'icône « QL » dans le volet des onglets de gauche pour accéder à la vue CodeQL.
3. Cliquez sur « Choisir une base de données à partir d'une archive » et sélectionnez le fichier `test-app-db.zip` à la racine du dépôt.
   Remarque : À ce stade, vous pouvez rencontrer une erreur dans VSCode avec un message contextuel demandant d'installer le CLI CodeQL. Accepter cette installation devrait résoudre le problème. Une fois l'installation du CLI terminée, vous devriez pouvoir terminer la sélection de la base de données ci-dessus.
   <img src="https://assets.kitploit.com/production/public/readmes/33098/65cc5790b8b49113623bc9a9b34a1be61575b05bea2428c46f83115e2271148b.png"  alt="Capture d'écran : Message d'erreur VSCode concernant CodeQL">
   <img src="https://assets.kitploit.com/production/public/readmes/33098/c3bf9c304d9c1f6199f591c9bcbf6e446ee4f5388ab209e30887326698129f84.png"  alt="Capture d'écran : Installation du CLI CodeQL par VSCode">

### Testez votre installation

#### Prérequis

Assurez-vous que la base de données CodeQL précédemment choisie est sélectionnée dans la vue CodeQL. (Cliquez sur « Sélectionner » si ce n'est pas le cas)

Lorsque la base de données est sélectionnée, elle devrait ressembler à ceci (notez la coche) :

<img src="https://assets.kitploit.com/production/public/readmes/33098/fee6e47c0d9b0754c7ac9e29e2f0b3a721093aa5ce882615b3839a99f4862506.png"  alt="Capture d'écran : Base de données CodeQL sélectionnée">

#### Instructions

1. Dans VS Code : allez dans le dossier de l'espace de travail : `codeql-custom-queries-python`
2. Créez un nouveau fichier `test.ql`
3. ajoutez le contenu suivant : `select "Hello World!"`
4. Enregistrez le fichier, faites un clic droit dans la zone du fichier et choisissez « CodeQL : Exécuter la requête sur la base de données sélectionnée »
5. Vous devriez voir un nouvel onglet s'ouvrir avec le résultat « Hello World! »

## :books: Ressources

- [Tutoriels QL](https://codeql.github.com/docs/writing-codeql-queries/ql-tutorials/)
- [Guide du langage CodeQL pour Python](https://codeql.github.com/docs/codeql-language-guides/codeql-for-python/)
- [Documentation CodeQL](https://codeql.github.com/docs/)
- [Référence du langage QL](https://codeql.github.com/docs/ql-language-reference/)
- [Bibliothèque CodeQL pour Python](https://codeql.github.com/codeql-standard-libraries/python/)
- [Requête de base pour le code 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 de zéro à héros partie 1 : les fondamentaux de l'analyse statique pour la recherche de vulnérabilités](https://github.blog/2023-03-31-codeql-zero-to-hero-part-1-the-fundamentals-of-static-analysis-for-vulnerability-research/)
- [CodeQL de zéro à héros partie 2 : démarrer avec CodeQL](https://github.blog/2023-06-15-codeql-zero-to-hero-part-2-getting-started-with-codeql/)
- [CodeQL de zéro à héros partie 3 : recherche en sécurité](https://github.blog/2024-04-29-codeql-zero-to-hero-part-3-security-research-with-codeql/)
- [CodeQL de zéro à héros partie 4 : étude de cas Gradio](https://github.blog/security/vulnerability-research/codeql-zero-to-hero-part-4-gradio-framework-case-study/)
- [CodeQL de zéro à héros partie 5 : débogage de requêtes](https://github.blog/security/vulnerability-research/codeql-zero-to-hero-part-5-debugging-queries/)

## Atelier

Bienvenue à l'atelier « Trouver des vulnérabilités avec CodeQL » !

Cette session présentera les fondamentaux de la recherche en sécurité et de l'analyse statique utilisés lors de la recherche de vulnérabilités dans les logiciels. Nous utiliserons un exemple de vulnérabilité simple, passerons en revue comment CodeQL pourrait la détecter, et fournirons des exemples sur la façon dont le public pourrait utiliser CodeQL pour trouver lui-même des vulnérabilités.

Avant de commencer, il est important que tous les prérequis soient remplis afin que vous puissiez participer à l'atelier.

L'atelier est divisé en plusieurs sections et chaque section se compose d'exercices qui mènent à la requête finale.

Pour chaque section, nous fournissons des *directives* qui vous aident à terminer l'exercice en vous donnant des références aux classes QL et aux prédicats membres que vous pouvez utiliser.

### Aperçu

Dans cet atelier, nous rechercherons des *vulnérabilités d'injection de commandes* connues dans [kohya_ss](https://securitylab.github.com/advisories/GHSL-2024-019_GHSL-2024-024_kohya_ss/). De telles vulnérabilités peuvent se produire lorsque des informations contrôlées par un utilisateur parviennent à un code d'application qui construit et exécute une commande de manière non sécurisée. La commande construite de manière non sécurisée à partir d'une entrée utilisateur peut être réécrite pour effectuer des actions non intentionnelles telles que l'exécution de commandes arbitraires ou la divulgation d'informations sensibles.

Les injections de commandes discutées dans cet atelier sont [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/).

## Théorie

### Sources et puits

Pensez à l'une des vulnérabilités les plus connues : l'injection de commandes. Cela se produit si une entrée utilisateur est utilisée dans des fonctions qui permettent d'exécuter des commandes dans un shell directement sur le serveur. Cela permet à un attaquant d'exécuter des commandes du système d'exploitation (OS) sur le serveur qui exécute une application, et généralement de compromettre totalement l'application et ses données.

La principale cause des vulnérabilités d'injection est l'utilisation d'entrées non fiables contrôlées par l'utilisateur dans des fonctions sensibles ou dangereuses du programme. Pour représenter cela en analyse statique, nous utilisons des termes tels que flux de données, sources et puits.

L'entrée utilisateur provient généralement des points d'entrée d'une application—l'origine des données. Cela inclut les paramètres dans les méthodes HTTP, telles que GET et POST, ou les arguments de ligne de commande d'un programme. Ceux-ci sont appelés « **sources** ».

En continuant avec notre injection de commandes, un exemple d'une fonction dangereuse qui ne devrait pas être appelée avec des données non fiables non assainies pourrait être `os.system`. Ces fonctions dangereuses sont appelées « **puits** ». Notez que ce n'est pas parce qu'une fonction est potentiellement dangereuse qu'elle constitue immédiatement une vulnérabilité exploitable et qu'elle doit être supprimée. De nombreux puits ont des moyens de les utiliser en toute sécurité. D'autres exemples de puits, qui ne devraient pas être utilisés avec des entrées utilisateur, sont MySQLCursor.execute() de la bibliothèque MySQLdb en Python (provoquant une injection SQL) ou la fonction intégrée eval() de Python qui évalue des expressions arbitraires (provoquant une injection de code).

Pour qu'une vulnérabilité soit présente, l'entrée non sécurisée contrôlée par l'utilisateur doit être utilisée sans désinfection ou validation appropriée dans une fonction dangereuse. En d'autres termes, il doit y avoir un chemin de code entre la source et le puits, auquel cas nous disons que les données circulent d'une source vers un puits—il y a un « **flux de données** » de la source au puits.

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

### Aide-mémoire CodeQL
La structure de requête de base```codeql
import python

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

where <conditions for variables>

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

Trouvez les références aux appels `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:~
Trouver les références aux appels à `os.system()`, cette fois avec un prédicat```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"

Rechercher les références aux appels os.system(), cette fois avec une 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:~
Rechercher les références aux appels `os.system()`, cette fois avec une classe.
Spécifiez que le type avec lequel nous commençons est `OsSystemSink````codeql
class OsSystemSink extends API::CallNode {
  OsSystemSink() {
    this = API::moduleImport("os")
    .getMember("system").getACall()
	}
}


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

Atelier partie I - base de données de test

Dans cet atelier, nous allons trouver des injections de commandes, dans lesquelles l'entrée utilisateur aboutit à un appel os.system.

Dans la première partie de l'atelier, nous écrirons des requêtes CodeQL pour trouver des sources et des puits, des appels os.system, sur une base de code intentionnellement vulnérable. Dans la deuxième partie de l'atelier, nous allons utiliser ces requêtes pour trouver une injection de commande d'une source à un puits dans un logiciel open source, kohya_ss v22.6.1.

Avec la requête CodeQL que nous écrivons, nous pourrons trouver des injections de commandes comme celle ci-dessous.

L'entrée utilisateur provient d'un composant Gradio interactif (framework web pour applications d'apprentissage automatique) gr.Textbox à #1. gr.Button.click à #2 lie le clic sur le bouton à la fonction execute_cmd, en transmettant les valeurs de folder. Cela signifie que lorsque le gr.Button est cliqué, folder est passé à execute_cmd, où folder est concaténé dans une commande, et exécuté sur le système dans un appel os.system à #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:~
Vous remarquerez également un autre exemple d'injection de commande dans l'atelier, dans une application créée à l'aide du framework `Flask`. Dans ce cas, l'entrée utilisateur provient d'un paramètre GET d'une requête Flask (framework web populaire en Python), qui est stocké dans la variable `files` (voir #1). `files` est ensuite passé à l'appel `os.system` et concaténé avec `ls`, ce qui entraîne une injection de commande (voir #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

Nous allons commencer par construire progressivement une requête pour détecter les appels à os.system, puis une requête pour les sources.

1. Trouver tous les appels aux fonctions provenant de bibliothèques externes

Nous pouvons trouver tous les appels aux fonctions provenant de bibliothèques externes (non définies dans la base de code) en utilisant le module ApiGraphs de CodeQL.

Utilisez le modèle ci-dessous :```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:~
Faites un clic droit dans la zone de fichiers et choisissez "CodeQL: Run Query on Selected Database" pour exécuter la requête.

<details>
<summary>Directives</summary>

- Dans la clause `from`, commencez par `API::` et appuyez sur `Ctrl + Espace` pour voir les types disponibles dans le module API Graphs.
- Un appel est représenté par le type `API::CallNode`. Créez une variable avec ce type et le nom `call`.
- Pour limiter les résultats uniquement aux appels dans le dossier racine de l'application (appelée `test-app`), ajoutez une clause ` where` avec la condition `where call.getLocation().getFile().getRelativePath().regexpMatch("test-app/.*")`.

</details>
<details>
<summary>Solution</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. Trouver tous les appels à os.system

Directives
  • Dans la clause from, créez une variable call de type API::CallNode.
  • Dans la clause where, utilisez l'opérateur d'égalité = pour affirmer que call est égal aux appels à os.system. Utilisez l'opérateur logique and pour spécifier plusieurs conditions.
  • Pour trouver les nœuds correspondant à la bibliothèque os, utilisez la méthode API::moduleImport() avec os comme argument. Pour accéder à la fonction system de la bibliothèque os, utilisez le prédicat getMember() sur . Enfin, obtenez tout appel à avec le prédicat .

3. Trouver les premiers arguments des appels à os.system

Nous voulons trouver les premiers arguments des appels à os.system, afin de voir plus tard si une entrée utilisateur se retrouve dans les premiers arguments (donc dans la commande qui sera exécutée).

Directives
  • Remplissez le modèle :```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>Solution</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. Transformez votre requête qui trouve les appels à os.system en une classe CodeQL

Les classes en CodeQL peuvent être utilisées pour encapsuler des portions réutilisables de logique. Les classes représentent des ensembles uniques de valeurs, et elles peuvent également inclure des opérations (appelées prédicats membres) spécifiques à cet ensemble de valeurs. Vous avez déjà vu de nombreux exemples de classes CodeQL (API::CallNode) et de prédicats membres (getLocation(), etc.)

Directives
  • Pour créer un nouveau type, nous devons étendre un supertype, ici API::CallNode, lui donner un nom, ainsi qu'un prédicat caractéristique portant le même nom. Nous nommerons notre classe OsSystemSink.

Remplissez le modèle :```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:~
- Utilisez le mot-clé magique `this`, qui fait référence aux instances des nœuds d'appel (`API::CallNode`s) que nous décrivons dans la classe. Utilisez `this` pour trouver les appels à `os.system` de la même manière que vous l'avez fait précédemment avec `API::moduleImport`.
- Modifiez la clause `where` pour que votre variable `call` soit une `instanceof` de votre nouvelle classe `OsSystemSink`.

</details>
<details>
<summary>Solution</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. Trouver toutes les sources avec la classe RemoteFlowSource

Passons maintenant à la recherche des sources.

La plupart des sources sont déjà modélisées dans CodeQL et possèdent le type RemoteFlowSource. Nous pouvons utiliser ce type pour trouver n'importe quelle source dans une base de code.

Consignes
  • Importez semmle.python.dataflow.new.RemoteFlowSources pour utiliser le type RemoteFlowSource.
  • Dans la clause from, appuyez sur Ctrl + Espace pour voir tous les types disponibles.

Remplissez le modèle :```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>Solution</summary>```codeql
import python
import semmle.python.dataflow.new.RemoteFlowSources

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

Atelier partie II - trouver des injections de commandes dans kohya_ss

Kohya_ss est une interface graphique pour les scripts de Stable Diffusion de Kohya pour l'entraînement, la génération et les utilitaires pour Stable Diffusion.

Dans la deuxième partie de l'atelier, nous allons changer la base de code que nous interrogeons pour celle de kohya_ss et trouver les flux de données des sources vers les puits dans kohya_ss, qui mènent à des injections de commandes : CVE-2024-32022, CVE-2024-32026, CVE-2024-32025, CVE-2024-32027

Avant de commencer l'exercice suivant :

  • Allez dans l'onglet CodeQL de VSCode, section Databases, cliquez sur "Choose Database from Archive" et sélectionnez le fichier kohya_ss-db.zip à la racine du dépôt. Une coche devrait apparaître. Cela sélectionnera la base de données CodeQL sur laquelle vous travaillez.

6. Trouver les flux de données des sources vers le premier argument des appels os.system

Directives
  • Utilisez le modèle ci-dessous et notez :
  • dans le prédicat isSource, affinez la variable source pour qu'elle soit du type RemoteFlowSource.
  • dans le prédicat isSink, affinez la variable sink pour qu'elle soit le premier argument d'un appel os.system. Faites-le en utilisant le mécanisme exists et votre classe OsSystemSink.
    • exists est un mécanisme pour introduire des variables temporaires avec une portée restreinte. Vous pouvez les considérer comme leur propre from-where-select. Dans ce cas, utilisez exists pour introduire la variable call de type OsSystemSink, puis affinez sink pour être le premier argument de .
```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 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>Solution</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"

Exercices bonus, si le temps le permet

7. Interroger la base de code avec les requêtes par défaut

Les requêtes CodeQL pour Python se trouvent dans le dossier ql/python/ql/src/Security. Il existe déjà des requêtes pour les vulnérabilités les plus courantes : injection SQL, injection de commandes, injection de code, etc. Exécutez la requête d'injection SQL (CWE-089) sur la base de données de test (vous devrez la sélectionner dans l'extension CodeQL > Bases de données. Notez la coche).

💡 Ceci est très intéressant pour les chercheurs en sécurité – en utilisant les requêtes par défaut, nous pouvons obtenir une idée générale des potentielles vulnérabilités qui pourraient exister dans un projet donné.

8. Exécuter vos propres requêtes à l'aide de l'analyse multi-dépôts (MRVA)

La puissance de CodeQL réside dans la possibilité de réutiliser les requêtes et les modèles CodeQL pour les exécuter sur n'importe quelle base de code dans le même langage. Nous pouvons exécuter des requêtes CodeQL sur jusqu'à 1000 dépôts à la fois en utilisant l'analyse multi-dépôts (MRVA). Les projets doivent être hébergés sur GitHub.

💡 Ceci est très intéressant pour les chercheurs en sécurité – si vous avez trouvé une source ou un puits potentiellement dangereux, vous pouvez l'ajouter à CodeQL (ou l'exécuter comme une requête) et faire vos recherches sur un millier de dépôts à la fois.

  • Suivez la configuration dans la documentation.
  • Notez que MRVA s'exécute à l'aide de workflows GitHub Actions. Les workflows Actions sont gratuits sur les dépôts publics, et payants sur les dépôts privés.
  • Après la configuration, faites un clic droit et choisissez "CodeQL: Run Variant Analysis".

Remarques finales

Aujourd'hui, vous avez appris à explorer une base de code à l'aide de CodeQL et à utiliser CodeQL dans votre propre flux de travail de recherche en sécurité.

Consultez ces ressources si vous souhaitez en savoir plus sur :

  • l'analyse statique et son fonctionnement :
    • CodeQL zero to hero partie 1 : les fondamentaux de l'analyse statique pour la recherche de vulnérabilités.
  • les fondamentaux de l'utilisation de CodeQL et de son langage de requête :
    • CodeQL zero to hero partie 2 : prise en main de CodeQL.
  • la recherche en sécurité avec CodeQL :
    • CodeQL zero to hero partie 3 : recherche en sécurité.
  • Comment modéliser CodeQL pour un framework web sur l'exemple de Gradio
    • CodeQL zero to hero partie 4 : étude de cas Gradio.
  • Déboguer pourquoi une requête pourrait ne pas fonctionner :
    • CodeQL zero to hero partie 5 : débogage des requêtes

Si vous finissez par trouver une vulnérabilité à l'aide de CodeQL, n'hésitez pas à l'ajouter au CodeQL Wall of Fame.

Télécharger l’outil
API::moduleImport()
os.system
getACall()

Remplissez le modèle :```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>Solution</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