Usecases mit wazuh

Logeinträge zu Alarmen korrelieren.

Usecases mit wazuh

In der heutigen IT-Landschaft ist die Analyse von Logdaten ein fundamentaler Bestandteil der Sicherheitsüberwachung. Dieser Artikel beleuchtet die Bedeutung von Use Cases in Wazuh, einem Open-Source SIEM-System, um spezifische Sicherheitsbedrohungen zu erkennen. Anhand eines konkreten Beispiels eines verdächtigen Webserver-Logeintrags wird demonstriert, wie ein solcher Use Case in Wazuh implementiert werden kann, um ähnliche Ereignisse zukünftig proaktiv zu erkennen und sich anbahnende Angriffe zu verhindern.

Was ist ein Usecase?

Ein Use Case beschreibt die technische Umsetzung einer konkreten Fragestellung. Zwei Beispiele:

  1. Brute-Force-Erkennung:
    Frage: Versucht jemand auffällig oft, sich an meinem Server anzumelden, und ist der Angriff erfolgreich?
    Lösung: Ich überwache fehlgeschlagene Login-Versuche. Falls sich dieselbe IP später erfolgreich anmeldet, deutet das auf einen erfolgreichen Angriff hin – und ich möchte sofort benachrichtigt werden.
  2. Ungewöhnlicher Netzwerkzugriff durch eine Photovoltaikanlage:
    Frage: Versucht meine PV-Anlage, auf andere Systeme in meinem Netzwerk zuzugreifen?
    Lösung: Normalerweise sendet die Anlage nur Daten an den Hersteller. Falls sie jedoch plötzlich interne Systeme scannt oder darauf zugreift, ist das verdächtig. Genau das ist mir passiert – ein Grund, warum ich mein Netzwerk massiv auf Selfhosting umgestellt habe.

Ein Beispiel aus der Praxis

Wenn jemand meinen Webserver besucht, tut er das normalerweise indem er die passende URL in seinen Browser eingibt: https://www.meister-security.de. Dann landet er genau hier 😄.

Ruft jemand jedoch den Webserver mit seiner IP-Adresse, also zum Beispiel https://35.212.132.126/, dann habe ich ihn so konfiguriert, dass er nicht antworten soll (in der Hoffnung, dass die Script-Kiddies weiterziehen).

Eigener Webserver mit offiziellen Zertifikaten
Der Basis-Artikel für alle folgenden Services, die ich hier demonstrieren werde…

Anstelle der Conratulations Page stelle ich im Proxy einfach auf No Response um, sodass der Fehler 444 ausgegeben wird.

Rufe ich meine Server jetzt mit seiner IP, sehe ich folgendes:

Der Aufruf hinterlässt natürlich einen Logeintrag, aus dem ich sofort erkennen kann, dass die IP, die den Server auf diese Weise kontaktiert, nichts Gutes im Schilde führt.

3.135.227.145 - - [24/Mar/2025:04:32:21 +0000] "GET /.git/config HTTP/1.1" 444 0 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 12_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/7.0.5(0x17000523) NetType/4G Language/zh_CN"

Am liebsten würde ich diesen User direkt für alle meine Services auf diesem Server sperren. Und genau das soll der Usecase werden, den ich hier aufbauen werde.

Der Usecase: IPs sperren, die keine guten Absichten zeigen

Die erste Frage, die ich dafür klären muss: Welche Informationen brauche ich, um das zu erkennen?

Das ist in diesem Fall recht einfach: Die Logfiles des Webservers. Die befinden sich hier:

Ich kann sie meinem SIEM leicht zur Verfügung stellen, damit es diese beobachten kann. Dafür lege ich im Config-File des wazuh-agent einen neuen Abschnitt an:

<localfile>
  <location>/var/docker/web/nginx-proxy-manager/data/logs/*.log</location>
  <log_format>syslog</log_format>
</localfile>

Und so kann wazuh nun die Logs mitlesen.

Falls Wazuh das Logformat nicht kennt, muss ich meinem SIEM erst beibringen, welche Bedeutung die einzelnen Einträge haben – dieser Prozess wird Parsing genannt. Dafür habe ich zwei Möglichkeiten: Entweder ich frage meine lokale KI, oder ich probiere es einfach direkt aus.

Antwort in open-webui

Auf regex101.com ausprobiert:

Ist der Logeintrag erfolgreich in seine Bestandteile zerlegt, kann der Parser mit der gefundenen Regex konfiguriert werden. Dies geschieht in der Datei /var/ossec/etc/decoders/local_decoder.xml

Decoder konfigurieren

In der Datei /var/ossec/etc/decoders/local_decoder.xml fügen wir nun unseren Parser für das Logfile hinzu:

<decoder name="npm-access-logs">
    <prematch>^\d+\.\d+\.\d+\.\d+ </prematch>
    <regex>(\S+) (\S+) (\S+) \[([^\]]+)\] "(\S+) (\S+) (\S+)" (\d+) (\d+) "([^"]*)" "([^"]*)"</regex>
    <order>srcip auth_srv auth_user time method url protocol id bytes_sent referer user_agent</order>
</decoder>

Und damit ist wazuh auch schon in der Lage die Logs zu interpretieren.

Rules konfigurieren

Jetzt gilt es zu konfigurieren, was wazuh machen soll. Dies macht man in der Datei /var/ossec/etc/rules/local_rules.xml.

<rule id="31101" level="5">
<id>444</id>
<description>Web server 444 error code.</description>
<group>attack,pci_dss_6.5,pci_dss_11.4,gdpr_IV_35.7.d,nist_800_53_SA.11,nist_800_53_SI.4,tsc_CC6.6,tsc_CC7.1,tsc_CC8.1,tsc_CC6.1,tsc_CC6.8,tsc_CC7.2,tsc_CC7.3,</group>
</rule>

Diese Regel mit der ID 31101 ist eine Sicherheitsregel mit einem Alarm-Level von 5, die sich auf den HTTP-Statuscode 444 bezieht.

  • ID: 31101 → Eindeutige Regelkennung im System.
  • id: 444 → Die Regel betrifft den HTTP-Statuscode 444, der in Nginx verwendet wird.
  • description: Die Regel identifiziert ein Ereignis, bei dem ein Webserver den 444-Fehlercode zurückgibt.
  • level: 5 → Weist auf eine mittlere oder erhöhte Priorität hin (je nach System).
  • group: Die Regel ist mit mehreren Sicherheitsstandards und Compliance-Anforderungen verknüpft, darunter:
    • PCI DSS (Payment Card Industry Data Security Standard)
    • GDPR (Datenschutz-Grundverordnung)
    • NIST 800-53 (US-Sicherheitsstandard für Informationssysteme)
    • TSC (Trust Services Criteria – relevant für Audits und Sicherheit)

Nach einem systemctl restart wazuh-manager kann man überprüfen, ob die Rule den Logeintrag korrekt verarbeitet. Dazu startet man das Tool wazuh-logtest und kopiert einen Logeintrag in die Konsole:

Hier lässt sich gut beobachten, wie Wazuh darauf reagiert:

  • Phase 1: Das Event wird erkannt.
  • Phase 2: Die relevanten Daten werden extrahiert und in ihre Felder zerlegt.
  • Phase 3: Das Regelwerk wird auf das Log angewendet.

Doch das allein reicht uns nicht – wir wollen gezielt IP-Adressen sperren, die dieses Verhalten zeigen. Dafür gibt es aktive Antworten („active-responses“). In diesem Fall soll eine Firewall den Kontakt zum Angreifer unterbrechen und die IP für 180 Sekunden sperren. Das dürfte eine Brute-Force-Attacke erheblich verlangsamen. Zudem erhält mein Server morgen ohnehin eine neue IP-Adresse vom Provider, was den Angreifer zusätzlich ausbremst.

Angreifer aussperren mittels Active Responses

In der zentralen Konfigurationsdate von wazuh /var/ossec/etc/ossec.conf sagen wir nun, dass falls die Rule 31101 zutrifft, wir eine DROP-RULE auf der Hostfirewall (iptables) für die srcip aktivieren wollen. Dazu fügen wir wieder einen neuen Abschnitt hinzu:

  <active-response>
    <command>firewall-drop</command>
    <location>local</location>
    <rules_id>31101</rules_id>
    <timeout>180</timeout>
  </active-response>

Falls man später noch mehr Regeln erstellt hat, die zur Sperrung des Users führen sollen, kann man die Liste kommagetrennt erweitern. Und wieder folgt einsystemctl restart wazuh-manager um alles scharfzuschalten.

Logs prüfen

Ein Blick in die Logs zeigt (von unten nach oben), dass die IP 103.102.230.8 direkt auf den Server zugegriffen hat, woraufhin sie sofort gesperrt wurde. Drei Minuten später erfolgte die Freigabe, doch seitdem tauchte die IP nicht mehr auf – offenbar hat der Angreifer aufgegeben und ist weitergezogen. Kurz darauf versuchen es die nächsten Angreifer.

Ein voller Erfolg

Jetzt muss ich mich um solche Störenfriede nicht mehr kümmern, da wazuh die Situation im Auge behält. Mal schauen, wie oft die Rule 31101 jetzt getriggert wurde.

rule 31101

Es ist klar ersichtlich, dass die Sperrung des Angreifers um 12:31 die Anzahl seiner Versuche erheblich reduziert hat, sodass weitere Angriffe ins Leere laufen. Stattdessen tauchen nun hauptsächlich neue IPs im Alarm-Log auf, die jeweils ihren ersten Versuch starten.

Doch manchmal möchte man komplexere Zusammenhänge abbilden.

Komplexere Rules

Um einen erfolgreichen Angriff zu verhindern, ist es entscheidend, die einzelnen Phasen eines Angriffs zu erkennen. Dazu gehört zunächst die Reconnaissance-Phase, in der ein Angreifer erkundet, welche Dienste der Server anbietet. Anschließend kann ein Brute-Force-Angriff folgen, der darauf abzielt, Zugangsdaten zu erraten. Gelingt der Login, besteht die Gefahr einer Persistierung oder einer lateralen Bewegung innerhalb des Netzwerks.

Mit Wazuh lässt sich dieser Ablauf einfach abbilden. Dazu können gezielt Regeln erstellt werden: Eine Regel zur Erkennung eines Portscans, eine weitere für fehlgeschlagene Login-Versuche und schließlich eine, die einen erfolgreichen Login von derselben Quell-IP identifiziert.

<group name="linux,sshd">
  <!-- Regel 200001: Mehrere fehlgeschlagene SSH-Anmeldeversuche -->
  <rule id="200001" level="12" frequency="3" timeframe="120">
    <decoded_as>sshd</decoded_as>
    <!-- Erfasst fehlgeschlagene Anmeldeversuche, z. B. "Failed password" -->
    <match>Failed password</match>
    <!-- Gruppiert Events anhand der Quell-IP -->
    <same_field>srcip</same_field>
    <description>Fehlgeschlagene SSH-Anmeldeversuche – 3 Versuche in 120 Sekunden</description>
    <mitre>
      <id>T1110</id>
    </mitre>
    <group>authentication_failed,linux_sshd</group>
  </rule>

  <!-- Regel 200002: Alarmierung bei erfolgreicher SSH-Anmeldung nach fehlgeschlagenen Versuchen -->
  <rule id="200002" level="12">
    <if_matched_sid>200001</if_matched_sid>
    <decoded_as>sshd</decoded_as>
    <!-- Erfasst erfolgreiche Anmeldungen, z. B. "Accepted password" -->
    <match>Accepted password</match>
    <same_field>srcip</same_field>
    <description>Erfolgreiche SSH-Anmeldung nach mehrfachen fehlgeschlagenen Versuchen – möglicher Brute-Force-Angriff</description>
    <group>authentication_success,linux_sshd</group>
  </rule>
</group>

Dabei sollen diese Regeln folgendes erkennen:

  • Regel 200001: Diese Regel wird ausgelöst, wenn innerhalb von 120 Sekunden mindestens drei SSH-Fehlversuche (z. B. "Failed password") von derselben Quell-IP (srcip) erkannt werden. Damit wird ein mögliches Brute-Force-Muster erfasst.
  • Regel 200002: Sobald nach den fehlgeschlagenen Versuchen eine erfolgreiche SSH-Anmeldung (z. B. "Accepted password") erfolgt – wieder von derselben Quell-IP – wird ein Alarm generiert.

Dieses Ruleset weist darauf hin, dass trotz mehrerer Fehlversuche der Zugang letztlich gewährt wurde. Ich könnte auch dann wieder mit einer Active-Response reagieren.

Fazit

Wazuh ist äußerst flexibel: Jede Quelle, die Logfiles erzeugt, kann für eine Reaktion genutzt werden. Also auch einen Wasserzählerstand:

So habe ich letztlich über meine Firewall-Logs bemerkt, dass mein Wechselrichter versucht hat, sich auf anderen Systemen in meinem Haus einzuloggen! Die Konsequenz? Kein Internetzugriff mehr für das Gerät – stattdessen visualisiere ich die relevanten Informationen nun in meinem eigenen Dashboard.

Ich habe bereits mit vielen SIEMs gearbeitet und dabei sämtliche Kategorien kennengelernt: von "hübsch, aber nur für Windows nützlich" über "leistungsstark, aber teuer" bis hin zu "genial, flexibel und kostenlos". Welches SIEM in welche Kategorie fällt? Das überlasse ich meinen Lesern. 😉