top of page
Rechercher

Wazuh : écrire des règles de corrélation pour passer de centaines d'événements à quelques alertes

ghizlanetikouk
9 oct.
5 min de lecture

Un SIEM qui génère des centaines d'alertes par jour n'est pas un SIEM utile : c'est un SIEM que plus personne ne regarde. Le problème vient rarement de l'outil, mais de règles qui déclenchent une alerte par événement au lieu d'une alerte par comportement. Dans cet article, nous montrons comment écrire des règles de corrélation avec Wazuh pour trois cas d'usage concrets : la force brute, la force brute suivie d'une connexion réussie, et le balayage réseau détecté par Suricata. L'objectif est de passer d'un flux d'événements à quelques alertes qualifiées.


Le principe : agréger avant d'alerter

Wazuh évalue chaque événement reçu contre une arborescence de règles. Une règle peut :


  • réagir à un événement unique (une connexion échouée) ;

  • réagir à une répétition d'événements correspondant à une autre règle, dans une fenêtre de temps donnée, avec des attributs communs (même adresse IP source, même compte) ;

  • réagir à un événement précédé d'un autre type d'alerte pour la même source ;

  • s'appuyer sur une règle parente pour affiner un cas particulier.


Les règles personnalisées se placent dans /var/ossec/etc/rules/local_rules.xml sur le manager, avec des identifiants compris entre 100000 et 120000, plage que la documentation Wazuh recommande pour les règles personnalisées. Ne modifiez jamais directement les fichiers de règles fournis par Wazuh : ils sont écrasés à chaque mise à jour. Pour adapter une règle native, copiez-la dans local_rules.xml avec l'attribut overwrite="yes".


Cas 1 : force brute sur un serveur Windows

Les échecs d'ouverture de session Windows (événement 4625) sont déjà décodés par Wazuh et classés par ses règles natives (règle 60122). Plutôt que d'alerter à chaque échec, on agrège :


<group name="local,windows,authentication_failures,">

  <!-- 5 échecs depuis la même adresse IP en 2 minutes (connexions locales exclues) -->
  <rule id="100110" level="10" frequency="5" timeframe="120">
    <if_matched_sid>60122</if_matched_sid>
    <field name="win.eventdata.ipAddress" negate="yes">^-$|^127.0.0.1$|^::1$</field>
    <same_field>win.eventdata.ipAddress</same_field>
    <description>Force brute probable : 5 échecs d'authentification depuis $(win.eventdata.ipAddress) en 2 min</description>
    <mitre>
      <id>T1110</id>
    </mitre>
  </rule>

</group>

Points clés :


  • if_matched_sid désigne la règle native des échecs d'authentification Windows.

  • frequency et timeframe définissent le seuil : ici 5 occurrences en 120 secondes.

  • same_field impose que les occurrences partagent la même adresse IP source. Sans cette condition, 5 échecs dispersés sur 5 postes différents déclencheraient la même alerte.

  • Le filtre negate="yes" écarte les ouvertures de session locales, dont le champ d'adresse vaut -, et qui seraient sinon toutes regroupées ensemble.


Wazuh fournit déjà une règle équivalente (60204 : 8 échecs depuis la même adresse en 240 secondes). La règle 100110 sert à l'adapter à votre contexte : avec un seuil plus bas, elle se déclenche avant la règle native. Vérifiez avec l'outil de test laquelle se déclenche sur vos événements.


Cas 2 : force brute suivie d'une connexion réussie

Une série d'échecs est un signal. Une série d'échecs suivie d'une réussite depuis la même source est un incident probable : le mot de passe a peut-être été trouvé. Wazuh permet de corréler un événement avec des alertes antérieures :


<group name="local,windows,attacks,">

  <!-- Connexion Windows réussie depuis une IP ayant déclenché une alerte de force brute dans les 10 dernières minutes -->
  <rule id="100111" level="13" timeframe="600">
    <if_group>authentication_success</if_group>
    <field name="win.system.eventID">^4624$</field>
    <if_matched_group>authentication_failures</if_matched_group>
    <same_field>win.eventdata.ipAddress</same_field>
    <description>Connexion réussie après force brute depuis $(win.eventdata.ipAddress)</description>
    <mitre>
      <id>T1110</id>
      <id>T1078</id>
    </mitre>
  </rule>

</group>

Ici, la règle s'accroche à toutes les règles du groupe authentication_success (dont 60106, l'ouverture de session Windows réussie) et vérifie qu'une alerte du groupe authentication_failures (notre règle 100110 ou la règle native 60204) a été émise pour la même adresse IP dans les 600 secondes précédentes. C'est le modèle utilisé par la règle native 40112 de Wazuh. Le niveau 13 la place au-dessus du simple signal de force brute : c'est celle qui doit réveiller l'analyste.


Deux précautions :


  • La règle n'a pas d'attribut frequency : un seul événement de réussite suffit, à condition qu'il soit précédé d'une alerte d'échecs.

  • Elle est rangée dans un groupe distinct (attacks) : placée dans authentication_success, elle s'accrocherait à son propre groupe.


Cas 3 : agréger les alertes de balayage Suricata

Une sonde Suricata sur un port miroir détecte les balayages réseau. Mais certaines signatures, sans seuil configuré, déclenchent une alerte à chaque paquet ou connexion correspondant : un seul scan peut produire des centaines d'alertes. On les regroupe en une alerte par campagne, en deux temps :


<group name="local,ids,suricata,">

  <!-- Alerte Suricata unitaire de reconnaissance -->
  <rule id="100119" level="3">
    <if_sid>86601</if_sid>
    <field name="alert.category">^Attempted Information Leak$|^Detection of a Network Scan$</field>
    <description>Suricata : alerte de reconnaissance - $(alert.signature)</description>
    <options>no_full_log</options>
  </rule>

  <!-- 20 alertes de reconnaissance depuis la même IP en 5 minutes -> 1 alerte de campagne -->
  <rule id="100120" level="10" frequency="20" timeframe="300" ignore="1800">
    <if_matched_sid>100119</if_matched_sid>
    <same_field>src_ip</same_field>
    <description>Balayage réseau depuis $(src_ip) : campagne agrégée</description>
    <mitre>
      <id>T1046</id>
    </mitre>
  </rule>

</group>

  • La règle 86601 est la règle native qui reçoit les alertes Suricata au format JSON (eve.json).

  • La règle intermédiaire 100119 isole les alertes de reconnaissance (catégories Suricata « Attempted Information Leak » et « Detection of a Network Scan ») ; c'est elle que 100120 compte. Un filtre field placé directement dans la règle de fréquence ne filtrerait que le dernier événement, pas les 20 événements comptés.

  • Dans les règles, les champs Suricata s'écrivent alert.category ou src_ip : le préfixe data. n'apparaît que dans le tableau de bord.

  • ignore="1800" empêche la règle de se redéclencher pendant 30 minutes, quelle que soit l'adresse source : une campagne produit une seule alerte, mais un second scanner actif pendant cette période ne générera pas de nouvelle alerte. Choisissez cette durée en connaissance de cause.


Les alertes unitaires restent au niveau 3 et n'encombrent plus le tableau de bord. Les événements bruts peuvent être conservés pour l'investigation en activant l'archivage (option logall_json dans ossec.conf, désactivée par défaut).


Tester avant de déployer : wazuh-logtest

Wazuh fournit un outil qui rejoue un événement dans le moteur de règles et affiche les règles déclenchées, sans rien envoyer en production :


/var/ossec/bin/wazuh-logtest

Collez un événement brut (une ligne de journal ou un événement JSON) : l'outil indique le décodeur utilisé, les champs extraits et l'identifiant de la règle déclenchée. C'est ainsi que l'on vérifie le nom exact des champs et les identifiants des règles parentes avant d'écrire une corrélation. L'outil recharge les règles à chaque session et signale les erreurs de syntaxe, sans redémarrer le manager.


Une fois les règles validées, il faut redémarrer le manager pour qu'elles produisent de vraies alertes :


systemctl restart wazuh-manager
tail -n 50 /var/ossec/logs/ossec.log

Une erreur de syntaxe dans local_rules.xml empêche le démarrage du moteur d'analyse : vérifiez toujours le journal après un redémarrage.


Mesurer le résultat

Une règle de corrélation se juge sur deux indicateurs, à suivre dans le temps :


  • le volume d'alertes qualifiées par semaine et par site, qui doit devenir lisible par un analyste ;

  • le taux de faux positifs de chaque règle, qui guide les ajustements de seuils et les exclusions (scanners de vulnérabilités internes, comptes de service, sauvegardes).


Cette étape de réglage fait partie intégrante d'une mise en service : une plateforme de détection n'est réellement opérationnelle qu'une fois ces seuils calibrés sur le trafic réel de l'entreprise.


Conclusion

Wazuh offre tout ce qu'il faut pour transformer un flot d'événements en quelques alertes qui comptent : fréquence, fenêtre temporelle, champs communs, corrélation entre groupes de règles et délai de réarmement. La différence entre un SIEM bruyant et un SIEM utile tient souvent à quelques dizaines de lignes de règles bien pensées et bien testées.


Les équipes cybersécurité de Gazeltech conçoivent et ajustent des dispositifs de détection basés sur Wazuh et Suricata. Contactez-nous pour en parler.

 
 
 

Commentaires


Mentions légales

Politique en matière de cookies

Politique de confidentialité

© 2024 par GazelTech. 

Contactez-nous pour une consultation gratuite

Conditions d'utilisation

  • LinkedIn
bottom of page