bloodhound
Enables users to query BloodHound Active Directory graph data using natural language, finding attack paths, Kerberoastable accounts, and other AD security insights.
README
Agent BloodHound
Un assistant Claude qui répond en langage naturel (FR/EN) à tes questions sur un audit Active Directory. Tu demandes « quels comptes sont Kerberoastables ? » ou « un chemin de sansa.stark vers les Domain Admins ? », il interroge le graphe et répond avec des tableaux clairs et les chemins d'attaque.
Nouveau sur le sujet ? BloodHound cartographie un Active Directory en graphe (utilisateurs, groupes, machines, droits) pour révéler les chemins qu'un attaquant emprunterait. SharpHound collecte les données (un
.zipde JSON). Cet agent lit ce graphe et l'explique. Usage : test d'intrusion autorisé ou labo.
Capacités
L'agent choisit lui-même l'outil adapté — tu poses juste la question :
- Credentials — Kerberoastables, AS-REP roastables, lecteurs LAPS / gMSA.
- Chemins d'attaque — vers Domain Admins / tier-0 (
paths_to_tier0), entre deux objets, portée (blast_radius). Ne traverse que les edges abusables (les edges structurelsContains/GPLinksont exclus → pas de faux chemins). - Privilèges — DCSync, délégations (non contrainte, contrainte, RBCD), abus d'ACL.
- Triage — profil de sécurité d'un objet (attributs vérifiés, qui le contrôle, distance au tier-0), détails, recherche.
- Domaine / forêt — Domain Admins (imbriqués), Domain Controllers, relations de confiance, objets tier-0.
- Owned — marque des comptes compromis, puis « chemins depuis owned ».
Toutes les requêtes sont en lecture seule et auditées (runs/audit.log).
Prérequis
| Outil | Pourquoi | Vérifier / installer |
|---|---|---|
| Docker (ou OrbStack) | Bases de BloodHound | docker --version. Sinon Docker Desktop / OrbStack. Doit être lancé. |
| Python 3.10+ | Faire tourner l'agent | python3 --version. Sinon python.org ou brew install python@3.12. |
Claude Code (CLI claude) |
L'agent utilise Claude | Connexion au 1er lancement — pas de claude login séparé à taper. |
Installation
Trois voies. Toutes ont besoin d'un BloodHound CE avec des données : l'option B
(setup.sh) met tout en place pour toi (et peut charger un jeu de démo) ; les options
A et C supposent que la base tourne déjà (voir Charger des données).
Option A — Plugin Claude Code (marketplace)
À privilégier si tu utilises déjà Claude Code et as un BloodHound CE qui tourne. Le
dépôt est un plugin distribuable : serveur MCP bloodhound (23 outils lecture
seule, qui crée son propre venv au 1er lancement) + une compétence analyste (SKILL.md).
Dans Claude Code :
/plugin marketplace add The-bub/Agent-BloodHound # depuis GitHub
/plugin install bloodhound@agent-bloodhound
(Ou depuis un clone local : /plugin marketplace add /chemin/vers/Agent-BloodHound.)
marketplace addenregistre le catalogue ;installcopie le plugin et propose un scope (projet / utilisateur) — confirme-le.- Si Claude affiche « Run /reload-plugins to activate », lance
/reload-plugins. - À la 1re requête, approuve le serveur MCP « bloodhound ». Ce premier appel prend ~10 s (création du venv du plugin).
Gérer : /plugin (activer / désactiver), /plugin marketplace update (nouvelle
version). Neo4j non standard ? Définis NEO4J_URI / NEO4J_USER / NEO4J_PASSWORD
dans l'environnement où tu lances claude.
Option B — En local avec setup.sh (turnkey)
À privilégier si tu pars de zéro : monte les bases, l'environnement Python et (optionnel) les données de démo, puis ouvre Claude Code.
cd /Users/eliotbedel/Claude/Agent-BloodHound
./setup.sh # bases + venv + (option) données de démo GOAD
./bloodhound # démarre tout et ouvre Claude Code (connexion au 1er lancement)
./bloodhound relance les bases si besoin et ouvre Claude Code dans le dossier (via
.mcp.json + CLAUDE.md). Discute normalement : Claude appelle les outils et garde
le contexte.
Option C — Python (avancé / scripting)
Pour interroger sans Claude Code (REPL ou one-shot scriptable).
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt # ou: pip install -e . → la commande `bh-agent`
python -m agent.main # REPL (garde le contexte)
python -m agent.main -q "Qui peut faire un DCSync ?" # one-shot
python -m agent.main -q "Détaille le 1er compte" -c # continue le one-shot
python -m agent.main -q "..." --export # + rapport dans runs/
Après pip install -e ., bh-agent remplace python -m agent.main. Commandes du
REPL : help, export (rapport runs/), exit.
Charger des données
Nécessaire pour les options A et C (l'option B setup.sh peut charger la démo à ta
place). Trois méthodes.
Démo GOAD (recommandé pour débuter)
Vrai jeu d'exemple (labo GOAD, 3 domaines) :
mkdir -p demo && cd demo
base="https://github.com/m4lwhere/Bloodhound-CE-Sample-Data/raw/main"
curl -fsSLO "$base/ce_branch_bloodhoundpy_essos_20240411011238_bloodhound.zip"
curl -fsSLO "$base/ce_branch_bloodhoundpy_north_20240411011008_bloodhound.zip"
curl -fsSLO "$base/ce_branch_bloodhoundpy_sevenkingdoms_20240411011059_bloodhound.zip"
cd ..
docker compose logs bloodhound | grep "Initial Password" # mot de passe admin
export BH_ADMIN_PW='COLLE_LE_MOT_DE_PASSE'
python scripts/ce_ingest.py --json-dir demo # dézippe tout seul
Résultat : ~333 objets / ~3300 relations.
Ton extract, via l'interface web
Le plus visuel, sans ligne de commande.
- Collecte — lance SharpHound (Windows) ou
bloodhound.py/ AzureHound ; tu obtiens un.zip(parfois plusieurs). - Connexion — ouvre http://localhost:8080, identifie-toi avec
admin+ le mot de passe des logs (docker compose logs bloodhound | grep "Initial Password"). BloodHound impose un nouveau mot de passe au premier login. - Import — menu Administration → File Ingest, glisse ton (tes)
.zip. - Attente — BloodHound parse puis post-traite (calcul des edges) ; les compteurs montent, le graphe est prêt quand ils se stabilisent.
Tes fichiers locaux, en ligne de commande
Le plus rapide quand les fichiers sont déjà sur disque. Le script les pousse via l'API
CE : il dézippe les .zip tout seul et accepte un dossier mêlant .zip et .json.
docker compose logs bloodhound | grep "Initial Password" # mot de passe admin
export BH_ADMIN_PW='COLLE_LE_MOT_DE_PASSE'
python scripts/ce_ingest.py --json-dir /chemin/vers/mes-extraits # --no-wait pour ne pas attendre
Utiliser l'agent
Une fois installé (n'importe quelle option), pose tes questions en langage naturel. L'agent ne fait pas qu'énumérer : il explique les vulnérabilités et donne les commandes d'exploitation (contexte de test autorisé). Les noms ci-dessous viennent du jeu de démo GOAD.
Exemples de questions
Énumération / cartographie
- Liste les comptes Kerberoastables activés (avec leurs SPN).
- Quels ordinateurs ont une délégation non contrainte ?
- Qui peut faire un DCSync sur chaque domaine ?
- Quels sont les objets tier-0 de la forêt ? Et les Domain Controllers ?
Chemins d'attaque
- Chemin le plus court de jon.snow vers les Domain Admins.
- Depuis sansa.stark, quels sont les chemins vers le tier-0 ?
- Existe-t-il un chemin cross-domain de NORTH vers ESSOS ?
- Si je compromets sql_svc@essos.local, qu'est-ce que j'atteins en 2 sauts ?
Comprendre une vulnérabilité
- Explique le Kerberoasting et pourquoi ces comptes sont exposés.
- C'est quoi l'unconstrained delegation, et pourquoi WINTERFELL est critique ?
- Quelle différence entre DCSync, Golden Ticket et Silver Ticket ?
Demander les commandes d'exploitation
- Donne-moi les commandes pour Kerberoaster jon.snow (Rubeus et impacket).
- Étapes + outils pour abuser l'unconstrained delegation de WINTERFELL.
- Comment cracker le hash récupéré (hashcat) ?
Triage / priorisation
- Fais le profil de sécurité de sansa.stark.
- Qui contrôle l'administrateur du domaine (ACL entrantes dangereuses) ?
- Quels sont les 5 comptes les plus intéressants à compromettre en premier, et pourquoi ?
Owned / post-compromission
- Marque sql_svc comme owned, puis montre les chemins vers le tier-0.
- Depuis mes comptes owned, quel est le chemin le plus court vers les Domain Admins ?
Remédiation (blue team)
- Comment corriger le Kerberoasting sur ces comptes ?
- Quelles priorités de durcissement pour couper les chemins vers les Domain Admins ?
Rendu
Les actions défilent en grisé, puis la réponse dans un panneau : résumé en gras, listes en tableaux, objets critiques (Domain Admins / tier-0) marqués 🔴.
you › Profil de sécurité de sansa.stark, puis ses chemins vers le tier-0 ?
⚙ profil sansa.stark
↳ profil SANSA.STARK@NORTH.SEVENKINGDOMS.LOCAL · tier-0 à 1 saut
⚙ chemins tier-0 depuis sansa.stark
↳ 3 chemins
╭─ réponse ─────────────────────────────────────────────────╮
│ 🔴 sansa.stark : kerberoastable + unconstrained deleg, │
│ 1 saut du tier-0 (domaine NORTH via CoerceToTGT). │
│ … (tableau des attributs + chemins) … │
╰────────────────────────────────────────────────────────────╯
⟳ 4 tours · 14s · $0.12
Contexte & langue
- Contexte : le REPL et Claude Code gardent le fil d'une question à l'autre.
Chaque
-q(Python) est en revanche un processus indépendant ; pour enchaîner des-q, ajoute-c(continue la session),--newpour repartir de zéro. - Langue : par défaut, réponse dans la langue de la question. Forcer avec
--lang fr(Python) ouBH_LANG=fr(voir Configuration).
Configuration
Variables d'environnement (ou fichier .env — voir .env.example) :
| Variable | Rôle | Défaut |
|---|---|---|
NEO4J_URI · NEO4J_USER · NEO4J_PASSWORD |
Connexion Neo4j | bolt://localhost:7687 · neo4j · bloodhoundcommunityedition |
BH_MODEL |
Modèle Claude | sonnet |
BH_LANG |
Langue des réponses (auto / fr / en) |
auto |
BH_MAX_ROWS · BH_QUERY_TIMEOUT |
Cap lignes · timeout requête (s) | 1000 · 30 |
BH_SHOW_ROWS |
Afficher les lignes brutes en table | 0 |
BH_AUDIT |
Journal runs/audit.log |
1 |
Sécurité
- Lecture seule : un validateur (
agent/guardrails.py) rejette toute requête d'écriture ; l'agent n'a pas accès au shell ni aux fichiers de la machine. - Audit : chaque Cypher exécuté est tracé dans
runs/audit.log(BH_AUDIT=0pour désactiver). - « owned » est stocké côté application (
runs/owned.json), jamais écrit en base. - Garantie stricte (optionnelle) — Neo4j Community n'a pas de vrai compte read-only.
Après ingestion, verrouille la base :
(à ne PAS activer pendant l'ingestion ; reviens avecdocker compose -f docker-compose.yml -f docker-compose.readonly.yml up -d graph-dbdocker compose up -d graph-db). - Ports Docker bindés sur
127.0.0.1uniquement. Données d'un test autorisé / labo.
Dépannage
| Symptôme | Solution |
|---|---|
Cannot connect to the Docker daemon |
Docker pas lancé. Ouvre Docker Desktop / OrbStack. |
Cannot reach Neo4j at bolt://… |
Bases éteintes : docker compose up -d, vérifie docker compose ps. |
| L'agent dit 0 node / vide | Données pas (encore) chargées — attends ~30 s après l'import. |
port is already allocated (7687/8080) |
Un service occupe le port. Arrête-le ou change le port dans docker-compose.yml. |
OAuth session expired |
Relance claude (il redemande la connexion) ou claude login. |
ImportError: cannot import name 'pa' (Neo4j) |
Python 3.14 + Neo4j trop récent — déjà épinglé dans requirements.txt. |
bloodhound reste Restarting |
docker compose logs bloodhound ; sinon docker compose down -v puis up -d. |
| Mot de passe admin oublié | docker compose down -v puis up -d régénère un mot de passe (dans les logs). |
Comment ça marche
extract JSON SharpHound (.zip)
│ (import via BloodHound CE)
BloodHound CE ──▶ Neo4j (graphe, bolt :7687)
▲
│ Cypher lecture seule (audité)
┌────────────────┴─────────────────┐
serveur MCP « bloodhound » agent Python (Claude Agent SDK)
(Claude Code / Desktop / plugin) (REPL + one-shot)
└──── mêmes outils : profils, chemins edge-filtrés,
catalogue de requêtes vérifiées, owned… ────┘
BloodHound CE calcule tous les liens à l'import ; l'agent interroge le graphe. Claude choisit lui-même les outils, itère et rédige — un vrai agent tool-use. Deux frontaux partagent les mêmes outils : le serveur MCP (Claude Code / Desktop / plugin) et l'agent Python (REPL / scripting).
Arrêter / nettoyer
docker compose down # arrête (garde les données)
docker compose down -v # arrête ET efface les données
Développement
pip install -r requirements-dev.txt # ou: pip install -e ".[dev]"
pytest -q # unitaires (intégration auto-skippée)
BH_TEST_NEO4J=1 pytest -q # + intégration (Neo4j chargé requis)
claude plugin validate . --strict # valide le plugin / marketplace
Structure du projet
bloodhound lanceur : démarre tout + ouvre Claude Code
setup.sh bootstrap 1re fois (installe + option données démo)
docker-compose.yml bases BloodHound CE (Neo4j + PostgreSQL + appli)
docker-compose.readonly.yml overlay lecture seule stricte (optionnel)
scripts/ce_ingest.py import headless (.json et/ou .zip) via l'API CE
.mcp.json · CLAUDE.md Claude Code en local (serveur MCP + instructions)
.claude-plugin/ · SKILL.md plugin marketplace (manifestes + compétence)
bin/mcp-server.sh lanceur MCP du plugin (bootstrap venv, sortie stderr)
agent/
main.py agent Python : REPL + one-shot (-q, -c, --export, --lang)
mcp_server.py serveur MCP standalone (Claude Code / Desktop / plugin)
tools.py outils exposés à Claude (profils, chemins, catalogue, owned…)
queries.py edges d'attaque + catalogue de requêtes vérifiées
neo4j_client.py accès Neo4j lecture seule (+ audit)
guardrails.py blocage des requêtes d'écriture
render.py affichage type chat (tableaux, couleurs, 🔴)
report.py export d'un rapport markdown
audit.py journal des requêtes · owned.py ensemble « owned »
knowledge/ schéma BloodHound + recettes Cypher + Azure (contexte de l'agent)
tests/ tests unitaires + intégration
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.