← Accueil

Wazuh à l'état brut : 19 alertes pour 4 attaques simulées

16 octobre 2026 · Homelab · Wazuh · Sysmon · Blue Team · Projet associé

Round 1 de mon homelab SOC : quatre attaques simulées (Atomic Red Team) sur une VM Windows surveillée par Sysmon et Wazuh, avec les règles par défaut. Je reconstitue ce qui s'est passé à partir des alertes seules, puis je compare avec la vérité terrain : 19 alertes, 8 hypothèses justes, 8 partielles, 3 fausses. Mes conclusions sont celles prises pendant l'analyse ; la vérité terrain n'a été consultée qu'après.

Objectif

Établir une baseline « out of the box » (règles Wazuh par défaut + Sysmon) :

  1. Un script tire 4 tests Atomic Red Team au hasard et les exécute avec des délais aléatoires.
  2. Je reconstitue la séquence uniquement à partir des alertes.
  3. Je compare avec le journal de vérité terrain et je documente mes erreurs.

Environnement

Round réalisé le 16 octobre 2026 sur un lab local (KVM/QEMU, réseau NAT) :

  • une VM Windows 10 LTSC 2021 (évaluation) avec Sysmon v15.22 (configuration SwiftOnSecurity) et l’agent Wazuh ;
  • une VM Ubuntu Server avec Wazuh 4.14 (manager, indexer, dashboard) ;
  • Atomic Red Team pour simuler les attaques.

L’architecture, le script, le journal de vérité terrain et la liste des alertes sont dans le dépôt GitHub.

Protocole

Paramètre Valeur
Tirage 4 tests tirés dans un pool (scripts/round.ps1)
Délai entre tests 60-150 s (aléatoire)
Outils autorisés dashboard Wazuh, VirusTotal
Méthode de notes une entrée par alerte : hypothèse (attaque / bruit) et justification

Vérité terrain

Action Début (UTC) Technique Test Atomic Red Team
1 15:58:59 T1136.001 Create a new user in a command prompt
2 16:00:46 T1547.001 Reg Key Run
3 16:01:54 T1547.009 Create shortcut to cmd in startup folders
4 16:03:42 T1059.003 Writes text to a file and displays it

Les 4 tests se sont terminés sans erreur (code de sortie 0). Journal complet : results/round-1/journal.csv.

Télémétrie observée

EID = identifiant d’événement Sysmon. Les alertes des sources ci-dessous totalisent les 19 alertes du round.

Source Volume
Alertes Wazuh (total) 19 : action 1 = 8, action 2 = 3, action 3 = 3, action 4 = 1, bruit = 4
Sysmon EID 1 (process create) 56 événements → 6 alertes
Sysmon EID 11 (file create) 5 événements → 4 alertes
Sysmon EID 12 (registry object) 8 événements → 0 alerte
Sysmon EID 13 (registry value) 33 événements → 1 alerte
Journal Security de Windows 5 alertes (4720, 4722, 4728, 4732, 4738)
FIM (File Integrity Monitoring) 1 alerte
Journaux système et application Windows 2 alertes

Reconstitution et verdicts

Verdict alerte par alerte

N° désigne le numéro de l’alerte dans l’ordre chronologique. Les alertes sont regroupées par action a posteriori : pendant le round, je les voyais dans cet ordre.

Le verdict porte sur mon hypothèse initiale, même quand je l’ai corrigée ensuite en cours d’analyse.

Légende :

  • ✅ action et qualification bonnes
  • ⚠️ action identifiée mais mal qualifiée
  • ❌ hypothèse fausse

Pour le bruit : ✅ correctement écarté, ❌ pris pour une attaque.

Action 1 : création de compte local (T1136.001, 15:58:59)

N° Alerte Hypothèse initiale
3
❌
cmd lancé par un processus anormal Probablement du bruit
4
❌
net.exe lancé par cmd Mise à jour Windows
5
✅
net1.exe : création d’utilisateur Compte backdoor possible, regroupé avec #3 et #4 (même seconde)
6
⚠️
Domain Users Group Changed (4728) Attaque certaine, escalade de privilèges ?
7
✅
User account enabled or created (4720) Début d’une chaîne d’événements liée
8
⚠️
User account enabled or created (4722) Activation du compte, hypothèse d’escalade maintenue
9
✅
User account changed (4738) L’opérateur utilise la session locale pour créer un compte
10
⚠️
Users Group Changed (4732), groupe Users Soupçon de droits administrateur

Réalité :

  • #3 et #4 : cmd et net.exe étaient les deux premiers maillons de net user /add, ni du bruit ni une mise à jour Windows. Je les ai écartés d’abord, puis reclassés comme attaque en lisant #6.
  • #6, #8, #10 : il n’y a pas d’escalade. Le compte est dans le groupe None (#6) et dans Users, pas Administrators (#10).

Action 2 : persistance par clé Run (T1547.001, 16:00:46)

N° Alerte Hypothèse initiale
11
⚠️
cmd, REG ADD ... Run Pertinence incertaine
12
✅
reg.exe, motif « Base64-like » Modification du registre liée à une attaque
13
⚠️
Entrée de registre exécutée au prochain logon Liée à #12, création d’un compte admin ou d’un processus privilégié

Réalité :

  • #11 : c’est la commande qui écrit la clé Run, le début de l’action.
  • #12 : la règle parle de Base64, mais la valeur ajoutée est un simple chemin. Le libellé est trompeur, ma lecture (modification du registre liée à une attaque) était juste.
  • #13 : le but est la persistance. Le programme se lance au prochain logon, ce n’est pas un compte admin.

Action 3 : raccourci dans les dossiers Startup (T1547.009, 16:01:54)

N° Alerte Hypothèse initiale
15
⚠️
FIM : fichier ajouté dans Startup Escalade de privilèges sur un exécutable
16
⚠️
PowerShell copie un fichier dans Startup Création en deux temps d’un fichier privilégié
17
⚠️
PowerShell crée un fichier « script » dans Startup (Roaming) Transformation du fichier en script

Réalité :

  • #15 : le fichier est un raccourci .lnk, et les permissions affichées sont celles du fichier, pas une modification par l’attaquant.
  • #15, #16, #17 : une seule commande PowerShell, deux fichiers .lnk. #15 (FIM) et #16 (Sysmon) concernent le même fichier, dans le Startup commun (ProgramData), vu par deux capteurs. #17 concerne celui du Startup de l’utilisateur (Roaming). Les événements Sysmon derrière #16 et #17 ont le même ProcessGuid, à 15 ms d’écart.

Action 4 : exécution via cmd (T1059.003, 16:03:42)

N° Alerte Hypothèse initiale
19
✅
cmd, echo Hello... Message de l’attaquant, probablement indépendant des actions précédentes

Bruit système (4 alertes)

N° Alerte Hypothèse initiale
1
✅
Service startup type changed (BITS) Bruit
2
❌
License Activation (slui.exe) failed Tentative d’attaque, partiellement échouée
14
✅
Exécutable déposé dans un dossier souvent utilisé par les malwares (niveau 15) Bruit : PowerShell met à jour un réglage
18
✅
Fichier déposé à la racine Windows (AM_Delta.exe) Mise à jour Windows

Réalité :

  • #2 est une activation de licence Windows (Trigger=NetworkQuarantineRetry).
  • #14 est un fichier de test de politique PowerShell (__PSScriptPolicyTest).
  • #18 est une mise à jour de Windows Defender.

Bilan chiffré

Sur 19 alertes (hypothèses initiales) : 8 ✅ 8 ⚠️ 3 ❌.

  • Couverture : les 4 actions sont identifiées. Trois d’entre elles (1, 2 et 3) contiennent au moins une alerte mal qualifiée, l’action 4 est entièrement juste.
  • Bruit : 3 alertes sur 4 correctement écartées (BITS, __PSScriptPolicyTest, AM_Delta). L’activation de licence Windows a été prise pour une attaque.
  • Ce qui a marché : regroupement temporel (alertes #3 à #5, une fois #6 lue), lecture du contexte de session (#9), niveau 15 non surpondéré (#14), rejet de l’hypothèse d’une altération des signatures Defender (#18).

Ce que j’en retiens

Les quatre premiers viennent d’erreurs du round, le dernier d’un point qui a bien marché.

  1. Compter les actions, pas les événements. Une commande peut produire jusqu’à 8 alertes (action 1). L’action 3 en produit 3 : un seul PowerShell crée deux .lnk, et le fichier du Startup commun est vu deux fois, par le FIM (#15) et par Sysmon (#16). J’ai lu #16 et #17 comme deux étapes alors que le même ProcessGuid à 15 ms d’écart figurait dans mes notes. Corréler par ProcessGuid / Logon ID.
  2. Lire les champs, pas les libellés ni les hash. Users n’est pas Administrators (#10), un .lnk n’est pas un exécutable (#15). Les hash de cmd.exe et reg.exe ne donnent rien sur VirusTotal : ce sont des binaires légitimes détournés (living off the land). Le signal est dans commandLine.
  3. Classer sur la preuve, pas sur l’impression de familiarité. J’ai écarté de vraies actions parce que tous les champs affichaient Microsoft et que VirusTotal ne détectait rien (#3, #4), et j’ai pris pour une attaque une activation de licence parce que j’ai mal lu le champ channel (#2). Dans les deux cas, regarder qui lance quoi : chaîne parent → enfant (cmd → net → net1) et ligne de commande.
  4. Ne pas conclure à une escalade sans preuve de privilège. Création de compte et persistance ne sont pas de l’escalade (#6, #8, #10, #13, #15). Chercher le groupe cible (Administrators) avant de parler de droits.
  5. Niveau ≠ pertinence. Le niveau 15 du round était du bruit (__PSScriptPolicyTest), la création de compte est au niveau 12 et la persistance Startup au niveau 14.

Limites

  • Un seul poste Windows, un seul utilisateur, peu d’activité de fond : baseline trop propre pour estimer le bruit en production.
  • Un seul round et 4 actions, avec des verdicts attribués après coup : les chiffres donnent un ordre de grandeur, pas une mesure. Une relecture indépendante serait nécessaire pour les valider.
  • Atomic Red Team laisse des artefacts nominatifs (T1136.001_CMD, « Atomic Red Team ») qu’un attaquant réel éviterait.
  • Résultats dépendants de la config Sysmon SwiftOnSecurity.
  • Pas de corrélation multi-événements : les règles que j’ai lues évaluent chacune un événement isolé, et je n’ai pas encore exploré les mécanismes de corrélation de Wazuh (frequency, if_matched_sid).

Suite

  • Écrire les règles : silence du bruit __PSScriptPolicyTest, et alignement du niveau d’alerte du Startup utilisateur (AppData\Roaming, niveau 9) sur celui du Startup commun (niveau 14).
  • Round 2 : même protocole et même grille de notation, règles custom actives, comparaison chiffrée avec cette baseline.