hackingBuddyGPT : un cadre Python pour agents de test d'intrusion pilotés par LLM
Helping Ethical Hackers use LLMs in 50 Lines of Code or less..
En bref
- De quoi s’agit-il ?
- Le dépôt ipa-lab/hackingBuddyGPT fournit la plomberie nécessaire pour écrire un cas d'usage offensif en quelques dizaines de lignes, avec des limites de coût et des traces JSONL. Le cadre impose Python 3.13 et exécute de vraies commandes sur de vraies machines, ce qui restreint sérieusement son terrain de jeu.
- À qui s’adresse-t-il ?
- À adopter si vous êtes chercheur ou pentester et que vous voulez prototyper un agent offensif sans réécrire la gestion du LLM, des sessions et des limites de budget. À éviter si vous cherchez un scanner prêt à l'emploi ou si vous ne pouvez pas aligner Python 3.13 sur votre parc.
- Puis-je l’utiliser commercialement ?
- Oui. MIT est une licence permissive : vous pouvez utiliser, modifier et vendre un logiciel qui en dépend, à condition de conserver les mentions de droit d’auteur et de licence.
- Est-il encore maintenu ?
- Oui. Les derniers commits datent d’il y a 3 jours.
- En quel langage est-il écrit ?
- Principalement Python, d’après les statistiques de langage de GitHub.
Ces réponses reposent sur les données GitHub du projet (dernière synchronisation le 15 septembre 2026) et sur notre analyse. Elles ne constituent pas un avis juridique.
ANALYSE OPEN SOURCE APPROFONDIE
Ce que le dépôt enlève du chemin critique
Écrire un agent offensif à base de LLM implique de résoudre des problèmes qui n'ont rien de passionnant : se connecter à un fournisseur de modèle, garder une session ouverte sur la cible, décider quand s'arrêter, journaliser ce qui s'est passé. hackingBuddyGPT existe pour que ces briques soient déjà là. Le README annonce la couleur : connectivité LLM, connecteurs de cible (SSH, shell local, psexec de type WinRM), câblage des capacités et des outils, limites d'exécution, journalisation structurée. Le public visé est explicite, chercheurs en sécurité et pentesters qui veulent tester une hypothèse sur les LLM appliqués aux tests d'intrusion, pas administrateurs cherchant un scanner clé en main. La promesse tient dans une phrase du dépôt : exprimer une nouvelle expérience, un cas d'usage, en quelques dizaines de lignes. Cette promesse n'a de sens que parce que le reste est mutualisé.
Deux boucles d'agent sous une même interface
Le cadre propose deux styles d'exécution. Le premier, illustré par MinimalPrivEscLinux, est une stratégie textuelle : un gabarit Mako injecte tout l'historique dans un seul prompt à chaque tour, la réponse est analysée pour en extraire une commande brute, qui est exécutée sur la cible. Le second, MinimalToolCallPrivEscLinux, conserve un véritable historique de conversation et pilote la cible par appels de fonctions. La différence n'est pas cosmétique. Dans le mode texte, l'historique est reformaté à chaque tour et le modèle n'a aucune notion d'outil ; dans le mode appels de fonctions, les outils sont déclarés et le modèle choisit lequel invoquer. Le point le plus intéressant du second est la vérification du succès : l'outil task_solved est confronté à la réalité du système, donc un modèle qui déclare avoir obtenu root sans l'avoir fait ne peut pas faire remonter un faux positif. C'est un choix de conception qui coûte de la complexité mais qui rend les résultats exploitables dans un contexte de recherche. Le README présente d'ailleurs MinimalPrivEscLinux comme le point de départ classique, ce qui suggère que le mode texte reste la voie la plus simple pour comprendre la boucle avant de passer aux outils.
Des cas d'usage livrés qui couvrent plusieurs surfaces
Le dépôt ne se limite pas à l'escalade de privilèges sous Linux. La liste des sous-commandes de wintermute couvre quatre familles. Côté privesc : les deux minimalistes déjà cités, PrivEscLinux avec génération augmentée par récupération via --rag_path, chaîne de pensée via --enable_cot, suivi d'état et guidage structuré, puis PrivEscWindows qui passe par psexec, et enfin ExPrivEscLinuxLSE, qui exécute d'abord lse.sh sur la cible, transforme sa sortie en indices, puis orchestre PrivEscLinux pour chaque indice. Ce dernier cas est instructif : un cas d'usage en appelle un autre, ce qui montre que l'unité de composition n'est pas seulement l'outil mais l'expérience entière. Côté web, WebTestingWithExplanation teste une page en HTTP en laissant le modèle verbaliser son raisonnement, avec un playbook de type OWASP ; WebTestingWithShell ajoute un accès shell à une machine attaquante de style Kali ; AdvancedWebTesting adopte une architecture différente, un agent de haut niveau sans accès direct à la cible qui délègue à des sous-agents bornés. Côté API, WebAPITesting détecte la surface, spécification OpenAPI ou plan de site, puis travaille en mode document, test ou auto. Côté Active Directory, AD reprend l'outil cochise avec un planificateur persistant qui maintient un arbre de tâches et une base de connaissances partagée, chaque tâche étant confiée à un exécutant tactique neuf et sans mémoire. Ce dernier design mérite qu'on s'y arrête : la mémoire est délibérément concentrée dans le planificateur, pas dans les exécutants, ce qui évite qu'un contexte pollué par des échecs successifs dégrade les décisions suivantes.
Mise en route : les commandes du README
L'installation suppose Python 3.13 ou plus récent et s'appuie sur le backend de build uv. Le README donne la séquence suivante : git clone du dépôt puis cd, uv sync et activation de .venv, copie de .env.example vers .env pour y placer la clé du modèle et la cible, puis exécution de wintermute sans argument pour lister les cas d'usage enregistrés. Un lancement typique ressemble à wintermute MinimalPrivEscLinux --conn=ssh --conn.host=192.168.122.151 --conn.username=lowpriv --conn.password=trustno1. L'aide par cas d'usage s'obtient avec wintermute <UseCase> --help. Les limites d'exécution sont exposées sous forme de clés uniques : --limits.max_rounds, --limits.max_tokens, --limits.max_cost et --limits.max_duration. Le fournisseur se choisit via la chaîne llm.model, litellm servant de couche d'accès unique, OpenRouter étant l'endpoint par défaut d'après le README. Le trafic peut être routé par un proxy d'interception, Burp ou mitmproxy, avec --llm.proxy. Ces options sont cohérentes entre elles : on peut plafonner un run en dollars et en durée en même temps, ce qui est rare dans les projets de ce genre et évite les mauvaises surprises sur une facture d'API.
Ce que le cadre ne protège pas
Le README contient un avertissement qu'il faut prendre au pied de la lettre : le logiciel exécute de vraies commandes sur des systèmes en production. En mode shell local, ces commandes s'exécutent sur votre propre machine ; en mode SSH ou psexec, sur la cible que vous désignez. Aucun bac à sable n'est mentionné. Le cadre fournit des limites de tours, de jetons, de coût et de durée, mais rien n'empêche une commande destructive d'être exécutée au premier tour si le modèle la propose et si la cible l'accepte. C'est une différence importante avec des outils qui simulent l'exécution ou qui imposent une validation humaine avant chaque action. Autre limite : la vérification du succès par ground truth n'est mentionnée que pour l'escalade de privilèges. Pour WebTestingWithExplanation, WebTestingWithShell, AdvancedWebTesting ou WebAPITesting, le README ne décrit pas de mécanisme équivalent, donc la question de savoir comment un succès est établi sur ces surfaces reste ouverte dans la documentation fournie. Enfin, le projet impose Python 3.13, une version récente ; sur un parc où cette version n'est pas disponible, l'installation demande soit uv, soit une gestion d'environnement dédiée. Ce n'est pas un détail pour une équipe qui voudrait l'intégrer à une chaîne d'intégration continue existante.
Traces JSONL et comparaison avec un script maison
Chaque exécution est écrite sous forme de trace JSONL OpenTelemetry/GenAI, en ajout seul, et le dépôt fournit des outils en ligne de commande pour rejouer et agréger les runs. C'est le point qui distingue le plus ce cadre d'un script personnel de cent lignes qui appelle une API de modèle en boucle. Un script maison journalise ce qu'on pense à journaliser ; ici le format est fixé et des outils de relecture existent déjà. Pour de la recherche reproductible, l'écart est réel. Le dépôt maintient d'ailleurs un benchmark d'escalade de privilèges Linux dans un dépôt séparé, benchmark-privesc-linux, et un lanceur de benchmark sur flotte Docker pour les tests de régression contre de nombreuses cibles simultanément. Un script maison n'offre rien de tout cela. En contrepartie, un script maison se lit en une soirée et ne dépend d'aucune abstraction : ni litellm, ni asyncio, ni structure de cas d'usage à respecter. Si votre besoin est d'appeler un modèle une fois pour classer une sortie de nmap, le cadre est disproportionné. Si votre besoin est de comparer trois modèles sur la même tâche avec des limites de coût identiques et des traces comparables, il fait gagner un temps considérable.
Coût de maintenance et licence
Le projet est publié sous licence MIT, ce qui autorise la réutilisation, la modification et la redistribution, y compris dans un contexte commercial, à condition de conserver l'avis de licence. Le README ne signale aucune clause supplémentaire ni restriction d'usage ; c'est donc à vous d'encadrer contractuellement et légalement vos tests, la licence ne couvrant évidemment pas l'autorisation d'attaquer un système. Sur le rythme de publication, les versions récentes listées sont v0.5.0 en août 2025, v0.4.0 en avril 2025 et v0.3.0 en août 2024 : deux livraisons en 2025 contre une seule en 2024, ce qui suggère une cadence qui s'accélère, sans qu'on puisse en déduire une politique de support à long terme. Le coût de mise à jour tient surtout à la dépendance à litellm et à la contrainte Python 3.13+. Comme litellm sert de couche unique vers les fournisseurs, un changement d'API côté fournisseur se règle normalement par une mise à jour de cette dépendance plutôt que par une modification de votre cas d'usage. À l'inverse, si vous écrivez beaucoup de cas d'usage contre les capacités internes du cadre et que celles-ci évoluent entre deux versions mineures, la migration peut demander du travail. Le dépôt ne publie pas, dans les éléments fournis, d'engagement de compatibilité ascendante entre versions.
Conclusion éditoriale
À adopter si vous êtes chercheur ou pentester et que vous voulez prototyper un agent offensif sans réécrire la gestion du LLM, des sessions et des limites de budget. À éviter si vous cherchez un scanner prêt à l'emploi ou si vous ne pouvez pas aligner Python 3.13 sur votre parc. Avant tout essai, lisez le fichier .env.example et la sortie de wintermute <UseCase> --help, puis vérifiez que le modèle que vous comptez utiliser accepte le tool calling, faute de quoi MinimalToolCallPrivEscLinux et sa vérification de succès ne fonctionneront pas.
Notes de la communauté