Wer mit Windows-Events in Wazuh arbeitet, landet früher oder später hier:
Die Konsole ist voll mit ganz normalen, technischen Logons, vor allem Event ID 4624 (Logon Success) – z. B. Service-Logons über services.exe.
Kein Angriff, kein Risiko – aber jede Menge Lärm.
Genau das wollte Kashif in seinem Test-Setup lösen:
„Wie unterdrücke ich nur diese Routine-Logons, ohne andere Logon-Events zu verlieren?“
Schauen wir uns an, was schiefgelaufen ist – und wie die finale, funktionierende Lösung aussieht.
Ausgangspunkt: sinnvoller Ansatz, aber falsche Feldnamen
Kashif startete mit einer eigenen Regel, die eine sehr spezifische Kombination abfangen sollte:
- Windows Logon Success (
if_sid 60106) - Event ID 4624
- Logon Type 5 (Service Logon)
- Auth-Package
Negotiate - Logon Process
Advapi - Process Name
C:\Windows\System32\services.exe
Die Idee war exakt richtig:
einen vorhandenen Standard-Alarm (60106) „verfeinern“ und in diesem Spezialfall stummschalten.
Sein erster Versuch sah so aus (vereinfacht):
<group name="windows,windows_security,authentication_success,">
<rule id="100002" level="0">
<if_sid>60106</if_sid>
<field name="data.win.system.eventID">4624</field>
<field name="data.win.eventdata.logonType">5</field>
<field name="data.win.eventdata.authenticationPackageName">Negotiate</field>
<field name="data.win.eventdata.logonProcessName">Advapi</field>
<field name="data.win.eventdata.processName">C:\\\\Windows\\\\System32\\\\services\.exe</field>
<description>Ignore normal service logons (SYSTEM via services.exe using Advapi/Negotiate)</description>
<options>no_full_log</options>
</rule>
</group>
Problem:
In Wazuh-Regeln heißen die Felder nicht data.win.…, sondern z. B.:
win.system.eventIDwin.eventdata.logonType- usw.
data. siehst du später im Index (z. B. in OpenSearch/Kibana), aber für den Regel-Parser gilt die Struktur aus archives.json bzw. aus dem Decoder – und dort sind die Feldnamen ohne data.
Erster Fix von Stuti: data. überall entfernen.
Zweiter Stolperstein: Regex & Backslashes
Im nächsten Schritt hakte es noch am Feld processName.
Im Alert sah das Feld so aus:
"processName": "C:\\\\Windows\\\\System32\\\\services.exe"
Das ist doppelt escaped, weil es durch mehrere Ebenen (JSON, Konsole, UI) ging.
In der Regel muss der Pfad so angegeben werden, wie er nach der Dekodierung vorliegt – und im Wazuh-Regel-Regex gelten eigene Regeln.
Kashifs Zwischenversion:
<field name="win.eventdata.processName" type="pcre2">(?i)^C:\\Windows\\System32\\services\.exe$</field>
Dazu zwei wichtige Punkte:
- Standard-Wazuh-Regex (ohne
type="pcre2"):.wird als Wildcard interpretiert- willst du einen echten Punkt matchen, darfst du ihn nicht escapen:
<field name="somefield">program.exe</field> program\.exewäre hier falsch und würdeprogramXexeetc. matchen
- Mit
type="pcre2"gilt klassische PCRE2-Syntax
→ da istprogram\.exekorrekt, wenn du einen Punkt literal willst.
Stuti ist einen Schritt einfacher gegangen und hat gar kein pcre2 benutzt, sondern die Literal-Variante sauber mit Backslashes angegeben.
Die funktionierende Version:
<group name="windows,authentication,service_logons">
<!-- Suppress normal Windows service logons -->
<rule id="100003" level="0">
<if_sid>60106</if_sid>
<field name="win.system.eventID">4624</field>
<field name="win.eventdata.logonType">5</field>
<field name="win.eventdata.authenticationPackageName">Negotiate</field>
<field name="win.eventdata.logonProcessName">Advapi</field>
<field name="win.eventdata.processName">C:\\\\Windows\\\\System32\\\\services.exe</field>
<description>Ignore normal Windows service logons (SYSTEM via services.exe)</description>
<options>no_full_log</options>
</rule>
</group>
Warum vier Backslashes?
- In XML schreibst du
C:\\\\Windows... - Nach Parsing / Interpretation landet das beim Regex-Engine als
C:\\Windows... - Und das entspricht dann einem Windows-Pfad mit einem Backslash.
Warum level="0" und if_sid?
Zwei wichtige Design-Entscheidungen der Regel:
1. if_sid 60106 – auf bestehende Logik aufbauen
Rule 60106 ist eine Standardregel im Wazuh-Ruleset:
Windows Logon Success
Sie triggert bereits korrekt auf erfolgreiche Windows-Logons.
Statt das Rad neu zu erfinden, nimmt Kashif:
<if_sid>60106</if_sid>
Damit sagt er:
„Nur Alerts, die bereits die 60106 ausgelöst haben, sollen nun zusätzlich meine Bedingungen matchen.“
Das ist sauber, robust und zukunftssicher, weil du der bestehenden Wazuh-Logik vertraust.
2. level="0" – komplett unterdrücken
level="0" bedeutet:
- Kein Alert in
wazuh-alerts-* - Kein Eintrag in der UI
- Kein E-Mail-Alert (außer du überschreibst das explizit, was hier nicht der Fall ist)
So werden genau diese Routine-Service-Logons voll unterdrückt – alle anderen Logons (z. B. interaktiv, RDP, Netzwerk) bleiben weiterhin sichtbar.
Woher bekomme ich den „richtigen“ Raw-Log für meine Regel?
Kashif wollte wissen:
„Wie kommst du an genau den Log, den Wazuh intern benutzt? Event Viewer sieht anders aus.“
Antwort von Stuti:
- Archivierung aktivieren (auf Manager-Seite)
Inossec.conf:<logall>yes</logall> <logall_json>yes</logall_json>(Achtung: mehr Storage-Verbrauch!) - Logs anschauen:
cat /var/ossec/logs/archives/archives.json | grep <keyword>Dort siehst du genau den JSON-Event, auf dessen Basis die Wazuh-Regeln arbeiten.
Und daraus kannst du sauber Feldnamen wiewin.eventdata.processNameübernehmen. - Regel mit
wazuh-logtesttesten
So siehst du direkt, ob dein Regelwerk greift, bevor es live geht.
Zusätzlich hat Kevin Branch noch auf sein eigenes Toolset verwiesen, das speziell das Testen von Windows EventChannel-Logs gegen Wazuh-Regeln vereinfacht – ideal, wenn du öfter mit solchen Custom-Rules arbeitest.
Muster für eigene „Noise-Filter“-Regeln
Die Vorgehensweise aus diesem Beispiel kannst du generell nutzen, um andere Noise-Events zu reduzieren:
- Event identifizieren, das du unterdrücken willst
– im Dashboard oder direkt ausarchives.json. - Standardregel finden, die darauf triggert
→ im Alertrule.idanschauen (z. B.60106). - Eigene Rule schreiben mit:
if_sidoderif_matched_sidauf diese ID- mehreren
<field>-Bedingungen, um das Event sehr konkret einzugrenzen
(ID, Typ, Prozess, User, etc.) level="0"für vollständige Unterdrückung
oder z. B.level="1"für „fast unsichtbar, aber noch suchbar“
- Regex-Syntax beachten
- Standard-Regex ≠ PCRE2
- Punkt, Backslashes, Anker (
^,$) bewusst einsetzen
- Manager neu starten
systemctl restart wazuh-manager - Im Zweifel: mit
wazuh-logtestundarchives.jsonprüfen.
Fazit: Von „zu viel Noise“ zu „gezielt ruhiggestellt“
Ausgangssituation:
Das Dashboard war voll mit erfolgreichen, systeminternen Service-Logons, die niemanden interessieren, aber die Sicht auf echte Auffälligkeiten stören.
Durch:
- korrekte Feldnamen (
win.event*stattdata.win.*), - saubere Regex für den Prozesspfad,
- Nutzung der bestehenden Rule
60106als Basis, - und
level="0"zur vollständigen Unterdrückung
hat Kashif das Problem sauber gelöst – und nebenbei eine sehr gute Blaupause für weitere Suppression-Regeln gebaut.
https://wazuh.slack.com/archives/C0A933R8E/p1761898091851149