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/izar/pytm
Analyse des VulnérabilitésDevSecOpsRenseignement sur les MenacesApprentissage et Éducation
GitHubizar/pytm

pytm

Un framework Pythonic pour la modélisation des menaces

Voir le dépôt
221il y a 6 joursVérifié par Kitploit

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

build+test OpenSSF Best Practices

pytm : Un framework Pythonique pour la modélisation des menaces

logo pytm

Introduction

La modélisation traditionnelle des menaces arrive trop souvent en retard, ou parfois pas du tout. De plus, créer des flux de données et des rapports manuellement peut être extrêmement chronophage. L'objectif de pytm est de déplacer la modélisation des menaces vers la gauche, en la rendant plus automatisée et centrée sur le développeur.

Fonctionnalités

En fonction de votre entrée et de la définition de la conception architecturale, pytm peut générer automatiquement les éléments suivants :

  • Diagramme de flux de données (DFD)
  • Diagramme de séquence
  • Menaces pertinentes pour votre système

Prérequis

  • Linux/MacOS
  • Python 3.11+
  • Paquet Graphviz
  • Java (OpenJDK 10 ou 11)
  • plantuml.jar

Pour commencer

Le fichier tm.py est un modèle exemple. Vous pouvez l'exécuter pour générer le rapport et les fichiers d'images de diagramme auxquels il fait référence :``` mkdir -p tm ./tm.py --report docs/basic_template.md | pandoc -f markdown -t html > tm/report.html ./tm.py --dfd | dot -Tpng -o tm/dfd.png ./tm.py --seq | java -Djava.awt.headless=true -jar $PLANTUML_PATH -tpng -pipe > tm/seq.png

root@kitploit:~
Il y a aussi un exemple de `Makefile` qui regroupe tout cela en cibles pouvant être facilement partagées pour plusieurs modèles. Si vous avez [GNU make](https://www.gnu.org/software/make/) installé (disponible par défaut sur les distributions Linux mais pas sur OSX), exécutez simplement :```
make MODEL=the_name_of_your_model_minus_.py

Vous devez soit avoir plantuml.jar dans le même répertoire que votre modèle, soit définir PLANTUML_PATH. Pour éviter d'installer toutes les dépendances, comme pandoc ou Java, le script peut être exécuté dans un conteneur :```

do this only once

export USE_DOCKER=true make image

call this after every change in your model

make

root@kitploit:~
### Prise en main - Variante Devbox

Pour simplifier l'utilisation de `pytm`, les dépendances de l'hôte peuvent être complètement isolées en utilisant [`Devbox`](https://github.com/jetify-com/devbox). C'est généralement une alternative moins lourde et plus pratique que l'approche par conteneur OCI.

- Installer Devbox sur Linux/MacOS : `curl -fsSL https://get.jetify.com/devbox | bash`
- Installer Devbox sur [Windows/WSL](https://www.jetify.com/docs/devbox/installing-devbox/index#installing-wsl2)
- Mettre à jour vers la dernière version de devbox : `devbox version update`
- Définir votre jeton d'accès GitHub dans le fichier `~/.config/nix/nix.conf` : `access-tokens = github.com=YOUR_TOKEN_HERE`
- Créer un nouvel environnement shell isolé qui inclut tous les outils et paquets spécifiés dans le fichier `devbox.json` du projet : `devbox shell`
- Afficher le chemin complet vers l'exécutable Python qui sera utilisé lorsque vous tapez simplement `python` dans votre terminal en utilisant la commande `which python`. La sortie doit être le chemin suivant :  `.devbox/nix/profile/default/bin/python`
- Tester en exécutant la commande suivante, qui devrait générer un DFD sous forme de fichier PNG appelé `sample.png` :  `./tm.py --dfd | dot -Tpng -o sample.png`
- Quitter l'environnement shell Devbox : `exit`

## Utilisation

Tous les arguments disponibles :```text
usage: tm.py [-h] [--debug] [--dfd] [--report REPORT]
             [--exclude EXCLUDE] [--seq] [--list] [--describe DESCRIBE]
             [--list-elements] [--json JSON] [--levels LEVELS [LEVELS ...]]
             [--stale_days STALE_DAYS]

optional arguments:
  -h, --help            show this help message and exit
  --debug               print debug messages
  --dfd                 output DFD
  --report REPORT       output report using the named template file (sample
                        template file is under docs/template.md)
  --exclude EXCLUDE     specify threat IDs to be ignored
  --seq                 output sequential diagram
  --list                list all available threats
  --colormap            color the risk in the diagram
  --describe DESCRIBE   describe the properties available for a given element
  --list-elements       list all elements which can be part of a threat model
  --json JSON           output a JSON file
  --levels LEVELS [LEVELS ...]
                        Select levels to be drawn in the threat model (int
                        separated by comma).
  --stale_days STALE_DAYS
                        checks if the delta between the TM script and the code
                        described by it is bigger than the specified value in
                        days

L'argument stale_days tente de déterminer l'écart en jours entre le script de modèle (que vous écrivez) et le code qui implémente le système modélisé. Idéalement, ils devraient être assez proches dans la plupart des cas d'un système en développement actif. Vous pouvez exécuter cela périodiquement pour mesurer le pouls de votre projet et la 'fraîcheur' de votre modèle de menace.

Les éléments actuellement disponibles sont : TM, Element, Server, ExternalEntity, Datastore, Actor, Process, SetOfProcesses, Dataflow, Boundary, Lambda, LLM et Agent.

Les propriétés disponibles d'un élément peuvent être listées en utilisant --describe suivi du nom d'un élément :```text

(pytm) ➜ pytm git:(master) ✗ ./tm.py --describe Element Element class attributes: OS definesConnectionTimeout default: False description handlesResources default: False implementsAuthenticationScheme default: False implementsNonce default: False inBoundary inScope Is the element in scope of the threat model, default: True isAdmin default: False isHardened default: False name required onAWS default: False

root@kitploit:~
L'argument *colormap*, utilisé avec *dfd*, produit un DFD codé en couleur où les éléments sont colorés en rouge, jaune ou vert en fonction de leur niveau de risque (identifié par l'exécution des règles).

## Usage - Devbox Variant

- `devbox shell`
- utilisation de `pytm` comme d'habitude
- `exit`

## Creating a Threat Model

Voici un exemple de fichier `tm.py` qui décrit une application simple où un utilisateur se connecte à l'application et publie des commentaires sur l'app. Le serveur de l'application stocke ces commentaires dans la base de données. Il y a une AWS Lambda qui nettoie périodiquement la base de données.```python

#!/usr/bin/env python3

from pytm import TM, Server, Datastore, Dataflow, Boundary, Actor, Lambda, LLM, Data, Classification

tm = TM("my test tm")
tm.description = "another test tm"
tm.isOrdered = True

User_Web = Boundary("User/Web")
Web_DB = Boundary("Web/DB")

user = Actor("User")
user.inBoundary = User_Web

web = Server("Web Server")
web.OS = "CloudOS"
web.isHardened = True
web.sourceCode = "server/web.cc"

db = Datastore("SQL Database (*)")
db.OS = "CentOS"
db.isHardened = False
db.inBoundary = Web_DB
db.isSql = True
db.inScope = False
db.sourceCode = "model/schema.sql"

comments = Data(
    name="Comments", 
    description="Comments in HTML or Markdown",  
    classification=Classification.PUBLIC,  
    isPII=False,
    isCredentials=False,  
    # credentialsLife=Lifetime.LONG,  
    isStored=True, 
    isSourceEncryptedAtRest=False, 
    isDestEncryptedAtRest=True 
)

results = Data(
    name="results", 
    description="Results of insert op",  
    classification=Classification.SENSITIVE,  
    isPII=False, 
    isCredentials=False,  
    # credentialsLife=Lifetime.LONG,  
    isStored=True, 
    isSourceEncryptedAtRest=False, 
    isDestEncryptedAtRest=True 
)

my_lambda = Lambda("cleanDBevery6hours")
my_lambda.hasAccessControl = True
my_lambda.inBoundary = Web_DB

llm_api = LLM("AI Writing Assistant")
llm_api.isThirdParty = True
llm_api.processesPersonalData = True
llm_api.hasContentFiltering = False
llm_api.hasSystemPrompt = True
llm_api.processesUntrustedInput = True

my_lambda_to_db = Dataflow(my_lambda, db, "(λ)Periodically cleans DB")
my_lambda_to_db.protocol = "SQL"
my_lambda_to_db.dstPort = 3306

user_to_web = Dataflow(user, web, "User enters comments (*)")
user_to_web.protocol = "HTTP"
user_to_web.dstPort = 80
user_to_web.data = comments

web_to_user = Dataflow(web, user, "Comments saved (*)")
web_to_user.protocol = "HTTP"

web_to_db = Dataflow(web, db, "Insert query with comments")
web_to_db.protocol = "MySQL"
web_to_db.dstPort = 3306

db_to_web = Dataflow(db, web, "Comments contents")
db_to_web.protocol = "MySQL"
db_to_web.data = results

web_to_llm = Dataflow(web, llm_api, "Chat completion request")
web_to_llm.protocol = "HTTPS"
web_to_llm.dstPort = 443

tm.process()

Vous avez également la possibilité d'utiliser pytmGPT pour créer vos modèles à partir de prose !

Générer des diagrammes

Les diagrammes sont produits au format Dot et PlantUML.

Lorsque l'argument --dfd est passé au fichier tm.py ci-dessus, il génère une sortie sur stdout, qui est ensuite transmise à dot de Graphviz pour générer le diagramme de flux de données :```bash

tm.py --dfd | dot -Tpng -o sample.png

root@kitploit:~
Génère ce diagramme :

dfd.png

Ajouter les attributs ".levels = [1,2]" à un élément le fera (ainsi que ses flux de données associés si les deux extrémités des flux sont dans le même niveau DFD) s'afficher (ou non) en fonction de l'argument de commande "--levels 1 2".

La commande suivante génère un diagramme de séquence.```bash

tm.py --seq | java -Djava.awt.headless=true -jar plantuml.jar -tpng -pipe > seq.png

Génère ce diagramme :

seq.png

Création d'un rapport

Les diagrammes et les résultats peuvent être inclus dans le modèle pour créer un rapport final :```bash

tm.py --report docs/basic_template.md | pandoc -f markdown -t html > report.html

root@kitploit:~
Le format de template utilisé dans le modèle de rapport est très simple :```text

# Threat Model Sample
***

## System Description

{tm.description}

## Dataflow Diagram

![Level 0 DFD](https://raw.githubusercontent.com/izar/pytm/HEAD/dfd.png)

## Dataflows

Name|From|To |Data|Protocol|Port
----|----|---|----|--------|----
{dataflows:repeat:{{item.name}}|{{item.source.name}}|{{item.sink.name}}|{{item.data}}|{{item.protocol}}|{{item.dstPort}}
}

## Findings

{findings:repeat:* {{item.description}} on element "{{item.target}}"
}

Pour regrouper les résultats par éléments, utilisez une boucle imbriquée plus avancée :```text

Findings

{elements🔁{{item.findings:if:

{{item.name}}

{{item.findings🔁 Threat: {{{{item.id}}}} - {{{{item.description}}}}

Severity: {{{{item.severity}}}}

Mitigations: {{{{item.mitigations}}}}

References: {{{{item.references}}}}

}}}}}

root@kitploit:~
Tous les éléments à l'intérieur d'une boucle doivent être échappés, en doublant les accolades, donc `{item.name}` devient `{{item.name}}`.
L'exemple ci-dessus utilise deux boucles imbriquées, donc les éléments de la boucle interne doivent être échappés deux fois, c'est pourquoi ils utilisent quatre accolades.

### Surcharges

Vous pouvez remplacer les attributs des constatations (menaces correspondant aux actifs du modèle et/ou aux flux de données), par exemple pour définir un score CVSS personnalisé et/ou un texte de réponse :```python
user_to_web = Dataflow(user, web, "User enters comments (*)", protocol="HTTP", dstPort="80")
user_to_web.overrides = [
    Finding(
        # Overflow Buffers
        threat_id="INP02",
        cvss="9.3",
        response="""**To Mitigate**: run a memory sanitizer to validate the binary""",
        severity="Very High",
    )
]

Si vous ajoutez un Finding, assurez-vous d'ajouter une sévérité : "Very High", "High", "Medium", "Low", "Very Low".

Base de données des menaces

Pour le praticien de la sécurité, vous pouvez fournir votre propre fichier de menaces en définissant TM.threatsFile. Il doit contenir des entrées comme :```json { "SID":"INP01", "target": ["Lambda","Process"], "description": "Buffer Overflow via Environment Variables", "details": "This attack pattern involves causing a buffer overflow through manipulation of environment variables. Once the attacker finds that they can modify an environment variable, they may try to overflow associated buffers. This attack leverages implicit trust often placed in environment variables.", "Likelihood Of Attack": "High", "severity": "High", "condition": "target.usesEnvironmentVariables is True and target.controls.sanitizesInput is False and target.controls.checksInputBounds is False", "prerequisites": "The application uses environment variables.An environment variable exposed to the user is vulnerable to a buffer overflow.The vulnerable environment variable uses untrusted data.Tainted data used in the environment variables is not properly validated. For instance boundary checking is not done before copying the input data to a buffer.", "mitigations": "Do not expose environment variable to the user.Do not use untrusted data in your environment variables. Use a language or compiler that performs automatic bounds checking. There are tools such as Sharefuzz [R.10.3] which is an environment variable fuzzer for Unix that support loading a shared library. You can use Sharefuzz to determine if you are exposing an environment variable vulnerable to buffer overflow.", "example": "Attack Example: Buffer Overflow in $HOME A buffer overflow in sccw allows local users to gain root access via the $HOME environmental variable. Attack Example: Buffer Overflow in TERM A buffer overflow in the rlogin program involves its consumption of the TERM environmental variable.", "references": "https://capec.mitre.org/data/definitions/10.html, CVE-1999-0906, CVE-1999-0046, http://cwe.mitre.org/data/definitions/120.html, http://cwe.mitre.org/data/definitions/119.html, http://cwe.mitre.org/data/definitions/680.html" }

root@kitploit:~
Le champ `target` liste les classes d'éléments de modèle à faire correspondre à cette menace.
Cela peut être des actifs (assets), comme : Actor, Datastore, Server, Process, SetOfProcesses, ExternalEntity, Lambda, LLM, Agent ou Element, qui est la classe de base et correspond à tout élément. Il peut aussi s'agir d'un Dataflow qui relie deux actifs.

Tous les autres champs (sauf `condition`) sont disponibles pour l'affichage et peuvent être utilisés dans le modèle pour lister les constatations (findings) dans le [rapport](#report) final.

> **ATTENTION**
>
> Le fichier `threats.json` contient des chaînes qui sont exécutées via `eval()`. Assurez-vous que le fichier a les permissions correctes, sinon vous risquez qu'un attaquant modifie les chaînes et vous amène à exécuter du code pour son compte.

La logique réside dans `condition`, où les membres de `target` peuvent être évalués logiquement.
Renvoyer vrai (true) signifie que la règle génère une constatation, sinon ce n'est pas une constatation.
La condition peut comparer des attributs de `target` et/ou des attributs de contrôle de `target.control` et également appeler l'une de ces méthodes :

* `target.oneOf(class, ...)` où `class` est un ou plusieurs : Actor, Datastore, Server, Process, SetOfProcesses, ExternalEntity, Lambda, LLM, Agent ou Dataflow,
* `target.crosses(Boundary)`,
* `target.enters(Boundary)`,
* `target.exits(Boundary)`,
* `target.inside(Boundary)`.

Si `target` est un Dataflow, rappelez-vous que vous pouvez accéder à `target.source` et/ou `target.sink` ainsi qu'à d'autres attributs.

Les conditions sur les actifs peuvent analyser tous les Dataflows entrants et sortants en inspectant les attributs `target.input` et `target.output`. Par exemple, pour cibler une menace uniquement contre les serveurs ayant du trafic entrant, utilisez `any(target.inputs)`. Un exemple plus avancé, pour cibler les éléments se connectant à des datastores SQL, serait `any(f.sink.oneOf(Datastore) and f.sink.isSQL for f in target.outputs)`.

## Importing from JSON

Avec un peu de code Python, il est possible d'importer un modèle de menace depuis un fichier JSON (notez le format spécial dans l'exemple fourni dans `tests/input.json`). L'exemple suivant importe l'exemple `input.json` présent dans les tests. Enregistrez le code suivant sous `tm2.py`.```python

#!/usr/bin/env python3
# Example tm2.py contents
# Run: python tm2.py --dfd | dot -Tpng -o sample_json.png

from pytm import (
    TM,
    Actor,
    Boundary,
    Classification,
    Data,
    Dataflow,
    Datastore,
    Lambda,
    Server,
    DatastoreType,
    Assumption,
    load,
)

json_file_string = './tests/input.json'
with open(json_file_string) as input_json:
    TM.reset()
    tm = load(input_json)
    tm.process()

Nous pouvons appeler tm2.py de la même manière qu'avant, ici avec --dfd puis rediriger la sortie vers Graphviz (dot):```bash

python tm2.py --dfd | dot -Tpng -o sample_json.png

root@kitploit:~
## Créer des diapositives !

Une fois le modèle de menace terminé et prêt, la redoutée étape de présentation arrive - et pytm peut maintenant vous y aider aussi, avec un modèle qui exprime votre modèle de menace sous forme de diapositives, en utilisant la puissance de (RevealMD)[https://github.com/webpro/reveal-md] ! Il suffit d'utiliser le modèle docs/revealjs.md et vous obtiendrez de jolies diapositives, entièrement configurables, que vous pouvez présenter et partager depuis votre navigateur.

https://github.com/izar/pytm/assets/368769/30218241-c7cc-4085-91e9-bbec2843f838

## Menaces actuellement prises en charge```text
INP01 - Buffer Overflow via Environment Variables
INP02 - Overflow Buffers
INP03 - Server Side Include (SSI) Injection
CR01 - Session Sidejacking
INP04 - HTTP Request Splitting
CR02 - Cross Site Tracing
INP05 - Command Line Execution through SQL Injection
INP06 - SQL Injection through SOAP Parameter Tampering
SC01 - JSON Hijacking (aka JavaScript Hijacking)
LB01 - API Manipulation
AA01 - Authentication Abuse/ByPass
DS01 - Excavation
DE01 - Interception
DE02 - Double Encoding
API01 - Exploit Test APIs
AC01 - Privilege Abuse
INP07 - Buffer Manipulation
AC02 - Shared Data Manipulation
DO01 - Flooding
HA01 - Path Traversal
AC03 - Subverting Environment Variable Values
DO02 - Excessive Allocation
DS02 - Try All Common Switches
INP08 - Format String Injection
INP09 - LDAP Injection
INP10 - Parameter Injection
INP11 - Relative Path Traversal
INP12 - Client-side Injection-induced Buffer Overflow
AC04 - XML Schema Poisoning
DO03 - XML Ping of the Death
AC05 - Content Spoofing
INP13 - Command Delimiters
INP14 - Input Data Manipulation
DE03 - Sniffing Attacks
CR03 - Dictionary-based Password Attack
API02 - Exploit Script-Based APIs
HA02 - White Box Reverse Engineering
DS03 - Footprinting
AC06 - Using Malicious Files
HA03 - Web Application Fingerprinting
SC02 - XSS Targeting Non-Script Elements
AC07 - Exploiting Incorrectly Configured Access Control Security Levels
INP15 - IMAP/SMTP Command Injection
HA04 - Reverse Engineering
SC03 - Embedding Scripts within Scripts
INP16 - PHP Remote File Inclusion
AA02 - Principal Spoof
CR04 - Session Credential Falsification through Forging
DO04 - XML Entity Expansion
DS04 - XSS Targeting Error Pages
SC04 - XSS Using Alternate Syntax
CR05 - Encryption Brute Forcing
AC08 - Manipulate Registry Information
DS05 - Lifting Sensitive Data Embedded in Cache
SC05 - Removing Important Client Functionality
INP17 - XSS Using MIME Type Mismatch
AA03 - Exploitation of Trusted Credentials
AC09 - Functionality Misuse
INP18 - Fuzzing and observing application log data/errors for application mapping
CR06 - Communication Channel Manipulation
AC10 - Exploiting Incorrectly Configured SSL
CR07 - XML Routing Detour Attacks
AA04 - Exploiting Trust in Client
CR08 - Client-Server Protocol Manipulation
INP19 - XML External Entities Blowup
INP20 - iFrame Overlay
AC11 - Session Credential Falsification through Manipulation
INP21 - DTD Injection
INP22 - XML Attribute Blowup
INP23 - File Content Injection
DO05 - XML Nested Payloads
AC12 - Privilege Escalation
AC13 - Hijacking a privileged process
AC14 - Catching exception throw/signal from privileged block
INP24 - Filter Failure through Buffer Overflow
INP25 - Resource Injection
INP26 - Code Injection
INP27 - XSS Targeting HTML Attributes
INP28 - XSS Targeting URI Placeholders
INP29 - XSS Using Doubled Characters
INP30 - XSS Using Invalid Characters
INP31 - Command Injection
INP32 - XML Injection
INP33 - Remote Code Inclusion
INP34 - SOAP Array Overflow
INP35 - Leverage Alternate Encoding
DE04 - Audit Log Manipulation
AC15 - Schema Poisoning
INP36 - HTTP Response Smuggling
INP37 - HTTP Request Smuggling
INP38 - DOM-Based XSS
AC16 - Session Credential Falsification through Prediction
INP39 - Reflected XSS
INP40 - Stored XSS
AC17 - Session Hijacking - ServerSide
AC18 - Session Hijacking - ClientSide
INP41 - Argument Injection
AC19 - Reusing Session IDs (aka Session Replay) - ServerSide
AC20 - Reusing Session IDs (aka Session Replay) - ClientSide
AC21 - Cross Site Request Forgery
DS06 - Data Leak
DR01 - Unprotected Sensitive Data
AC22 - Credentials Aging (deprecated)
AC23 - Credentials Disclosure
AC24 - Use of hardcoded credentials
LLM01 - Direct Prompt Injection
LLM02 - Indirect Prompt Injection via Retrieved Content
LLM03 - Sensitive Data Leakage to Third-Party Provider
LLM04 - Training Data Poisoning
LLM05 - Excessive Agency via Unauthorized Tool Use
LLM06 - Arbitrary Code Execution via LLM Agent
LLM07 - Jailbreaking and Safety Bypass
LLM08 - Sensitive Information Disclosure Through Output
LLM09 - Untrusted Tool Launch Configuration


Télécharger l’outil