ExfilGuardian

Cahier des charges

Présentation du projet ExfilGuardian, contexte, problématique et réponse technique

Contexte et problématique

L'exfiltration de données est aujourd'hui l'une des menaces les plus silencieuses et les plus coûteuses pour les organisations. Elle ne consiste pas à faire tomber un système, mais à en siphonner discrètement les informations sensibles : propriété intellectuelle, données personnelles, identifiants, communications internes. Sa particularité est de se dissimuler dans des protocoles parfaitement légitimes : une requête DNS banale peut transporter des mégaoctets de données encodées, un flux HTTP apparemment normal peut exfiltrer une base de données entière, et un simple upload vers un service de partage autorisé peut suffire à faire sortir des documents sensibles du périmètre.

Les outils de sécurité réseau existants répondent bien à d'autres types de menaces (intrusions, malwares, dénis de service), mais l'exfiltration les met en échec pour une raison simple : elle ressemble à du trafic normal. Les approches par signatures seules ne suffisent pas, car les techniques d'exfiltration évoluent en permanence pour contourner les règles connues. Les approches purement comportementales génèrent trop de faux positifs sans la contextualisation apportée par l'analyse protocolaire.

ExfilGuardian part du constat qu'aucune technique de détection prise isolément n'est suffisante. La réponse efficace est une approche en profondeur, où plusieurs couches d'analyse indépendantes se renforcent mutuellement.

Ce qu'est ExfilGuardian

ExfilGuardian est un système de détection d'exfiltration de données en temps réel, conçu selon une architecture distribuée et multi-plateforme. Un driver kernel intercepte le trafic réseau et le contexte (processus, fichiers, DNS) sur chaque machine, un agent local collecte cette télémétrie et la transmet à un serveur central d'analyse via gRPC. Le serveur analyse simultanément les flux selon quatre angles complémentaires (DPI, signatures, comportemental, corrélation) et produit des alertes enrichies consultables via une application desktop native ou une API REST.

La première cible était Windows, qui représente la majorité des postes de travail en entreprise et donc le vecteur d'exfiltration principal. Grâce au découplage driver/serveur (contrat Protobuf partagé), le support a été étendu sans modifier le serveur, l'analyse ni l'interface : Linux est livré et validé (driver eBPF/aya) et macOS est livré en agent passif (capture réseau via libpcap, sans driver kernel).

Ce n'est pas un firewall. Ce n'est pas un DLP. ExfilGuardian ne classe pas le contenu des fichiers, ne lit pas les données personnelles qui transitent, et ne tente pas de déchiffrer le trafic TLS. Il détecte des techniques d'exfiltration, c'est-à-dire la façon dont les données sont dissimulées ou extraites via le trafic réseau. Cela inclut aussi bien les canaux couverts (tunnel DNS, ICMP) que les abus de services légitimes (uploads massifs vers des plateformes de partage, exfiltration HTTP/HTTPS vers des destinations inhabituelles). Le système ne se limite pas aux techniques « exotiques » : il surveille l'ensemble des vecteurs de sortie de données.

En phase initiale, ExfilGuardian fonctionne en mode observation pure : il alerte, l'opérateur décide. Un mode réponse actif est envisagé pour les futures versions.

L'outil se destine aux équipes SOC, aux ingénieurs réseau et aux auditeurs de sécurité qui ont besoin d'une visibilité fine sur ce qui sort de leur réseau, avec la possibilité d'adapter les règles de détection à leur contexte spécifique.

Architecture distribuée

Le système est conçu en trois composants distincts qui communiquent via gRPC/Protobuf sécurisé par mTLS :

Le driver kernel (WFP)

Le driver est un module kernel Windows écrit en Rust (#![no_std]), compilé en .sys via les crates WDK. Il s'enregistre comme callout sur la couche FWPM_LAYER_DATAGRAM_DATA_V4 du Windows Filtering Platform (WFP) pour intercepter les paquets réseau au niveau kernel.

Le driver utilise un modèle d'IRP inversé : l'agent envoie un IRP pending via DeviceIoControl, et le driver le complète lorsqu'un paquet arrive. Ce modèle évite le polling et minimise les transitions kernel/userland.

Mécanismes de protection intégrés :

  • Anti-kill : ObRegisterCallbacks supprime le droit PROCESS_TERMINATE sur le processus agent
  • Protection registre : CmRegisterCallbackEx bloque les modifications aux clés SOFTWARE\EXFILGUARDIAN
  • DKOM bypass : positionnement du bit Force Integrity (0x20) sur LDR_DATA_TABLE_ENTRY.Flags pour contourner les restrictions de ObRegisterCallbacks sur les drivers non signés en développement

L'agent

L'agent est un service Windows (windows-service) qui tourne en userland. Il communique avec le driver via DeviceIoControl pour recevoir les paquets interceptés. Ses responsabilités :

  • Pré-filtrage heuristique : 8 vérifications rapides (volume sortant, intervalles réguliers, processus inhabituels, nouvelles destinations, ports non-standard, fréquence DNS, ICMP large, TLS vers IP brute) qui posent des flags de priorité sur les flux
  • File d'attente SQLite WAL : zéro perte de paquets quand le serveur est injoignable. Les paquets s'accumulent localement et sont retransmis à la reconnexion
  • Streaming gRPC : transmission continue des paquets au serveur via tonic avec reconnexion automatique

Le serveur central

Le serveur expose deux interfaces :

  • gRPC (port 50051) : réception des flux d'agents via tonic, sécurisé par mTLS
  • REST (port 8080) : API de consultation via axum, dashboard, enrollment des agents

Le pipeline d'analyse traite chaque flux reçu à travers quatre couches de détection indépendantes.

Les fonctionnalités

F1. Filtrage kernel WFP (Ring 0)

Le driver s'inscrit comme callout WFP sur FWPM_LAYER_DATAGRAM_DATA_V4 pour intercepter les paquets réseau directement dans le kernel. Cette interception au niveau le plus bas garantit que même un processus malveillant ne peut contourner la capture en se branchant sur des couches supérieures.

AspectDétail
CoucheRing 0 (kernel)
APIWindows Filtering Platform (WFP)
CommunicationIRP inversé vers l'agent (zero polling)
LangageRust #![no_std] via crates WDK
Artefactexfil_guardian.sys + .inf + .cat

F2. Agent de télémétrie local (Ring 3)

L'agent tourne comme service Windows (windows-service) et assure la liaison entre le driver kernel et le serveur cloud. Il reçoit les paquets du driver via DeviceIoControl, les pré-filtre avec 8 heuristiques rapides, et les transmet au serveur en streaming gRPC continu.

AspectDétail
CoucheRing 3 (userland)
ExécutionService Windows auto-start
Pré-filtrage8 heuristiques (volume, intervalles, processus, DNS, ICMP, TLS...)
ReconnexionAutomatique avec backoff exponentiel

F3. File d'attente zéro perte (SQLite WAL)

Quand le serveur est injoignable (panne réseau, maintenance), l'agent ne perd aucun paquet. Les données sont accumulées localement dans une base SQLite en mode WAL (Write-Ahead Logging), qui garantit :

  • Concurrence : lectures et écritures simultanées sans blocage
  • Durabilité : les données survivent à un crash de l'agent
  • Retransmission : à la reconnexion, les paquets en file sont envoyés par ordre chronologique

F4. Transport gRPC / Protobuf sur HTTP/2

La communication agent vers serveur utilise gRPC avec sérialisation Protobuf sur HTTP/2. Le RPC StreamPackets est un appel client-streaming : l'agent ouvre une connexion persistante et envoie un flux continu de NetworkPacket. Le serveur ne répond qu'à la fermeture du stream.

AspectDétail
FrameworkTonic (Rust gRPC)
SérialisationProtobuf binaire (compact vs JSON)
TransportHTTP/2 multiplexé
RPCStreamPackets(stream NetworkPacket) returns (StreamResponse)

F5. Authentification dynamique mTLS

Chaque agent présente un certificat client unique, signé par l'autorité de certification (CA) du serveur. Les certificats sont générés dynamiquement lors de l'enrollment :

  1. Le serveur génère une CA ECDSA P-256 au démarrage (si absente)
  2. À chaque enrollment, un certificat client unique est créé et signé par la CA
  3. Le CN du certificat inclut les 6 premiers caractères du token pour identification
  4. L'agent stocke son certificat et l'utilise pour toutes les connexions gRPC

La CA et les certificats serveur sont générés via rcgen. La vérification mutuelle garantit qu'aucun agent non autorisé ne peut se connecter.

F6. Déploiement zero-touch

L'enrollment suit un workflow inspiré de Teleport : l'administrateur génère un token single-use sur le serveur, qui produit une commande PowerShell one-liner. L'exécution de cette commande sur la machine cible :

  1. Crée les répertoires d'installation
  2. Écrit les certificats mTLS (embarqués dans le script)
  3. Télécharge le driver, l'agent et les fichiers d'installation depuis /static
  4. Installe le certificat de signature du driver
  5. Installe le driver via pnputil
  6. Configure le registre (URL du serveur)
  7. Crée et démarre les services Windows (driver + agent)

L'opérateur n'a qu'une seule commande à copier-coller dans un PowerShell élevé.

F7. Protection anti-kill (ObRegisterCallbacks)

Le driver enregistre un callback OB_OPERATION_HANDLE sur le processus agent via ObRegisterCallbacks. Ce callback intercepte toutes les demandes d'ouverture de handle sur le processus agent et supprime les droits PROCESS_TERMINATE et PROCESS_SUSPEND_RESUME. Résultat : même un administrateur ne peut pas terminer l'agent via taskkill, le Gestionnaire des tâches, ou un malware.

F8. Protection du registre (CmRegisterCallbackEx)

Le driver enregistre un callback via CmRegisterCallbackEx qui intercepte toutes les opérations sur les clés HKLM\SOFTWARE\EXFILGUARDIAN. Les tentatives de suppression ou modification des paramètres de configuration de l'agent (URL du serveur, chemin du driver, état du service) sont bloquées avec STATUS_ACCESS_DENIED. La protection couvre les opérations RegNtPreDeleteKey, RegNtPreSetValueKey, RegNtPreDeleteValueKey et RegNtPreRenameKey.

F9. Contournement DKOM et ouverture sécurisée

En développement, les drivers ne sont pas signés par Microsoft, ce qui empêche ObRegisterCallbacks de fonctionner (il exige LDRP_IMAGE_INTEGRITY_FORCED). Le driver contourne cette restriction en positionnant le bit Force Integrity (0x20) sur LDR_DATA_TABLE_ENTRY.Flags via Direct Kernel Object Manipulation (DKOM).

La fonction find_and_set_flag parcourt la liste doublement chaînée des modules kernel (PsLoadedModuleList) pour trouver l'entrée du driver, puis modifie le champ Flags directement en mémoire kernel. Cette technique n'est utilisée qu'en développement ; en production, le driver sera signé par un certificat EV.

F10. Backend cloud-native asynchrone

Le serveur utilise un runtime Tokio multi-threadé avec deux serveurs concurrents :

ComposantFrameworkPortRôle
gRPCTonic50051Ingestion des paquets agents
RESTAxum8080Dashboard, alertes, métriques, enrollment

Les deux serveurs sont lancés via tokio::select! et partagent le même ServerPipeline. La configuration est chargée depuis config.yaml avec des valeurs par défaut sensibles.

Endpoints REST :

MéthodeCheminDescription
GET/api/statusSanté du serveur et version
GET/api/v1/alertsListe des alertes actives
GET/api/v1/metricsMétriques du pipeline (paquets, flux, détections)
POST/api/v1/agent/tokensGénération d'un token d'enrollment
GET/api/v1/enroll/windowsScript PowerShell de déploiement
GET/static/*Fichiers statiques (binaires agent/driver)

F11. Analyse multi-couches (DPI / Signatures / Comportemental / Corrélation)

Le pipeline d'analyse traite chaque flux à travers quatre couches indépendantes, puis corrèle les résultats pour produire des alertes avec un score de confiance bayésien.

Voir la section Couches de détection pour le détail complet.

F12. Écosystème 100% Rust

L'ensemble du projet est écrit en Rust, du driver kernel (#![no_std]) au serveur cloud. Ce choix élimine les bugs de memory safety (buffer overflows, use-after-free, data races) dans un composant qui traite des données réseau potentiellement malveillantes. L'uniformité du langage simplifie le tooling, la CI, le recrutement et le partage de types entre les crates.

F13. Support multi-plateforme

L'architecture du projet est multi-plateforme, et ce n'est plus un objectif mais une réalité livrée. Le crate exfil-analysis et le serveur compilent sur toutes les plateformes ; la séparation entre le driver (spécifique à l'OS) et le reste de la stack a permis d'ajouter de nouveaux endpoints sans modifier l'agent, le serveur ni l'analyse :

  • Windows — driver WFP (#![no_std], WDK) : capture réseau kernel complète + processus + ETW (DNS, fichiers) + auto-défense.
  • Linux — driver eBPF/aya (classifiers tc, ring buffers, kernels ≥ 5.8) : capture réseau + processus + SHA-256 des binaires. Livré et validé sur VM.
  • macOS — agent passif (capture réseau via libpcap, sans driver kernel) : volontairement plus léger, il prouve la portabilité du contrat de télémétrie (le serveur l'ingère tel quel).

F14. Application desktop (Electron + Next.js)

L'application desktop est l'interface principale de consultation pour les opérateurs SOC. Elle est connectée au vrai backend REST (NEXT_PUBLIC_API_URL) — il n'y a plus de mode mock : en cas de serveur injoignable, elle passe en simple dégradé hors-ligne (listes vides + bandeau « offline » piloté par /api/status). Les types TypeScript du frontend sont alignés 1:1 sur les types Rust du backend (sérialisation serde JSON), garantissant la cohérence entre les données affichées et les données réelles du pipeline d'analyse.

Stack technique : Electron 40 + Next.js 16 (App Router + Turbopack) + React 19 + Tailwind CSS v4 + Zustand (state client) + TanStack Query (state serveur) + Recharts (graphiques) + Biome (linter).

La communication avec le serveur Rust passe par un bridge IPC sécurisé (contextBridge) avec isolation du contexte (contextIsolation: true, nodeIntegration: false, sandbox: true). La connexion HTTP vers l'API REST utilise un client dédié avec détection automatique de l'état (serveur connecté / hors-ligne). En production, l'auth (Better Auth) tourne en mode serveur (standalone).

F14.1 Dashboard — Vue synthétique temps réel

Le tableau de bord est la page d'accueil de l'application. Il agrège les métriques du pipeline d'analyse en temps réel.

ComposantDonnées affichéesSource backend
Stats Cards (4x)Packets Received, Active Alerts, Flows Processed, Active FlowsGET /metricsMetricsDto
Pipeline ChartGraphique temps réel des paquets/seconde et détections/seconde (60 points, fenêtre glissante)Deltas calculés entre deux ticks MetricsDto
Threat DistributionRépartition des alertes par sévérité (Critical/High/Medium/Low) avec barres proportionnellesGET /alerts → comptage par severity
Recent Alerts10 dernières alertes avec CategoryBadge, SeverityBadge, StatusBadge, résumé tronqué, IPs source/destinationGET /alertsAlert[]
Detection ModulesÉtat des 5 modules (DNS, HTTP, TLS, ICMP, Behavioral) avec compteur d'alertes par groupeGroupement dynamique des alertes par ThreatCategory

Un bandeau « offline » s'affiche lorsque le serveur est injoignable (les listes sont alors vides, aucune donnée simulée).

F14.2 Alertes — Système de gestion SOC

La page d'alertes est le cœur de l'application. Les alertes correspondent aux Alert du backend, produites par la couche de corrélation avec un score de confiance bayésien.

Liste d'alertes (/threats) :

  • Filtrage multi-critères : par sévérité (Critical/High/Medium/Low) et par statut (New, Investigating, Confirmed, False Positive, Resolved)
  • Chaque carte affiche : catégorie de menace (16 catégories groupées en 5 familles colorées), sévérité, statut, résumé, IPs, nombre de détections, barre de confiance
  • Clic → navigation vers la page de détail

Détail d'alerte (/threats/[id]) :

SectionContenu
HeaderCatégorie (badge coloré par famille), sévérité, barre de confiance 0-100%, sélecteur de statut (dropdown pour mise à jour)
SummaryDescription textuelle de l'alerte générée par le moteur de corrélation
Detection TimelineTimeline verticale chronologique des Detection[] : timestamp, détecteur (DPI/DNS Analyzer, Signature/SIG-001, Behavioral/Beaconing), confiance individuelle
ContextSources IPs, Destinations IPs, Agents concernés, Processus, Flow IDs référencés, date de création
Indicators (IOCs)Tags cliquables pour chaque indicateur : Domain, IP, JA3 Hash, Signature ID, Process, Entropy, Z-Score, Beacon Interval, Data Volume
RecommendationAction recommandée par le moteur (Monitor, Investigate, Block IP, Isolate Agent, Revoke Certificate) avec boutons d'action
Whitelist ActionsBoutons "Whitelist IP" et "Whitelist Domain" pré-remplissant le formulaire d'exclusion

Les 16 catégories de menaces sont organisées en 5 familles visuelles :

  • DNS (bleu) : DnsTunneling, DnsExfiltration, DgaDomain, DnsFlood
  • HTTP (vert) : HttpExfiltration, HttpCovertChannel
  • TLS (violet) : TlsMaliciousFingerprint, TlsCertAnomaly, TlsToRawIp
  • ICMP (orange) : IcmpCovertChannel, IcmpLargePayload
  • Behavioral (jaune) : C2Beaconing, DataExfiltrationVolume, UnusualProcessNetwork, SuspiciousNewDestination, BaselineDeviation

Le lifecycle d'une alerte suit 5 statuts : New → Investigating → Confirmed / False Positive → Resolved.

F14.3 Flows — Table des flux réseau

La page Flows affiche les FlowRecord bruts, l'unité de donnée fondamentale du pipeline. Les alertes y font référence via flow_ids.

Table des flows (/flows) :

  • Colonnes : Process, Source:Port, Destination:Port, Protocol (badge Tcp/Udp/Icmp), Packets, Bytes, Duration, Pre-filter Flags
  • Les flags de pré-filtrage (HighOutboundVolume, RegularIntervals, UnusualProcess, NewDestination, UnusualPort, HighDnsFrequency, LargeIcmpPayload, TlsToRawIp) sont affichés comme chips colorées
  • Clic → page de détail du flow

Détail d'un flow (/flows/[id]) :

  • Métadonnées complètes du 5-tuple (source, destination, ports, protocole, processus)
  • Statistiques de trafic : packets, bytes total, outbound/inbound, ratio sortant, intervalle moyen, écart-type
  • Flags protocolaires (DNS/TLS/ICMP) et flags de pré-filtrage
  • Alertes liées référençant ce flow

F14.4 Analysis — Visualisation du pipeline

La page Analysis offre une vue analytique du moteur de détection.

ComposantDescription
Pipeline DiagramSchéma visuel du pipeline : FlowRecord → [DPI + Signatures + Behavioral] (parallèle) → Correlation → Alert, avec compteurs live depuis MetricsDto (flows processed, signature rules, detections generated, active alerts)
Correlation GraphGraphique 24h montrant le nombre d'alertes et de détections par heure
Detection Modules5 modules (DNS, HTTP, TLS, ICMP, Behavioral) avec compteurs de détections et d'alertes dérivés dynamiquement des alertes actives
Signatures ListListe des règles de signatures YAML avec ID, nom, catégorie, état (enabled/disabled), nombre de hits
Behavioral StatsDétail par sous-type behavioral (C2 Beaconing, Volume Anomaly, Baseline Deviation, Unusual Process, New Destination) avec compteur et confiance moyenne

F14.5 Settings — Configuration alignée sur le backend

La page Settings est divisée en 4 onglets. L'onglet Detection est bindé sur le ServerAnalysisConfig (miroir de analysis/src/config.rs) :

Onglet General : démarrage automatique, notifications desktop, mode sombre (paramètres locaux).

Onglet Detection (configuration serveur) :

SectionParamètres
DPIdns_enabled, dns_entropy_threshold (slider 1-5), dns_subdomain_length_threshold, tls_enabled, icmp_enabled, icmp_payload_threshold
Signaturesenabled, rules_dir (lecture seule), reload_interval_s
Behavioralenabled, zscore_threshold (slider 1-5), cusum_threshold (slider 1-10), beaconing_enabled, beacon_regularity_threshold (slider 0.05-0.5)
Correlationenabled, window_s, alert_threshold (slider 0.1-1.0), critical_threshold (slider 0.5-1.0)

Chaque section est pliable. Les sliders offrent un contrôle fin sur les seuils de détection.

Onglet Storage : rétention (jours), espace maximum (Go), format d'export (JSON/CSV/PCAP).

Onglet Exclusions : gestion des entrées de whitelist (CRUD). Types supportés : IP, domaine, processus, JA3 hash, flow. Chaque entrée inclut un motif, une raison, une date d'expiration optionnelle, et un filtrage par catégorie de menace. Les boutons "Whitelist IP" et "Whitelist Domain" depuis le détail d'alerte pré-remplissent le formulaire.

F14.6 Administration — Gestion du parc

L'interface d'administration est accessible aux utilisateurs avec le rôle admin :

PageFonction
AgentsTable des agents déployés avec hostname, IP, OS, version, statut (online/offline/degraded), état du driver, date d'enrollment. Détail en sheet latérale
UsersGestion des utilisateurs : table, invitation par email, attribution de rôle (admin/member/viewer)
EnrollmentGénération de tokens d'enrollment single-use, script PowerShell de déploiement zero-touch, historique des enrollments

F14.7 Gestion des données — Vrai backend, dégradé hors-ligne

L'application est connectée au vrai backend — il n'y a pas de mode mock :

  • Connecté : les données proviennent de l'API REST du serveur via TanStack Query (polling toutes les 1-5 secondes selon le type de données).
  • Hors-ligne : si le serveur est injoignable, les hooks renvoient des listes vides et un bandeau « offline » s'affiche (aucune donnée simulée).

La détection de l'état est automatique : un hook useServerStatus poll /api/status. Le state management utilise Zustand pour l'état local (métriques temps réel, configuration) et TanStack Query pour l'état serveur (alertes, flows, signatures, whitelist), qui retombe simplement sur des données vides en cas de ConnectionError.

Les couches de détection

1. Inspection profonde (DPI)

L'analyse DPI décode les protocoles applicatifs et détecte les anomalies protocolaires :

DNS : trois types de détection.

  • Tunneling (iodine, dnscat2) : entropie de Shannon élevée des sous-domaines, patterns d'encodage base64/hex, profondeur de sous-domaines anormale
  • Exfiltration : données encodées dans les labels DNS, volume anormal de requêtes TXT/NULL
  • DGA (Domain Generation Algorithm) : score composite basé sur l'entropie, le ratio consonnes/voyelles, la longueur du domaine et la présence de chiffres

TLS : détection d'anomalies dans les connexions chiffrées.

  • JA3 fingerprinting : hash du ClientHello comparé à une base de signatures connues (Cobalt Strike, Meterpreter, Trickbot, Emotet)
  • Anomalies de certificats : auto-signés, mismatch SNI/CN, validité trop courte (< 7 jours)
  • TLS vers IP brute : connexion TLS sans résolution DNS préalable (indicateur de C2)

ICMP : détection de canaux couverts.

  • Payloads anormalement volumineux (> 64 octets)
  • Fréquence de requêtes ICMP suspecte
  • Combinaison des deux indicateurs pour une confiance renforcée

HTTP (en clair) : inspection L7 des flux HTTP non chiffrés.

  • Exfiltration : volume sortant anormal (HttpExfiltration, High)
  • Canal caché : User-Agent d'outil offensif ou URI anormalement longue (HttpCovertChannel, Medium)

Transparence. DGA, tunneling DNS, DNS flood, TLS→IP brute, ICMP et HTTP sont opérationnels. En revanche, les empreintes JA3, les anomalies de certificat TLS et CUSUM sont écrits et testés mais pas encore branchés sur le flux (il manque d'acheminer un TlsMetadata du handshake jusqu'au pipeline) — c'est une dette technique assumée.

2. Signatures (règles YAML)

Le moteur de signatures évalue chaque flux contre des règles YAML hot-reloadables. 16 règles sont fournies par défaut, réparties sur 5 répertoires (dns/, flow/, icmp/, tls/, http/) — dont, en plus des règles ci-dessous :

IDNomSévéritéProtocoleCatégorie
DNS-DGA-001Domain Generation Algorithm DetectionCriticalDNSDgaDomain
DNS-EXFIL-001DNS Exfiltration - Large PayloadHighDNSDnsExfiltration
DNS-EXFIL-002DNS Exfiltration - Encoded Data PatternMediumDNSDnsExfiltration
DNS-TUN-001DNS Tunneling - High Entropy SubdomainHighDNSDnsTunneling
DNS-TUN-002DNS Tunneling - Excessive TXT QueriesMediumDNSDnsTunneling
HTTP-HDR-001Suspicious Custom HeadersMediumHTTPHttpCovertChannel
HTTP-EXFIL-001HTTP Large Upload to Unknown HostHighHTTPHttpExfiltration
HTTP-EXFIL-002HTTP Chunked Upload ExfiltrationMediumHTTPHttpCovertChannel
TLS-CERT-001Self-Signed Certificate to External HostMediumTLSTlsCertAnomaly
TLS-CERT-002TLS SNI MismatchHighTLSTlsCertAnomaly

Les règles supportent 12 opérateurs (eq, neq, gt, gte, lt, lte, contains, not_contains, regex, exists, in, not_in) et peuvent cibler 23 champs du flux (métriques réseau, contexte processus, flags protocolaires). 16 catégories de menaces sont supportées.

Le rechargement à chaud (hot-reload) est supporté : modifier un fichier YAML est pris en compte sans redémarrer le serveur. La détection de doublons d'ID prévient les conflits entre règles.

3. Analyse comportementale

L'analyse comportementale modélise le trafic normal puis détecte les écarts :

Baseline. Pendant une période d'apprentissage (15 jours par défaut), le système accumule des statistiques par agent via l'algorithme de Welford (moyenne et écart-type incrémentaux, sans stocker tous les échantillons) :

  • Débit moyen, taille de paquets, volume sortant
  • Distribution protocolaire (ratios DNS, ICMP, TLS)
  • Processus et destinations connus

Détection d'anomalies. Après apprentissage, trois méthodes complémentaires :

  • Z-score : détecte les déviations soudaines (seuil configurable, défaut : 3σ)
  • CUSUM (Cumulative Sum) : détecte les augmentations graduelles qu'un Z-score instantané manquerait
  • EMA (Exponential Moving Average) : détecte les anomalies de volume (alerte quand le débit dépasse 3× la moyenne mobile)

Beaconing C2. Détection des communications régulières caractéristiques des implants :

  • Calcul du coefficient de variation (CV) des intervalles de connexion
  • CV < 0.15 avec au moins 20 connexions = beaconing probable
  • Confiance proportionnelle : CV de 0.05 donne une confiance plus élevée que 0.14

4. Corrélation et scoring

La couche de corrélation est le cerveau du système. Elle regroupe les détections des trois couches précédentes et calcule un score de confiance final :

Fenêtre temporelle. Les détections sont conservées dans une fenêtre glissante (5 minutes par défaut). Les corrélations se font par destination IP et par couple agent + catégorie de menace.

Scoring bayésien. Les confiances sont combinées via la formule P(A∪B) = 1 - (1-P(A)) × (1-P(B)), avec :

  • Décroissance temporelle : les détections anciennes perdent du poids (demi-vie de 5 minutes)
  • Bonus de diversité : +10% par détecteur distinct (DPI + signatures + comportemental = +20%)
  • Escalade de sévérité : quand la confiance dépasse 0.9, la sévérité monte d'un cran

Seuils d'alerte :

  • Confiance ≥ 0.6 : alerte standard
  • Confiance ≥ 0.85 : alerte critique
  • Confiance ≥ 0.85 + sévérité High : recommandation de blocage automatique

Les choix techniques et leurs justifications

Pourquoi tout en Rust ?

Le projet initial envisageait du C pour la capture. Ce choix a été abandonné : mélanger C et Rust annule les garanties de memory safety de Rust aux frontières FFI. Le driver kernel est écrit en Rust #![no_std] via les crates WDK, qui fournissent des abstractions sûres au-dessus des APIs kernel Windows. L'agent et le serveur sont en Rust standard. Cette uniformité élimine une catégorie entière de bugs (buffer overflows, use-after-free, data races) dans un composant qui traite des données réseau potentiellement malveillantes.

Pourquoi Windows en priorité ?

La décision de cibler Windows en priorité est un choix stratégique. Les postes de travail en entreprise, là où résident les données sensibles et où les attaquants opèrent, sont massivement sous Windows. Un système anti-exfiltration qui ne couvre pas Windows ne couvre pas le vecteur d'exfiltration principal. Le Windows Filtering Platform (WFP) fournit un mécanisme robuste et documenté pour l'interception réseau au niveau kernel, avec un modèle de callouts qui permet une intégration propre sans patcher le système. Le portage vers Linux (eBPF/aya) et macOS (agent passif libpcap) a ensuite été livré sans toucher au serveur — la preuve concrète que le contrat de télémétrie est portable.

Pourquoi une architecture distribuée ?

Un monolithe qui capture, analyse et affiche sur la même machine ne passe pas à l'échelle. L'architecture distribuée permet :

  • Déploiement sur N machines avec un seul serveur d'analyse
  • Pré-filtrage local qui réduit le trafic réseau entre agent et serveur
  • Résilience : la file SQLite WAL de l'agent garantit zéro perte même si le serveur tombe
  • Séparation des privilèges : le driver tourne en kernel, l'agent en SYSTEM, le serveur peut tourner sur une machine dédiée

Pourquoi gRPC/Protobuf ?

Le protocole entre agent et serveur doit supporter du streaming continu à haut débit avec un overhead minimal. gRPC avec Protobuf offre :

  • Sérialisation binaire compacte (vs JSON texte)
  • Streaming bidirectionnel natif
  • Support mTLS intégré dans tonic
  • Génération automatique du code client/serveur depuis le .proto

Pourquoi Electron + Next.js pour le desktop ?

L'application desktop devait être multi-plateforme et offrir une interface riche avec des graphiques temps réel. Electron permet de cibler les trois plateformes avec une seule base de code. Next.js avec React fournit les patterns de développement UI modernes. Ce choix permet à l'équipe de développer l'interface web et l'application native en parallèle avec le même code.

Pourquoi des règles YAML hot-reloadables ?

Durcir les règles de détection dans le code source est un anti-pattern dans le domaine de la sécurité. Les menaces évoluent, les contextes changent, les faux positifs doivent être ajustés. Externaliser les règles dans des fichiers YAML lisibles par un humain permet à un opérateur de les modifier sans recompiler. Le hot-reload garantit qu'une modification est prise en compte en quelques secondes sans interruption de service.

Ce que le projet produit

À terme, ExfilGuardian est un ensemble de livrables complémentaires :

Le driver kernel (.sys) s'installe sur chaque machine Windows à protéger. Il intercepte le trafic réseau via WFP et le transmet à l'agent local.

L'agent est un service système qui tourne en arrière-plan. Il pré-filtre les paquets, les met en file d'attente et les streame au serveur. Un installeur automatise le déploiement (registre + service Windows).

Le serveur d'analyse reçoit les flux de tous les agents, les analyse via le pipeline de détection (DPI + signatures + comportemental + corrélation) et expose les alertes via une API REST.

L'application desktop est l'interface principale. Elle présente un tableau de bord synthétique, un flux d'alertes filtrable et une vue de configuration. Elle communique avec le serveur via l'API REST.

Le site de documentation est intégré au projet. Il documente l'architecture, les conventions, les guides de démarrage et les références techniques.

Organisation du projet

Le projet est structuré en monorepo avec un workspace Cargo :

exfil-guardian/
├── driver/        # Kernel WDM, workspace séparé (nightly + WDK)
├── agent/         # Service système, gRPC client
├── server/        # Serveur d'analyse, gRPC + REST
├── analysis/      # Coeur analytique : DPI, signatures, behavioral, corrélation
├── installer/     # Installeur Windows
├── proto/         # Définitions Protobuf
├── certs/         # Générateur de certificats mTLS
├── signatures/    # Règles de détection YAML
├── desktop/       # Application Electron + Next.js
└── docs-site/     # Documentation Fumadocs

Le driver est un workspace Cargo séparé car il nécessite le toolchain nightly et le WDK, incompatible avec les crates userland. Les cinq autres crates Rust (agent, server, analysis, installer, certs) partagent un workspace commun avec des dépendances centralisées.

Le développement suit une approche industrielle : dépôt Git centralisé sur GitHub, branche principale protégée (Trunk), toute modification passant par une pull request. Le pipeline CI/CD automatise la vérification : formatage, clippy, tests, build Windows pour les composants agent/serveur.

Confidentialité et éthique d'usage

ExfilGuardian fait de l'inspection profonde de paquets. C'est une capacité puissante qui impose des responsabilités claires.

Le système n'est pas un DLP. Il ne lit pas le contenu des fichiers, ne déchiffre pas le trafic TLS, ne classe pas les données selon leur sensibilité. Ce qu'il fait, c'est extraire des caractéristiques statistiques (l'entropie d'un nom de domaine, la taille d'un champ, la fréquence de connexion vers un endpoint) pour en déduire un comportement. Le payload brut des paquets n'est jamais persisté. Les alertes stockées contiennent uniquement des métadonnées réseau : adresses IP, protocole, score, timestamp.

Sur le plan légal, cet outil est conçu pour être déployé par les administrateurs d'un réseau sur leur propre infrastructure. Dans un contexte d'entreprise, la surveillance du trafic réseau est soumise à des obligations d'information vis-à-vis des utilisateurs. Le RGPD et le Code du travail s'appliquent. L'outil s'inscrit dans un usage conforme à ces obligations.

On this page

Contexte et problématique
Ce qu'est ExfilGuardian
Architecture distribuée
Le driver kernel (WFP)
L'agent
Le serveur central
Les fonctionnalités
F1. Filtrage kernel WFP (Ring 0)
F2. Agent de télémétrie local (Ring 3)
F3. File d'attente zéro perte (SQLite WAL)
F4. Transport gRPC / Protobuf sur HTTP/2
F5. Authentification dynamique mTLS
F6. Déploiement zero-touch
F7. Protection anti-kill (ObRegisterCallbacks)
F8. Protection du registre (CmRegisterCallbackEx)
F9. Contournement DKOM et ouverture sécurisée
F10. Backend cloud-native asynchrone
F11. Analyse multi-couches (DPI / Signatures / Comportemental / Corrélation)
F12. Écosystème 100% Rust
F13. Support multi-plateforme
F14. Application desktop (Electron + Next.js)
F14.1 Dashboard — Vue synthétique temps réel
F14.2 Alertes — Système de gestion SOC
F14.3 Flows — Table des flux réseau
F14.4 Analysis — Visualisation du pipeline
F14.5 Settings — Configuration alignée sur le backend
F14.6 Administration — Gestion du parc
F14.7 Gestion des données — Vrai backend, dégradé hors-ligne
Les couches de détection
1. Inspection profonde (DPI)
2. Signatures (règles YAML)
3. Analyse comportementale
4. Corrélation et scoring
Les choix techniques et leurs justifications
Pourquoi tout en Rust ?
Pourquoi Windows en priorité ?
Pourquoi une architecture distribuée ?
Pourquoi gRPC/Protobuf ?
Pourquoi Electron + Next.js pour le desktop ?
Pourquoi des règles YAML hot-reloadables ?
Ce que le projet produit
Organisation du projet
Confidentialité et éthique d'usage