|8 min de lecture|Yvann Lièvre

Tester une règle Sigma avant la production : fixtures, régression et shadow mode

Comment tester des règles Sigma avant la production : fixtures true/false-positive, régression avec Atomic Red Team, shadow mode et backtest de couverture.

SigmaDetection EngineeringAtomic Red Team
Tester une règle Sigma avant la production : fixtures, régression et shadow mode

Une règle Sigma se déploie en quelques minutes. La confiance qu'on peut lui accorder se construit, elle, sur plusieurs jours de tests. Entre les deux se glisse un risque bien connu des équipes de détection : la règle qui ne détecte jamais rien (parce que le champ observé n'est pas celui du produit réellement déployé), et la règle qui détecte tout (parce que la condition est trop large et noie l'analyste sous des faux positifs). Ce risque n'a rien de nouveau, mais il s'est aggravé avec l'arrivée des copilotes qui génèrent des règles Sigma à la demande : la règle a l'air correcte syntaxiquement, elle « sonne bien », mais personne n'a vérifié qu'elle couvre réellement la technique visée. Voici la méthode pour tester une règle avant production : fixtures, régression contre des techniques réelles, et une période d'observation silencieuse avant toute alerte.

Pourquoi une règle non testée coûte plus cher qu'elle ne rapporte

Une règle Sigma déployée sans validation produit l'un de ces trois scénarios, tous coûteux :

  • Le faux négatif silencieux : la règle existe, apparaît dans le tableau de couverture ATT&CK, mais ne se déclenche jamais parce que le champ de log ciblé n'existe pas dans votre normalisation, ou parce que la valeur attendue diffère de celle produite par la version réelle de l'outil surveillé. Le risque est pire qu'une absence de règle : on croit être couvert.
  • Le faux positif de masse : une condition trop permissive (un simple mot-clé sur une ligne de commande, sans contexte de processus parent ni de chemin) déclenche des centaines d'alertes par jour. Résultat classique : l'équipe désactive la règle au bout d'une semaine, ou pire, arrête de regarder les alertes de cette source.
  • La dérive silencieuse : la règle fonctionnait au moment de son écriture, puis un changement d'environnement (mise à jour d'un produit, changement de format de log) la rend obsolète sans que personne ne s'en aperçoive.

Les trois scénarios partagent une cause commune : l'absence de preuve. Une règle Sigma n'est fiable que si elle a été testée sur des données réelles, dans les deux sens (elle détecte ce qu'elle doit détecter, elle reste silencieuse sur le reste).

Fixtures true-positive et false-negative avec pySigma et sigma-cli

La première étape consiste à construire des jeux de données de test, des fixtures, qui rejouent des événements représentatifs et vérifient que la règle se comporte comme attendu. sigma-cli, l'outil en ligne de commande basé sur pySigma, permet de convertir une règle vers le moteur cible et de la valider syntaxiquement :

# Valider la syntaxe et les métadonnées de la règle
sigma check rules/proc_creation_win_lsass_dump.yml
 
# Convertir la règle vers le moteur de requête cible (ici Splunk)
sigma convert -t splunk -p sysmon rules/proc_creation_win_lsass_dump.yml

Mais la validation syntaxique ne prouve rien sur l'efficacité. Le test réel consiste à faire tourner la règle convertie contre deux jeux d'événements :

# fixture_true_positive.yml : un événement qui DOIT déclencher la règle
title: LSASS dump via procdump
logsource:
  category: process_creation
  product: windows
detection:
  event:
    Image|endswith: '\procdump.exe'
    CommandLine|contains: 'lsass'
  condition: event
# fixture_false_negative_check.yml : une variante légitime qui NE DOIT PAS déclencher
# exemple : procdump utilisé sur un processus autre que lsass, dans le cadre d'un diagnostic
detection_test:
  Image: 'C:\Tools\procdump.exe'
  CommandLine: 'procdump.exe -ma notepad.exe notepad.dmp'
  expected: no_match

pySigma expose une API Python qui permet d'écrire ces vérifications comme de vrais tests unitaires, exécutés en CI à chaque modification de règle :

pytest tests/sigma/test_lsass_dump.py -v

Le principe est simple mais rarement appliqué avec rigueur : chaque règle mérite au moins un cas qui doit déclencher (true positive) et un cas qui ne doit pas (false negative attendu), rejoués contre le moteur réel, pas seulement contre un validateur de syntaxe.

Regression testing contre Atomic Red Team : prouver la couverture réelle

Une fixture artisanale prouve que la règle réagit à un événement fabriqué à la main. Cela ne prouve pas qu'elle détecte la technique MITRE ATT&CK qu'elle prétend couvrir dans ses métadonnées. Pour cela, il faut rejouer une technique réelle et vérifier que l'alerte se déclenche. Atomic Red Team, la bibliothèque de tests d'attaque par technique ATT&CK, sert exactement cet usage :

# Exécuter le test atomique correspondant à T1003.001 (OS Credential Dumping: LSASS Memory)
Invoke-AtomicTest T1003.001 -TestNumbers 1

Le test génère l'activité réelle (ici, un dump LSASS via un outil légitime), et on vérifie ensuite dans le pipeline de logs que la règle Sigma associée s'est effectivement déclenchée, avec les bons champs remontés. Sur un corpus de règles couvrant plusieurs dizaines de techniques, ce test de régression tourne en boucle : à chaque changement d'agent de collecte, de format de log ou de version d'un outil surveillé, on rejoue le catalogue d'atomiques correspondant et on compare le taux de déclenchement avant et après. C'est la seule preuve tangible qu'une ligne « couvre T1003.001 » dans un tableau de couverture correspond à une réalité opérationnelle, et pas seulement à une intention déclarée dans les métadonnées de la règle.

Shadow mode : sept jours de silence avant la première alerte

Une règle qui passe les fixtures et la régression Atomic Red Team n'est toujours pas prête pour la production, parce que ces deux tests jouent sur un environnement contrôlé, pas sur le bruit de fond réel de l'environnement client. La dernière étape est le shadow mode : la règle est déployée mais configurée pour ne générer aucune alerte visible, uniquement un comptage de matches sur une fenêtre de sept jours.

# Exemple de comptage quotidien en shadow mode (pseudo-requête)
SELECT date_trunc('day', matched_at) AS jour, count(*) AS volume
FROM sigma_matches
WHERE rule_id = 'proc_creation_win_lsass_dump'
  AND mode = 'shadow'
GROUP BY jour
ORDER BY jour;

Sept jours couvrent un cycle hebdomadaire complet (jours ouvrés et week-end), suffisant pour capter les tâches planifiées, les scripts de maintenance et les usages métier récurrents qui n'apparaîtraient jamais dans un test d'une journée. Si le volume reste stable et faible (quelques matches légitimes identifiés et exclus), la règle est candidate à la promotion. Si le volume explose sur un environnement client précis, c'est le signe d'un outil légitime local qui reproduit le comportement surveillé, et qui doit être exclu avant activation, pas découvert après le premier déluge d'alertes.

Backtester une règle générée par un copilote IA : la couverture réelle contre le sentiment de couverture

Les copilotes qui génèrent des règles Sigma à partir d'une simple description en langage naturel produisent un texte syntaxiquement valide en quelques secondes. Le problème n'est pas la syntaxe, c'est l'écart entre l'impression de couverture et la couverture réelle. Une règle générée peut citer une technique ATT&CK dans ses métadonnées sans que sa logique de détection couvre effectivement le comportement décrit par cette technique : champ mal choisi, condition trop étroite qui ne couvre qu'une variante de l'attaque, ou au contraire condition si large qu'elle capture aussi des usages légitimes.

Le traitement est le même que pour toute règle nouvelle, sans raccourci : fixtures true-positive et false-negative, rejeu Atomic Red Team sur la technique citée, puis shadow mode. Une règle générée qui échoue à l'un de ces trois tests n'est pas « presque bonne », elle n'a simplement pas encore été prouvée. Le sentiment de sécurité que procure une règle bien écrite syntaxiquement, avec des métadonnées propres et une description convaincante, est précisément ce qui rend ce backtest indispensable : c'est la forme qui rassure, pas la preuve.

Métriques de promotion : précision, volume, dérive

Avant de faire passer une règle du shadow mode à la production active, trois métriques suffisent à trancher :

MétriqueCe qu'elle mesureCritère go/no-go
PrécisionPart des matches en shadow mode confirmés comme pertinents après triage manuelSupérieure à un seuil défini par la criticité de la technique (typiquement 80 à 90 % pour une règle destinée à générer une alerte automatique)
VolumeNombre de matches par jour sur la fenêtre de sept joursStable, sans pic isolé non expliqué
DériveÉcart de volume entre deux fenêtres de shadow mode consécutives (ou après un changement d'environnement)Absence de dérive significative sans changement d'infrastructure documenté

Une règle qui satisfait les trois critères passe en production avec alerte active. Une règle qui échoue sur la précision reste en tuning (ajout d'une exclusion, resserrement d'une condition). Une règle qui échoue sur le volume ou la dérive retourne en shadow mode pour une nouvelle fenêtre d'observation.

Pourquoi un pack pré-validé change la donne

Reproduire cette méthode, fixtures, régression Atomic Red Team, shadow mode de sept jours, pour chaque règle individuellement représente un travail considérable, d'autant plus lourd que le volume de règles générées par des copilotes IA augmente sans que leur validation suive le même rythme. C'est exactement le travail qu'un pack de règles pré-validées humainement absorbe en amont : chaque règle a déjà traversé ce cycle avant d'arriver dans votre environnement, ce qui réduit à la fois le travail de validation et le bruit des règles auto-générées jamais éprouvées.

Le flux de règles Sigma ThreatClaw applique cette discipline en continu, pour que vos analystes reçoivent des alertes prouvées, pas des promesses de couverture.

Articles liés