Wazuh + MISP + Sysmon: Warum Logtest klappt, aber live keine MISP-Alerts kommen (und warum full_log alles kaputtmachen kann)

In diesem Thread ging es um ein Problem, das in der Praxis extrem häufig ist:

  • Im wazuh-logtest lässt sich ein MISP-IOC-Event sauber decodieren und die Regel feuert.
  • Live vom Windows-Agent (z. B. ping google.com) kommen zwar Sysmon-Alerts (Event 22), aber keine MISP-Integration-Alerts.
  • In ossec.log tauchen zudem Fehler auf wie KeyError: 'data' und später Indexing-Probleme rund um full_log.

Hier ist die Essenz + die eigentliche Root Cause-Kette.

1) Warum Logtest funktioniert, aber live nicht

wazuh-logtest prüft nur:

  • Decoder + Regeln auf einer Test-Logzeile (statisch).

Live passiert zusätzlich:

  • Der Integratord muss das Script ausführen
  • Das Script muss den korrekten IOC-Wert aus dem Alert ziehen
  • Das Script muss danach ein Event zurück in die Queue schicken
  • Filebeat muss es indexieren (Dashboard-Sichtbarkeit)

Heißt: Logtest kann “grün” sein, obwohl die Integration live an einer anderen Stelle bricht.

2) Der echte Showstopper: KeyError: 'data' (und sha256_after)

In den Logs stand wiederholt:

  • KeyError: 'data'
  • KeyError: 'sha256_after'

Das bedeutet:
Das Script erwartet Felder wie alert["data"][...] bzw. alert["syscheck"]["sha256_after"], aber bekommt Alerts, in denen diese Keys nicht vorhanden sind.

Warum passiert das?

  • Du hast die Integration so konfiguriert, dass sie auf Gruppen läuft:
<integration>
  <name>custom-misp</name>
  <group>sysmon_event1,sysmon_event3,sysmon_event6,sysmon_event7,sysmon_event15,sysmon_event22,syscheck</group>
  <alert_format>json</alert_format>
</integration>

Damit wird das Script (je nach Umgebung/Regeln) auch auf Events losgelassen, die nicht exakt dem erwarteten Schema entsprechen → Script crasht → kein MISP-Output.

Fix-Ansatz (prinzipiell):

  • Script defensiv machen (.get() statt [...])
  • Nur dann weiterarbeiten, wenn der erwartete Pfad existiert
  • Oder Integration enger fassen (z. B. nur bestimmte Rule-IDs statt breite Gruppen)

Das ist auch der Grund, warum es “auf frischem Wazuh” bei dir plötzlich ging: Dort waren vermutlich weniger Custom Rules / andere Groups / weniger “unerwartete” Events.

3) Warum MISP-Alerts zwar erzeugt werden, aber nicht im Dashboard erscheinen

Später kam der zweite große Knackpunkt:

Indexer-Fehler durch Field Mapping Conflict bei full_log:

failed to parse field [full_log] of type [text]
Can't get text on a START_OBJECT

Was heißt das?

  • In der Wazuh-Index-Template ist full_log als text/string definiert.
  • Dein MISP-Script (bzw. der Event-Aufbau) hat full_log als JSON-Objekt geliefert (START_OBJECT).
  • Ergebnis: Filebeat kann das Event nicht indexieren → Dashboard zeigt es nicht.

Das ist genau das, was du im Filebeat-Warnlog gesehen hast: HTTP 400 mapper_parsing_exception.

Wichtig: Das Event existiert dann trotzdem oft noch lokal in:

  • /var/ossec/logs/alerts/alerts.json
    aber es landet nicht sauber im wazuh-alerts-* Index.

4) Der Workaround, der wirklich hilft: no_full_log

Ihr habt es dann pragmatisch gelöst:

  • In MISP-Regeln: <options>no_full_log</options>

Damit wird full_log nicht mehr (oder nicht in der Form) in den Index gepusht → kein Mapping-Konflikt → Alerts erscheinen wieder.

Das ist ein legitimer Fix, weil:

  • Die “wertvollen” Felder stehen ohnehin in data.misp.*
  • full_log ist meistens nur “raw payload ballast”

5) Warum Bony John “google.com ist nicht in MISP” sagte – und es bei dir doch matchte

Das war ein Nebenschauplatz: Je nach aktivierten Feeds kann google.com tatsächlich auftauchen (z. B. OSINT-Falschpositive / Beispiel-IOCs). In eurem Thread wurde später bestätigt, dass es bei aktivierten Feeds durchaus matchen kann.

Praxis-Tipp:

  • Falls du “saubere” IoCs willst: Feeds selektiv aktivieren, OSINT-Daten regelmäßig bereinigen, und Test-IOCs in einem eigenen Event halten.

6) Best-Practice: So würde ich’s “richtig” bauen

Wenn du Stabilität willst:

  1. Script robust machen
    • überall .get() und früh exit’en, wenn Feldpfade fehlen
  2. Enrichment-Event klein halten
    • kein full_log als Objekt pushen
    • nur relevante MISP-Felder + Kontext (Agent, Quelle, Sysmon queryName etc.)
  3. Decoder nicht über Regex auf Raw-String erzwingen, wenn du sowieso JSON hast
    • lieber JSON direkt (Wazuh JSON decoder) + Regeln auf data.misp.*
  4. Index-Mapping nicht “quickfixen”, wenn’s nur MISP betrifft
    • sonst riskierst du Konflikte bei anderen Pipelines

https://wazuh.slack.com/archives/C0A933R8E/p1764139986109309