
NetLogic est une boîte à outils avancée d'analyse réseau et de cybersécurité pour l'inspection du trafic, l'analyse de paquets et la détection de menaces.
Cartographe de surface d'attaque Cloud-Native et corrélateur de vulnérabilités — v3.0
NetLogic est une plateforme de sécurité réseau combinant scan de ports actif, corrélation de CVE (API NVD en direct), analyse SSL/TLS, audit de sécurité HTTP, évaluation de la sécurité DNS/e-mail, détection de prise de contrôle de sous-domaine, OSINT passif, sondage de vulnérabilités actif, un moteur de raisonnement basé sur l'IA, la découverte de chaînes d'attaque inter-hôtes, et une architecture d'agent de sonde profonde — livrée en tant qu'application web (tableau de bord React + FastAPI). Le moteur de scan central est en Python 3.9+ pur avec la bibliothèque standard et zéro dépendance tierce.
| Module | Description |
|---|---|
| Scan de ports | Scan TCP connect avec 43/58 ports, 22 sondes de service, récupération de bannières |
| Corrélateur de CVE | API NVD v2.0 en direct + enrichissement EPSS via FIRST.org |
| Analyseur TLS | Versions de protocole, chiffrements faibles, POODLE/BEAST/CRIME/DROWN, expiration du certificat |
| Audit d'en-tête HTTP | HSTS, CSP, X-Frame-Options, CORS, drapeaux de cookie ; score 0–100 |
| Empreinte de pile | Détection de CMS, framework, fournisseur cloud, CDN, WAF à partir de bannière/en-tête/corps |
| Sécurité DNS | SPF, DKIM, DMARC, DNSSEC, transfert de zone, score d'usurpabilité |
| OSINT passif | Journaux de transparence des certificats, DNS DoH, recherche ASN — aucun contact direct avec la cible |
| Sonde de services | Sondes non authentifiées Redis/Mongo/ES/Docker/K8s/etcd, 33 chemins admin |
| Détecteur de prise de contrôle | Découverte de sous-domaines via logs CT + 25 empreintes CNAME de fournisseurs cloud |
| Intégration Nuclei | Wrapper pour 13 000+ templates communautaires (CVE, tech, exposition, mauvaise configuration) — licence MIT |
| Pipeline de fusion | Porte de signaux multi-capteurs → accord déterministe → arbitrage IA → graphe d'attaque → rapport en 6 sections |
| Empreinte Web | Hash de favicon (mmh3 compatible Shodan), secrets JS, marqueurs de version, fichiers exposés, détection de page d'accueil par défaut |
| Analyse IA | OpenAI / Anthropic / OpenRouter / Ollama / Gemini / Groq / Kimi / Qwen — streaming de jetons SSE |
| Moteur de raisonnement | Boucle adaptative observer→raisonner→agir avec EvidenceGraph, moteur d'hypothèses, décroissance de confiance, provenance, planificateur, playbooks, détection de changements, validation active |
| Sonde profonde | Architecture d'agent par service : ScoutAgent (recon), ProbeAgent (vérifications de CVE ciblées), Coordinateur, Sandbox |
| Agent d'investigation IA | Boucle de style ReAct : après les capteurs de base, l'IA pilote une surface d'outils organisée, limitée par scope et auditée (~35 outils) pour vérifier les pistes et construire des chaînes d'attaque — avec des outils agressifs optionnels (sondes de crash, preuve libre, exploit libre) pour les cibles autorisées |
| Moteur de vérification | Re-vérification de CVE pilotée par l'IA : conçoit des plans de sondes HTTP brutes à partir du contexte CVE, exécute via sockets stdlib |
| Orchestration multi-hôte | Pipeline de scan complet par hôte → contexte inter-hôtes et matrice d'accessibilité → découverte de chaîne d'attaque |
| Directeurs de capteurs IA | Le LLM décide quels capteurs prioriser en fonction des ports ouverts, de la pile technologique et des CVE |
| SSH authentifié | Sous-processus ssh avec identifiants lit les versions réelles des paquets installés (60+ correspondances de produits) |
| Énumération de services | Extraction d'attributs au niveau protocole (KEX SSH, SMBv1, NLA RDP, communauté SNMP, état d'authentification HTTP) |
| Cartographe de topologie | DNS inversé, IPv6, traceroute, ASN/org/pays via ip-api.com |
| Sonde d'accessibilité | Matrice de mouvement latéral post-compromise à partir de l'adjacence de sous-réseau |
| Sonde réseau | Balayage de sous-réseau actif (/24 voisins privés) avec découverte en deux phases (balayage en direct → scan de ports complet) |
| Diff de scan | Évolution dans le temps : différences entre le scan actuel et le rapport JSON antérieur le plus récent par cible |
| Gestion des licences | Système de licence commerciale avec activation par clé (stub pour Stripe/Paddle/Lemon Squeezy) |
| Configuration IA par organisation | Chaque organisation stocke ses propres identifiants LLM chiffrés au repos via Fernet |
| OIDC / Clerk | Connexions humaines via des JWT de session émis par Clerk vérifiés contre JWKS public avec provisionnement automatique |
| PostgreSQL | Persistance multi-locataire complète avec migrations automatiques (tâches de scan, paramètres organisation, état de raisonnement, audit) |
| Benchmark Fusion | Benchmark hors ligne contre des cassettes HTTP enregistrées ; métriques précision/rappel/rappel critique/réduction FP |
Il y a exactement deux façons d'exécuter NetLogic :
| Mode | Commande | Description |
|---|---|---|
| Application web | netlogic --gui | Démarre FastAPI + sert la SPA React + agent de scan intégré, génère automatiquement les secrets, et ouvre le tableau de bord dans votre navigateur. C'est la seule façon d'exécuter l'application web. |
| CLI | netlogic <target> [flags] | Scan terminal unique (pas de serveur), imprime/écrit le rapport. |
La surface du produit est l'application web (tableau de bord React + FastAPI). Le moteur de scan sous src/ alimente les tâches lancées depuis l'interface utilisateur.
pip install -r requirements-api.txt pip install -e .
netlogic --gui
netlogic scanme.nmap.org --full
## Référence CLI```
netlogic [target] [flags]
Le point d'entrée est api.cli:main (défini dans pyproject.toml), qui délègue à netlogic.py:main(). Toute la logique de scan se trouve dans src/.
| Format | Exemple | Mode |
|---|---|---|
| Nom d'hôte | example.com | Scan mono-hôte |
| IPv4 | 10.0.0.5 | Scan mono-hôte |
| CIDR | 192.168.1.0/24 | Balayage CIDR (scanner uniquement, pas de fusion) |
| Séparés par des virgules | target1,target2 | Orchestration multi-hôtes (contexte inter-hôtes) |
netlogic example.com
netlogic example.com --full
netlogic example.com --tls --headers
netlogic example.com --takeover
netlogic example.com --osint
netlogic example.com --stack
netlogic example.com --dns
netlogic 10.0.0.5 --probe
netlogic example.com --full --probe
### Sélection du port```
# Quick — 43 common ports (default)
netlogic example.com --ports quick
# Full — 58 extended ports
netlogic example.com --ports full
# Custom list
netlogic example.com --ports custom=22,80,443,8080,9200
netlogic example.com --ai --ai-key $KEY
netlogic example.com --ai --ai-provider openai --ai-key $KEY --ai-model gpt-4o-mini
netlogic example.com --ai --ai-provider anthropic --ai-key $KEY
netlogic example.com --ai --ai-provider gemini --ai-key $KEY --ai-model gemini-2.0-flash
netlogic example.com --ai --ai-provider ollama
netlogic example.com --ai --ai-provider custom --ai-base-url https://... --ai-model model-name
### Fournisseurs d'IA pris en charge
| Fournisseur | Modèle par défaut | Style d'API |
|---|---|---|
| `openrouter` | `anthropic/claude-sonnet-4` | OpenAI |
| `openai` | `gpt-4o-mini` | OpenAI |
| `anthropic` | `claude-3-5-sonnet-20241022` | Anthropic Messages |
| `kimi` (Moonshot) | `kimi-k2.6` | OpenAI |
| `qwen` (Alibaba) | `qwen-plus` | OpenAI |
| `groq` | `llama-3.3-70b-versatile` | OpenAI |
| `gemini` (Google) | `gemini-2.0-flash` | OpenAI |
| `ollama` | `llama3` | OpenAI |
| `custom` | spécifié par l'utilisateur | OpenAI |
### Moteur de raisonnement```
# Adaptive observe→reason→act loop (deterministic by default; AI-augmented with --ai)
netlogic example.com --reason
# Multi-host world modeling — discovers in-scope neighbours, reasons per host
netlogic example.com --reason --multi-host
# Change detection — diffs against prior saved report
netlogic example.com --since-last
# Active validation — confirms hypotheses with safe non-destructive GETs
netlogic example.com --reason --active-validate
# Deep probe — per-service agent architecture with context isolation
netlogic example.com --deep-probe
Après l'exécution des capteurs de base, un agent optionnel de style ReAct permet à l'IA de piloter ses propres outils pour vérifier les pistes et construire des chaînes d'attaque, au lieu de laisser les résultats CVE de version/bannière comme pistes non vérifiées. L'IA propose des appels d'outils ; un environnement d'exécution déterministe les exécute — chaque outil est limité par périmètre à la cible, nettoyé et enregistré comme une observation. L'IA ne touche jamais directement au réseau.```
netlogic example.com --ai --ai-agent
netlogic example.com --ai --agent-depth --agent-max-steps 24 --agent-max-requests 80
L'agent dispose d'environ 35 outils en lecture seule/actifs sécurisés par défaut : sondes HTTP/TLS/DNS, `dir_enum`, `confirm_tech`, `timing_probe`, `cve_probe` (vérifications de marqueurs CVE connus et organisés), `sqli_boolean`/`sqli_time`, `ssrf_canary`, `idor_diff`, `file_disclosure`, `browser_get` (sans tête, passe les défis JavaScript), plus la comptabilité HackerOne (`record_poc`, `severity_suggest`, `submit_readiness`).
**Outils agressifs optionnels** — désactivés par défaut, **uniquement pour les cibles autorisées / en propriété dans le périmètre** (jamais sur un scan public ou inconnu). Chacun nécessite `--ai-agent` :
| Flag | Tool | Ce qu'il déverrouille | Garde-fous conservés |
|---|---|---|---|
| `--allow-crash-probes` | `crash_probe` | Vérifications CVE de crash/DoS organisées (http.sys, MS15-034) qui PEUVENT faire planter l'hôte | Catalogue fixe de 3 CVE — pas de forme libre |
| `--allow-freeform-proof` | `http_proof` | Niveau C : GET/HEAD/OPTIONS libres (+ POST sur les chemins de type recherche/connexion/graphql) | Schémas destructeurs + PUT/PATCH/DELETE bloqués ; preuve, pas de mutation |
| `--allow-exploit-requests` | `exploit_request` | Niveau E : **toute méthode** (incl. PUT/PATCH/DELETE) + chemin/en-têtes/corps arbitraire contre la cible | Limité au périmètre ; fermeture en cas d'échec sur les schémas massivement destructeurs (DROP/TRUNCATE TABLE, `rm -rf`) et injection d'en-têtes CR/LF ; chaque requête est auditée |
L'ActionGate déterministe maintient le cœur en `safe_active` ; ces trois flags sont les options explicites et auditées au-dessus. Exemple (boîte de labo possédée + modèle local) :```
netlogic YOUR_LAB_HOST --full --ai --ai-agent --agent-depth \
--allow-crash-probes --allow-exploit-requests \
--ai-provider ollama --ai-model gemma4:31b-cloud \
--ai-base-url http://localhost:11434/v1 --ai-key ollama
netlogic example.com --ssh-user admin --ssh-key ~/.ssh/id_rsa
netlogic example.com --ssh-user admin --ssh-pass SECRET
netlogic example.com --ssh-user admin --ssh-key ~/.ssh/id_rsa --ssh-port 2222
### Benchmark```
# Fusion pipeline benchmark against recorded cassettes (oracle mode — perfect AI upper bound)
netlogic --benchmark
# With real AI model
netlogic --benchmark --benchmark-ai
# Export report
netlogic --benchmark --benchmark-export report.md
# Verbose per-subject output
netlogic --benchmark --benchmark-verbose
netlogic example.com --report terminal # terminal output (default) netlogic example.com --report json # JSON file netlogic example.com --report html # HTML report netlogic example.com --report all # terminal + JSON + HTML
netlogic example.com --out ./reports
netlogic example.com --min-cvss 7.0
netlogic example.com --no-color
### Gestion du cache NVD```
netlogic --cache-stats
netlogic example.com --nvd-key YOUR_NVD_KEY
netlogic --version # Show version and exit netlogic --gui # Start web dashboard
## Pipeline de fusion
Le pipeline de fusion est un entonnoir **capteurs → porte → arbitrage IA → synthèse** qui remplace les appels IA monolithiques par une porte de précision. Il se trouve dans `src/fusion/` (12 fichiers).
### Schéma de signal (`src/fusion/signals.py`)
Contrat de données portant des preuves. Chaque capteur émet des objets `Signal` :
- `source` : `probe`/`banner`/`nuclei`/`wappalyzer`/`nvd`/`osv`/`tls`/`dns`
- `kind` : `vuln`/`tech`/`exposure`/`misconfig`/`service`
- `claim` : sujet normalisé (ex. `"CVE-2021-44228"`, `"nginx"`)
- `host`, `port`, `service`, `evidence` (limité à 600 caractères)
- `confidence` (0..1), `reliability` (`high`/`medium`/`low`)
- `kev`, `epss` (0..1), `cvss` (0..10), `exploit_available`, `version_matched`, `probe_confirmed`
- `exposure` dict (reachability, WAF, vantage)
- `observed_data` (octets bruts envoyés à l'IA — PAS les noms de capteurs ou les sévérités pour éviter un biais d'étiquetage)
- `ai_view()` supprime les métadonnées du capteur, ne renvoie que les faits observés
### Gate (`src/fusion/gate.py`)
Accord déterministe — étant donné `list[Signal]`, regroupe par sujet et renvoie `list[Verdict]` :
| Condition | Verdict |
|---|---|
| KEV-listed OR probe-confirmed OR critical+exploit/high-EPSS | **Confirmé** (épinglé — indéboulonnable) |
| ≥2 sources indépendantes d'accord, ≥1 haute fiabilité | **Confirmé** (sauf si toutes correspondent par version → gris) |
| Faible fiabilité unique, impact faible/moyen, aucune corroboration | **Rejeté** |
| Tout le reste | **Gris** (coûte un jeton IA) |
### Arbitrage IA (`src/fusion/adjudicator.py`)
Ne touche que la bande grise. Contraintes de sécurité appliquées dans le code (pas via le prompt) :
- Les éléments gris haut/critique ne peuvent JAMAIS être rejetés — au pire rétrogradés en `potential`
- Les correspondances par version uniquement sont limitées à `potential` (les distributions backportent sans incrément de version)
- L'IA découvre également de nouvelles trouvailles à partir du contexte complet de l'hôte
- Défaillance douce : une panne de l'IA laisse la bande grise en `potential` — aucune perte silencieuse de données
### Synthèse (`src/fusion/synthesis.py`)
`build_attack_graph(verdicts)` → graphe de reachabilité déterministe à partir des trouvailles CONFIRMÉES.
`full_synthesize(...)` → rapport IA en 6 sections :
1. Résumé exécutif
2. Trouvailles clés (tableau)
3. Chaînes d'attaque (basées sur graphe, LLM raconte les arêtes réelles)
4. Au-delà des CVE connues
5. Faux positifs et bruit
6. Remédiation
### Capteurs
| Capteur | Fichier | Ce qu'il produit |
|---|---|---|
| Engine bridge | `engine_bridge.py` | Convertit les artefacts de scan → Signaux depuis NVD, sondes, stack, Nuclei, vérificateur |
| Wappalyzer | `sensors/wappalyzer.py` | Empreinte compatible Wappalyzer sans dépendance des réponses HTTP |
| Nuclei | `sensors/nuclei.py` | Exécute des modèles YAML sur les réponses (sous-ensemble de la syntaxe Nuclei) |
| Cassette | `cassette.py` | Enregistrement/rejeu à partir de cassettes HTTP (données de benchmark hors ligne) |
### Cross-host (`src/fusion/cross_host.py`)
Regroupement post-arbitrage des verdicts entre hôtes par service+version partagé pour la narration de chaîne d'attaque multi-sauts dans la synthèse.
### Flux du pipeline```
Engine artifacts / Cassette data
↓
engine_bridge.py / cassette.py → Signal list
↓
gate.py::adjudicate() → Verdict list (confirmed/discarded/gray)
↓
adjudicator.py::run_adjudication() → AI on gray band only
↓
synthesis.py::full_synthesize() → 6-section report + attack graph
Situé dans src/reasoning/ (~58 fichiers). Boucle multi-phase, sécurisée par paliers, observe→raisonne→agit. Activé avec --reason.
src/reasoning/director.py — ReconDirector.run())StrategyManager sélectionne le persona → Scheduler choisit l'action → SensorStep exécute → EvidenceGraph intègre les observations → ConfidenceEngine rafraîchit les croyancesProposal → AICoordinator normalise/classe/vérifie → Les propositions acceptées ensemencent l'état → Compiler → ExecutionPlanner → ExecutionKernel exécute les sondes → InferenceEngine résoutCrossHostGraph, génère des instances HostReasoner fillesGoalPlanner produit des plans d'investigationReasoningValidator → ProvenanceBuilder enregistre les arêtes → état persistantsrc/reasoning/state.py)| Couche | Classe | Ce qu'elle suit |
|---|---|---|
| WorldModel | WorldModel | EvidenceGraph, observations, croyances, hôtes, technologie, accessibilité |
| InvestigationState | InvestigationState | Objectifs (DAG), hypothèses, contradictions, impasses, persona actuel |
| ExecutionState | ExecutionState | Budget, historique des sondes, provenance, plans d'investigation, transcription IA |
| LearnedPatterns | LearnedPatterns | Heuristiques multi-scan + playbooks |
| Composant | Fichier | Description |
|---|---|---|
| EvidenceGraph | evidence_graph.py | Graphe d'entités temporelles dédupliquées (observations adressées par contenu via SHA-256) |
| Moteur d'hypothèses | hypothesis.py | Candidats concurrents avec vraisemblances, entropie, gain d'information, résolution postérieure |
| ConfidenceEngine | confidence.py | Noisy-OR sur des sources distinctes ; version seule plafonnée à 0,60 ; KEV/sonde bloqué à 0,97 |
| ProvenanceBuilder | provenance.py | Arêtes Observation→Inférence→Hypothèse, adressées par hachage de contenu |
| Scheduler | scheduler.py | Sélection d'actions par gain d'information avec explore_reserve (10%) |
| StrategyManager | strategy.py | Méta-raisonnement : sélection du persona, mode exploration/exploitation, détection de plateau |
| ActionGate | action_gate.py | Défense en profondeur : niveaux de risque (READ_ONLY < SAFE_ACTIVE < INTRUSIVE < EXPLOIT), maximum cœur est SAFE_ACTIVE |
| InferenceEngine | inference.py | Règles déterministes depuis rules/*.json, n'écrit jamais de confiance |
| NovelInferenceEngine | novel_inference.py | Règles pour cache_poisoning, request_smuggling, auth_bypass, etc. |
| ExecutionKernel | execution_kernel.py | Valide + exécute + trace les sondes (portée → lecture seule → budget → déduplication → profondeur) |
| Système de playbooks | playbooks.py | Playbooks YAML avec conditions de déclenchement et modèles d'intention |
| Détection de changement | change_detection.py | Phase 7 : diff sur les observations immuables (pas l'état), produit un ScanDelta de DeltaEvents |
| Validation active | active_validation.py | Phase 8b : sondes SAFE_ACTIVE non destructives via ActionGate |
src/reasoning/ai/)Pipeline : Générer → Normaliser → Classer → (élagage MetaReasoner) → Vérifier → Stocker
| Fichier | Composant |
|---|---|
coordinator.py | AICoordinator — orchestration du pipeline par étapes |
proposals.py | Enveloppe typée Proposal avec payload spécifique au type, provenance, économie |
normalize.py | ProposalNormalizer — porte de validation totale |
rank.py | ProposalRanker — score = raw_score × prob_correct × reputation_weight |
meta_reasoner.py | Élagage déterministe (détection de boucle, réduction d'incertitude) |
verifier.py | 4 étapes : Syntaxe → Sémantique → Preuve → Sécurité |
store.py | ProposalStore — registre de cycle de vie |
transcript.py | InvestigationTranscript — enregistrement des chaînes causales |
evaluation.py | Harnais d'évaluation déterministe basé sur cassettes |
reputation.py | AgentReputation — suit le taux d'acceptation/rejet par agent |
agents/hypothesis_generator.py | C1 — propose des explications concurrentes + hypothèses de vulnérabilité inédites |
agents/counterfactual.py | C11 — propose des objectifs de réfutation |
agents/investigation_designer.py | C2 — conçoit des plans de collecte de preuves |
Situé dans src/deep/ (7 fichiers). Utilisé avec --deep-probe. Architecture agent par service pour une exécution de sonde en contexte isolé.
| Composant | Fichier | Description |
|---|---|---|
DeepCoordinator | coordinator.py | Orchestre le pipeline profond complet : plan de capteur IA → ScoutAgent → ProbeAgent par service → énumération de service → Nuclei → vérificateur → prise de contrôle → sonde de sous-réseau → topologie → authentification → diff → accessibilité |
ScoutAgent | scout_agent.py | Reconnaissance passive : TLS, en-têtes, pile, DNS, OSINT |
ProbeAgent | probe_agent.py | Cible un service avec un contexte CVE/technologie isolé — exécute les sondes + vérificateur |
ExploitChain | chain.py | Planification de chemin d'attaque BFS sur des verdicts confirmés par fusion, génération de PoC |
Sandbox | sandbox.py | Sous-processus restreint pour la validation de PoC (répertoire temporaire, délai d'attente, nettoyage) |
Mission / AgentReport | models.py | Modèles de données pour les directives et résultats des agents |
Déroulement de DeepCoordinator.run() :
_build_sensor_plan via sensor_director)ScoutAgent pour la reconnaissance passiveProbeAgent par service (chacune avec un contexte CVE/technologie isolé)Situé dans src/verifier/ (3 fichiers). Confirmation de CVE pilotée par IA avec des sondes ciblées.
| Composant | Fichier | Description |
|---|---|---|
run_verifier() | engine.py | Orchestre : générer des plans → exécuter → construire des Signaux confirmés par sonde |
generate_plans_for_cves() | planner.py | Par CVE (CVSS ≥ 7,0) : vérifie ~20 plans intégrés → l'IA génère un plan HTTP brut (méthode, chemin, en-têtes, corps, statut/corps attendu) |
run_test() | runner.py | Exécution brute de socket TCP/TLS, analyse manuelle HTTP/1.0, correspondance de motif de corps attendu |
Re-vérification Phase 2 (reverify_with_context) fournit le contexte complet de l'hôte pour affiner les tests échoués.
Situé dans src/directors/ (4 fichiers). Sélection des paramètres de scan pilotée par LLM.
| Directeur | Fichier | Ce qu'il décide |
|---|---|---|
SensorDirector | sensor_director.py | Quels capteurs activer/désactiver et à quelle priorité, en fonction des ports ouverts + pile technologique + CVE |
ReprobeDirector | reprobe.py | Si des résultats potentiels peuvent être résolus avec des sondes HTTP ciblées |
NucleiSelector | nuclei_selector.py | Quelles balises de modèles Nuclei inclure/exclure (réduit les exécutions non pertinentes) |
SubnetDirector | subnet_director.py | Quels hôtes adjacents sonder, quels ports, à quelle profondeur (ignorer/rapide/standard/profonde) |
Situé dans src/orchestrator.py. Déclenché par des cibles séparées par des virgules. Exécute run_scan() par hôte, agrège les résultats, construit un contexte inter-hôtes à partir des verdicts de fusion combinés. Les groupes inter-hôtes détectent les services/versions partagés entre hôtes pour la narration de chaînes d'attaque multi-sauts.
src/nvd_lookup.py)--nvd-key)src/epss.py) : API FIRST.org par lots de 100 ID CVE, cache disque 24h dans ~/.netlogic/epss_cache.json, repli doux à 0,0src/external/nuclei_runner.py enveloppe le binaire Nuclei (licence MIT). Optionnel — se dégrade gracieusement si le binaire n'est pas trouvé. Les résultats alimentent le pipeline de fusion sous forme de signaux typés (étiquettes de sévérité supprimées pour éviter les biais du LLM).```
scoop install nuclei # Windows brew install nuclei # macOS go install github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest # Linux
---
## Fusion Benchmark
`src/fusion/benchmark.py` — mesure hors ligne sur des cassettes HTTP étiquetées (`benchmark/*.json` et `src/fusion/data/`). Métriques :
| Métrique | Seuil de passage |
|---|---|
| Réduction des FP | ≥ 80 % |
| Rappel critique | = 100 % |
Deux modes :
- **Oracle** (`--benchmark`) : borne supérieure de l'IA parfaite — mesure le fonctionnement déterministe seul
- **Modèle réel** (`--benchmark --benchmark-ai`) : mesuré avec le LLM configuré
---
## Architecture```
netlogic/
├── netlogic.py ← Local launcher (`--gui`, optional CLI helpers)
│
├── src/ ← Scan engine (used by the web API)
│ ├── scanner.py ← TCP scanner, 22 service probes, banner grabbing
│ ├── engine.py ← Orchestrator: SensorStep pipeline, all scan modules + fusion
│ ├── orchestrator.py ← Multi-host: per-host scan → cross-host context
│ ├── ai_analyst.py ← LLM integration (9 providers, stdlib-only transport)
│ ├── cve_correlator.py ← CVE matching: NVD
│ ├── nvd_lookup.py ← NVD API v2.0 client, disk cache, CISA KEV
│ ├── epss.py ← EPSS enrichment (FIRST.org, 24h cache)
│ ├── service_prober.py ← Unauthenticated service access, default creds, admin paths
│ ├── vuln_prober.py ← CVE-specific safe active probes
│ ├── osint.py ← DoH, CT logs, ASN lookup
│ ├── tls_analyzer.py ← SSL/TLS deep analysis
│ ├── header_audit.py ← HTTP security header audit
│ ├── stack_fingerprint.py ← CMS, framework, cloud, CDN, WAF detector
│ ├── web_fingerprint.py ← Favicon mmh3, JS secrets, version files, exposed paths, lander detection
│ ├── dns_security.py ← SPF, DKIM, DMARC, DNSSEC, zone transfer
│ ├── takeover.py ← Subdomain takeover (25 provider fingerprints)
│ ├── authenticated.py ← SSH subprocess: dpkg/rpm/apk parsing, 60+ product mappings
│ ├── topology.py ← PTR, IPv6, traceroute, ASN/org/country
│ ├── reachability_prober.py ← Lateral movement matrix from subnet adjacency
│ ├── network_prober.py ← /24 subnet sweep: live-host → full port scan
│ ├── service_enum.py ← Protocol attribute extraction (SSH KEX, SMBv1, RDP NLA, SNMP)
│ ├── ssl_utils.py ← Configurable SSL context management, TLS probe
│ ├── scan_diff.py ← Change-over-time: diffs against prior JSON report
│ ├── json_bridge.py ← Streaming JSON events for agent / REST API
│ ├── reporter.py ← Terminal, JSON, HTML output renderers
│ │
│ ├── fusion/ ← Precision funnel (12 files)
│ │ ├── signals.py ← Signal schema
│ │ ├── gate.py ← Deterministic agreement
│ │ ├── adjudicator.py ← AI adjudication (gray band only)
│ │ ├── synthesis.py ← Attack graph + 6-section report
│ │ ├── ai.py ← CompleteFn/StreamCompleteFn adapter
│ │ ├── engine_bridge.py ← Artifacts → Signals → verdicts
│ │ ├── benchmark.py ← Offline benchmark (oracle + real model)
│ │ ├── cassette.py ← HTTP cassette record/replay
│ │ ├── corpus.py ← Cassette→case conversion + CLI
│ │ ├── cross_host.py ← Cross-host verdict correlation
│ │ ├── sensors/nuclei.py ← Nuclei YAML → Signal conversion
│ │ └── sensors/wappalyzer.py← Wappalyzer fingerprint → Signal
│ │
│ ├── directors/ ← AI sensor directors (4 files)
│ │ ├── sensor_director.py ← LLM selects which sensors to enable
│ │ ├── reprobe.py ← LLM designs re-probe plans
│ │ ├── nuclei_selector.py ← LLM selects Nuclei template tags
│ │ └── subnet_director.py ← LLM directs subnet probing
│ │
│ ├── verifier/ ← AI CVE verification (3 files)
│ │ ├── engine.py ← Verifier orchestration
│ │ ├── planner.py ← Built-in + AI-generated probe plans
│ │ └── runner.py ← Raw TCP/TLS probe execution
│ │
│ ├── deep/ ← Deep probe agents (7 files)
│ │ ├── coordinator.py ← Full deep pipeline orchestrator
│ │ ├── scout_agent.py ← Passive recon agent
│ │ ├── probe_agent.py ← Per-service probe agent
│ │ ├── chain.py ← Exploit chain planning + PoC generation
│ │ ├── sandbox.py ← Restricted PoC execution
│ │ ├── base_agent.py ← Abstract base
│ │ └── models.py ← Mission/AgentReport data models
│ │
│ ├── reasoning/ ← Adaptive reasoning engine (~58 files)
│ │ ├── director.py ← ReconDirector (main loop)
│ │ ├── state.py ← WorldModel/InvestigationState/ExecutionState
│ │ ├── hypothesis.py ← Hypothesis engine (competing candidates)
│ │ ├── evidence_graph.py ← Temporal entity graph (content-addressed obs)
│ │ ├── confidence.py ← Noisy-OR belief computation
│ │ ├── provenance.py ← Observation→Inference→Hypothesis edges
│ │ ├── scheduler.py ← Information-gain action selection
│ │ ├── strategy.py ← Meta-reasoning: personas, explore/exploit
│ │ ├── strategies.py ← Concrete strategy implementations
│ │ ├── action_gate.py ← Risk-tiered probe authorisation
│ │ ├── change_detection.py ← Phase 7: observation-level diff
│ │ ├── active_validation.py ← Phase 8b: SAFE_ACTIVE probes
│ │ ├── cross_host.py ← Cross-host world modeling
│ │ ├── objective.py ← Objective DAG management
│ │ ├── intent.py ← Intent model + EvidenceType enum (29 types)
│ │ ├── candidate.py ← Action candidate with lazy factory
│ │ ├── actions.py ← Action model with RiskTier + Predicate
│ │ ├── compiler.py ← Intent → InvestigationGraph
│ │ ├── execution_planner.py ← InvestigationGraph → ProbePlanGraph
│ │ ├── execution_kernel.py ← Probe execution with validators
│ │ ├── probe_executor.py ← Read-only probe backends
│ │ ├── primitive_registry.py← Probe primitive catalogue
│ │ ├── generators.py ← Deterministic objective/hypothesis population
│ │ ├── playbooks.py ← YAML playbook system
│ │ ├── planning_pass.py ← GoalPlanner integration
│ │ ├── budget.py ← Probe budget management
│ │ ├── inference.py ← Deterministic rule-based inference
│ │ ├── novel_inference.py ← Novel-vuln hypothesis rules
│ │ ├── investigation_planner.py ← Goal-directed investigation planning
│ │ ├── investigation_memory.py ← Strategy attempt memory
│ │ ├── observation_translator.py ← Raw data → structured observations
│ │ ├── observation.py ← Immutable, content-addressed observation
│ │ ├── reflect.py ← PlannerFeedback generation
│ │ ├── reasoning_validator.py ← Continuous integrity audit
│ │ ├── builder.py ← State population from artifacts
│ │ ├── trace.py ← Execution tracing
│ │ ├── explanation.py ← Explanation records
│ │ ├── ai/ ← AI cognitive layer (subsystem)
│ │ ├── packs/ ← Technology pack calibration
│ │ ├── playbooks/ ← YAML playbook templates
│ │ └── rules/ ← JSON inference rules
│ │
│ └── external/nuclei_runner.py ← Nuclei binary wrapper
│
├── api/ ← FastAPI controller
│ ├── main.py ← App factory, lifespan, middleware stack
│ ├── cli.py ← Typer -> netlogic.py bridge
│ ├── db.py ← PostgreSQL connection + migration runner
│ ├── crypto.py ← Fernet seal/unseal (AES-128-CBC + HMAC-SHA256)
│ ├── auth/
│ │ ├── api_keys.py ← Dual-store (memory/PG), SHA-256 hashed
│ │ ├── jwt_handler.py ← Stdlib-only HS256 JWT
│ │ ├── oidc.py ← Clerk/IdP OIDC (RS256 + JWKS)
│ │ ├── license.py ← LicenseManager (stub → real payment API)
│ │ ├── rate_limit.py ← Sliding-window, IP banning
│ │ ├── provisioning.py ← Clerk auto-provisioning
│ │ └── dependencies.py ← require_org FastAPI dependency
│ ├── agents/
│ │ ├── registry.py ← Agent lifecycle (concurrency-aware, JSON persistence)
│ │ └── local_agent.py ← Built-in in-process agent
│ ├── jobs/
│ │ ├── manager.py ← ScanJob lifecycle, capped event deque (10k), SSE, Postgres
│ │ └── executor.py ← Dispatch (capability/selector, least-loaded, reclaimer)
│ ├── middleware/audit.py ← X-Request-ID + structured audit + SIEM shipping
│ ├── models/
│ │ ├── scan_request.py ← Pydantic ScanRequest (ipaddress validation)
│ │ └── agent.py ← AgentRegistration constraints
│ ├── routes/
│ │ ├── auth.py ← /v1/auth/*
│ │ ├── jobs.py ← /v1/jobs/*
│ │ ├── agents.py ← /v1/agents/*
│ │ ├── health.py ← /health + /v1/health
│ │ ├── license.py ← /v1/license/*
│ │ └── settings.py ← /v1/settings/*
│ └── storage/
│ ├── json_store.py ← 10 MB cap, 500 file cap, atomic writes
│ ├── pg_store.py ← Postgres JSONB upsert
│ └── reasoning_store.py ← Dual-store for reasoning state
│
├── dashboard/ ← React SPA (Vite + TypeScript + Tailwind + Clerk)
│ └── src/
│ └── pages/ ← Dashboard, NewScan, ScanDetail, Agents, Targets,
│ TargetTimeline, Settings, License, Login, SignUp, Legal
│
├── docs/ ← Design documentation
│ ├── DEPLOY_SAAS.md, saas-auth.md
│ ├── REASONING_ENGINE_DESIGN.md
│ ├── LEGAL_COMPLIANCE.md
│ ├── ENTERPRISE_READINESS.md
│ └── DESIGN_PARTNER_PACK.md
│
├── db/migrations/ ← PostgreSQL schema migrations
└── benchmark/ ← HTTP cassette recordings for fusion benchmark
Toutes les routes sous le préfixe /v1/. Authentification:
POST /v1/auth/token → HS256 JWT (expiration par défaut 1h)require_org vérifie via JWKSPOST /v1/auth/token Exchange API key for JWT [10/min/IP] POST /v1/auth/keys Create API key (X-Admin-Key) [admin] GET /v1/auth/keys List keys (masked) [admin] DELETE /v1/auth/keys Revoke key (body, not URL) [admin]
### Tâches```
POST /v1/jobs Create scan job [30/min/org]
GET /v1/jobs List recent jobs
GET /v1/jobs/history/{target} Scan history for target
GET /v1/jobs/{id} Job detail
GET /v1/jobs/{id}/stream SSE event stream [60/min/org]
GET /v1/jobs/{id}/export Export (format=json|md|raw)
POST /v1/jobs/{id}/explore-beyond AI deep-dive on finding
POST /v1/jobs/{id}/cancel Cancel job
DELETE /v1/jobs/{id} Remove job
POST /v1/agents/register Register agent [5/hr/IP] POST /v1/agents/{id}/heartbeat Keep-alive [3/min] GET /v1/agents/{id}/tasks Poll pending jobs POST /v1/agents/{id}/tasks/{job_id}/events Submit events [60/min, 500/batch] POST /v1/agents/{id}/tasks/{job_id}/complete Mark done/failed GET /v1/agents List agents (org-scoped) GET /v1/agents/{id} Agent detail DELETE /v1/agents/{id} Deregister POST /v1/agents/{id}/activate Enable agent POST /v1/agents/{id}/deactivate Disable agent
### Licence / Paramètres```
GET /v1/license License status
POST /v1/license/activate Activate key [3/hr/IP]
GET /v1/settings/ai Get org AI config (key masked)
POST /v1/settings/ai Update org AI config (encrypted)
POST /v1/settings/ai/test Test AI connection
GET /health Service status + uptime GET /docs OpenAPI docs GET /redoc ReDoc docs
---
## Variables d'environnement
### Contrôleur
| Variable | Défaut | Description |
|---|---|---|
| `NETLOGIC_ENV` | _(non défini)_ | `production`/`prod` = validation du secret au démarrage |
| `NETLOGIC_JWT_SECRET` | `changeme-in-production` | Secret de signature HS256, ≥32 caractères |
| `NETLOGIC_JWT_EXPIRY` | `3600` | Durée de vie du JWT en secondes |
| `NETLOGIC_ADMIN_KEY` | `admin-changeme` | Identifiant administrateur, ≥32 caractères en production |
| `NETLOGIC_API_KEYS` | _(vide)_ | Clés initiales : `key1:org1,key2:org2,...` |
| `NETLOGIC_CORS_ORIGINS` | _(vide)_ | Origines autorisées (CORS désactivé si vide) |
| `NETLOGIC_PORT` | `8000` | Port d'écoute |
| `NETLOGIC_HOST` | `0.0.0.0` | Adresse d'écoute |
| `NETLOGIC_NO_BROWSER` | _(non défini)_ | `1` désactive l'ouverture automatique |
| `NETLOGIC_OIDC_ISSUER` | _(non défini)_ | URL de l'API Frontend Clerk → connexion OIDC |
| `NETLOGIC_OIDC_AUDIENCE` | _(non défini)_ | Audience OIDC |
| `NETLOGIC_OIDC_DEFAULT_ORG` | _(non défini)_ | org_id de repli pour les utilisateurs OIDC |
| `NETLOGIC_DATABASE_URL` | _(non défini)_ | Chaîne de connexion PostgreSQL |
| `NETLOGIC_SECRETS_KEY` | _(non défini)_ | Clé Fernet pour les informations d'identification au repos |
| `NETLOGIC_AGENT_TOKEN_MAX_AGE` | `604800` | Durée de vie du jeton agent (7 jours) |
| `NETLOGIC_AGENT_PENDING_CAP` | `50` | Nombre max de tâches en attente par agent |
| `NETLOGIC_MAX_AGENTS_PER_ORG` | `100` | Nombre max d'agents enregistrés |
| `NETLOGIC_AI_PROVIDER` | `openrouter` | Fournisseur IA par défaut |
| `NETLOGIC_AI_API_KEY` | _(vide)_ | Clé IA par défaut |
| `NETLOGIC_AI_MODEL` | par défaut du fournisseur | Modèle par défaut |
| `NETLOGIC_AI_BASE_URL` | par défaut du fournisseur | URL de base personnalisée |
| `NETLOGIC_NVD_KEY` | _(vide)_ | Clé API NVD |
| `NETLOGIC_VALID_LICENSES` | _(vide)_ | Surcharges de licence de développement/test |
| `NETLOGIC_LICENSE_KEY` | _(vide)_ | Clé de licence de l'instance |
| `NETLOGIC_SCANS_DIR` | _(par défaut)_ | Répertoire de stockage des scans |
| `NETLOGIC_SIEM_ENDPOINT` | _(vide)_ | URL d'expédition des journaux d'audit |
| `NETLOGIC_WAPPALYZER_DATA` | _(intégré)_ | Chemin des empreintes Wappalyzer |
### Agent
| Variable | Défaut | Description |
|---|---|---|
| `NETLOGIC_CONTROLLER` | `http://localhost:8000` | URL de base du contrôleur |
| `NETLOGIC_API_KEY` | _(non défini)_ | Clé API pour l'enregistrement |
---
## Architecture de sécurité
### Pile des middleware (ordre d'application)
1. **AuditMiddleware** — Corrélation `X-Request-ID`, journal d'audit JSON structuré, expédition SIEM
2. **RequestSizeLimitMiddleware** — Limite du corps de 10 Mo (protection anti-DoS)
3. **LicenseMiddleware** — Bloque toutes les routes `/v1/` en l'absence de licence (renvoie 402)
4. **SecurityHeadersMiddleware** — HSTS (1 an), CSP (différencié HTML vs API), X-Frame-Options, X-Content-Type-Options, Permissions-Policy, Referrer-Policy
5. **OriginCheckMiddleware** — Validation de l'origine pour POST/PUT/DELETE (défense en profondeur contre les CSRF)
6. **CORSMiddleware** — Restrictif : pas de wildcard, origines spécifiques uniquement
### Authentification
- **Clés API** : SHA-256 hachées au repos ; en clair uniquement sur `create()` et dans le corps de la requête lors de `verify()`
- **JWT** : HS256 avec la bibliothèque standard (`hashlib`+`hmac`+`base64`), champ `alg` fixé avant vérification (empêche alg=none), fallback aléatoire éphémère pour le développement
- **OIDC** : Clerk/Auth0/WorkOS — RS256 + JWKS, provisionnement automatique des utilisateurs et organisations lors de la première connexion
- **Jetons d'agent** : SHA-256 hachés dans le registre, comparaison en temps constant, expiration à 7 jours
### Limitation de débit
Fenêtre glissante en mémoire. Par point de terminaison, par portée (IP, org_id, agent_id). Bannissement IP après 5 échecs d'échange de jetons en 10 minutes (bannissement de 1 heure).
### Protection des données
- Clés API LLM : chiffrées avec Fernet au repos (AES-128-CBC + HMAC-SHA256). Fermeture en cas d'échec en production : nécessite `NETLOGIC_SECRETS_KEY`
- Multi-tenant : toutes les données limitées à `org_id` ; une recherche inter-organisation renvoie 404 (pas 403)
- Traversée de chemin : tous les chemins de stockage sont validés, les séparateurs et `..` sont rejetés
---
## CI / Tests```bash
pip install -r requirements-dev.txt
python -m pytest
CI pipeline (.github/workflows/ci.yml) — 5 tâches :
pip-auditnpm ci + npm run buildNetLogic est destiné uniquement aux évaluations de sécurité autorisées, aux tests d'intrusion et à l'administration réseau. Scanner ou sonder des hôtes sans autorisation écrite explicite est illégal dans la plupart des juridictions. L'auteur décline toute responsabilité en cas d'utilisation non autorisée.
MIT © 2026 Dmitry Flynn — Voir LICENSE.txt