Realtime-Attack-Map
SURICATA / LIVE FEED

Dirty Frag & Copy Fail: Echtzeit-Erkennung mit Wazuh und automatischer Gegenwehr

File Integrity Monitoring versagt bei Page-Cache-Exploits - nur Syscall-Monitoring schlägt an.

Dirty Frag & Copy Fail: Echtzeit-Erkennung mit Wazuh und automatischer Gegenwehr

Wer nach dem Auftauchen von Dirty Frag und Copy Fail instinktiv die Dateiüberwachung in seinem SIEM aktiviert, um auf der sicheren Seite zu sein, liegt leider komplett falsch - beide Exploits schreiben ausschließlich in den RAM-seitigen Page Cache, ohne die Festplattenkopie jemals zu berühren. Die einzig wirksame Echtzeiterkennung ist verhaltensbasiert: auditd auf Syscall-Ebene kombiniert mit passenden Wazuh-Regeln. Kritische Infrastrukturen sollten hier unbedingt handeln. Dieser Beitrag zeigt den aktuellen Stand meines vollständigen Setups - inklusive Active Response, die den Exploit-Prozess killt oder den kompromittierten Rechner automatisch vom Netz nimmt.

    Warum klassische FIM-Überwachung hier blind ist

    Wer den Artikel zu Dirty Frag gelesen hat, kennt das Prinzip bereits: Der Exploit überschreibt nicht die Datei /usr/bin/su auf der Festplatte, sondern die im RAM gehaltene Page-Cache-Kopie davon. Der Kernel verwendet bei späteren Zugriffen die manipulierte RAM-Version, ohne dass ein Writeback auf den Storage erfolgt. Aus diesem Grunde kann File Integrity Monitoring (FIM) diese Manipulation nicht sehen.

    Konkret sieht das so aus:

    Klassischer FIM-Ansatz:
      Datei von Disk lesen -> Hash berechnen -> Vergleich -> kein Befund
    
    Dirty Frag / Copy Fail Realität:
      /usr/bin/su auf Disk  = UNVERÄNDERT (identischer Hash)
      /usr/bin/su im RAM    = ENTHÄLT ROOT-SHELL-ELF
      FIM-Ergebnis          = BLIND
    

    Das gilt für beide Schwachstellen: Copy Fail (CVE-2026-31431) nutzt AF_ALG-Sockets mit splice() über algif_aead, Dirty Frag (CVE-2026-43284 / CVE-2026-43500) erreicht denselben Effekt über vmsplice + splice durch den esp_input()- bzw. rxkad_verify_packet_1()-Decrypt-Pfad. Die Schnittstelle, über die der Page Cache korrumpiert wird, ist verschieden - das blinde Fleck-Problem für FIM bleibt dasselbe.

    Das ist übrigens auch der Grund, warum die Copy-Fail-Mitigation (algif_aead blacklisten) keinen Schutz gegen Dirty Frag bietet: Beide teilen zwar denselben authencesn-Sink im Kernel, werden aber über völlig unterschiedliche Code-Pfade erreicht.

    Die Exploit-Kette beider Varianten

    Für das Verständnis der Erkennungsregeln ist es wichtig, die genauen Syscall-Sequenzen zu kennen.

    Dirty Frag - Variante ESP (CVE-2026-43284)
    unshare(CLONE_NEWUSER|CLONE_NEWNET)   <- User Namespace: CAP_NET_ADMIN intern
      -> XFRM SA via Netlink registrieren  <- ESP-SA anlegen
      -> vmsplice(ESP-Header in Pipe)      <- [!] Angreifer-Bytes in Pipe pflanzen
      -> splice(Zieldatei in Pipe)         <- [!] Page Cache der Zieldatei in Pipe
      -> splice(Pipe an UDP-Socket)        <- Kernel-Decrypt-Pfad aktivieren
      -> esp_input() AEAD-Decrypt          <- 4 Bytes deterministisch in Page Cache
      -> execve(/usr/bin/su)               <- Korrumpiertes SUID-Binary läuft als root
    

    Auf Ubuntu 24.04+ ist diese Variante durch apparmor_restrict_unprivileged_userns=1 standardmäßig blockiert - auditd protokolliert den Versuch trotzdem (AppArmor-AUDIT-Event), was Regel 200002 auslöst. Der Exploit-Binary switcht dann automatisch auf Variante 2.

    Dirty Frag - Variante RxRPC (CVE-2026-43500)
    add_key("rxrpc", ...)      <- Kein Privilege erforderlich - Session Key K
      -> socket(AF_RXRPC=35)   <- rxrpc.ko wird automatisch geladen
      -> vmsplice(RxRPC-Header) <- [!] Wire-Header in Pipe
      -> splice(Zieldatei)      <- [!] /etc/passwd Page Cache in Pipe
      -> splice(Pipe an UDP)    <- Decrypt-Pfad: rxkad_verify_packet_1()
      -> 8 Bytes in /etc/passwd <- root-Eintrag: leeres Passwortfeld
      -> su -                   <- Root-Login ohne Passwort
    

    Diese Variante umgeht AppArmor vollständig, läuft ohne jede Erhöhung im Namespace und ist auf allen Linux-Kerneln seit Commit 2dc334f1a63a (Juni 2023) verwundbar - ein Kernel-Patch existiert bisher nicht.

    Copy Fail (CVE-2026-31431)
    socket(AF_ALG=38, SOCK_SEQPACKET, 0)  <- Kein Privilege
      -> bind() an authencesn              <- Vulnerable Code Path
      -> sendmsg() mit AAD-Payload         <- Bytes 4-7 = Zielwert
      -> splice()                          <- [!] Page Cache in writable SGL
      -> recv()                            <- authencesn schreibt seqno_lo
      -> execve(/usr/bin/su)               <- Root
    

    Erkennungsarchitektur

    Das Detection-Repository von mym0us3r implementiert zwei voneinander unabhängige Erkennungsschichten, die weder den Kernel-Patchstand noch die Distribution voraussetzen.

    GitHub - mym0us3r/DIRTY-FRAG-Detection-with-Wazuh-4.14.4: Wazuh 4.14.4 detection rules for CVE-2026-43284 / CVE-2026-43500 (Dirty Frag) - Linux Local Privilege Escalation via page cache write
    Wazuh 4.14.4 detection rules for CVE-2026-43284 / CVE-2026-43500 (Dirty Frag) - Linux Local Privilege Escalation via page cache write - mym0us3r/DIRTY-FRAG-Detection-with-Wazuh-4.14.4
    Schicht Methode Aktualisierungsfrequenz
    Layer 1 Verhaltensbasiert: auditd Syscall-Sensor + Wazuh-Regeln Echtzeit
    Layer 2 Konfigurationsbasiert: SCA-Policy Alle 12 Stunden

    Für Copy Fail existiert ein paralleles Repository: COPY-FAIL-Detection-with-Wazuh-4.14.4 mit den Regeln 199600-199607. Beide Regelsätze koexistieren problemlos auf demselben Wazuh-Manager - die auditd-Key-Namespaces (dirty_frag_* vs. copy_fail_*) und Regel-IDs überlappen nicht.

    GitHub - mym0us3r/COPY-FAIL-Detection-with-Wazuh-4.14.4: Wazuh 4.14.4 detection rules for CVE-2026-31431 (Copy Fail) - Linux Local Privilege Escalation via authencesn page cache write
    Wazuh 4.14.4 detection rules for CVE-2026-31431 (Copy Fail) - Linux Local Privilege Escalation via authencesn page cache write - mym0us3r/COPY-FAIL-Detection-with-Wazuh-4.14.4

    Layer 1 - auditd als Syscall-Sensor

    auditd beobachtet die Syscall-Ebene des Kernels und schreibt Ereignisse nach /var/log/audit/audit.log. Wazuh liest diesen Log und verarbeitet ihn durch seine Regelmaschine.

    Ein Detail ist dabei kritisch: Die ESP-Variante ruft unshare(CLONE_NEWUSER) auf und mappt sich selbst als uid=0 im neuen Namespace. Der Kernel-Audit-Subsystem schreibt diese Namespace-interne UID in SYSCALL-Events - ein Filter -F uid!=0 würde die anschließenden vmsplice/splice-Events des Exploit-Prozesses damit unsichtbar machen. Deshalb verwenden die Sensor-Regeln für vmsplice und splice stattdessen -F auid>=1000: Die auid (Login-UID) wird beim Login gesetzt und lässt sich durch Namespace-Remapping nicht verändern.

    Die Sensor-Regeln werden als Datei /etc/audit/rules.d/cve-dirty-frag.rules abgelegt:

    # Dirty Frag / CVE-2026-43284+43500 - auditd Sensor Rules
    # Quelle: github.com/mym0us3r/DIRTY-FRAG-Detection-with-Wazuh-4.14.4
    
    # vmsplice: Protokoll-Header in Pipe pflanzen (beide Varianten)
    # auid statt uid - wegen User-Namespace-Remapping im ESP-Pfad
    -a always,exit -F arch=b64 -S vmsplice -F auid>=1000 -F auid!=-1 -k dirty_frag_vmsplice
    -a always,exit -F arch=b32 -S vmsplice -F auid>=1000 -F auid!=-1 -k dirty_frag_vmsplice
    
    # splice: Zieldatei-Page-Cache in Pipe bringen (beide Varianten)
    -a always,exit -F arch=b64 -S splice   -F auid>=1000 -F auid!=-1 -k dirty_frag_splice
    -a always,exit -F arch=b32 -S splice   -F auid>=1000 -F auid!=-1 -k dirty_frag_splice
    
    # unshare(CLONE_NEWUSER): ESP-Variante - User Namespace Escape
    -a always,exit -F arch=b64 -S unshare  -F uid!=0                  -k dirty_frag_ns_escape
    
    # add_key("rxrpc"): RxRPC-Session-Key pflanzen - ohne Privileges
    -a always,exit -F arch=b64 -S add_key  -F uid!=0                  -k dirty_frag_add_key
    
    # socket(AF_RXRPC): rxrpc.ko Auto-Load Trigger
    -a always,exit -F arch=b64 -S socket   -F a0=0x23 -F uid!=0       -k dirty_frag_rxrpc_socket
    
    # kmod/modprobe Ausführung: esp4/esp6/rxrpc Modul-Load
    -w /usr/bin/kmod -p x                                              -k dirty_frag_modload
    
    # execve /usr/bin/su: LPE-Nachweis - auid statt uid
    -a always,exit -F arch=b64 -S execve -F exe=/usr/bin/su -F auid>=1000 -F auid!=-1 -k dirty_frag_execve_su
    

    Für Copy Fail kommen analog die Regeln aus cve-2026-31431.rules in eine separate Datei /etc/audit/rules.d/cve-copy-fail.rules.

    Layer 2 - Wazuh Detection Rules

    Die neun Erkennungsregeln für Dirty Frag (IDs 200000-200008) gehen in /var/ossec/etc/rules/local_rules.xml. Sie bauen alle auf dem Wazuh-Built-in-Anker 80700 (decoded_as=auditd) auf. Die offiziellen Regeln werden direkt aus dem Repository bezogen:

    git clone https://github.com/mym0us3r/DIRTY-FRAG-Detection-with-Wazuh-4.14.4.git
    git clone https://github.com/mym0us3r/COPY-FAIL-Detection-with-Wazuh-4.14.4.git
    

    Zur Orientierung - so sieht die Regelarchitektur aus (Level und Parent-Beziehungen):

    Regel-ID Parent Signal Level
    200000 80700 vmsplice() - Header in Pipe 10
    200001 80700 splice() - Page Cache in Pipe 10
    200002 80700 unshare(CLONE_NEWUSER) - ESP-Pfad 12
    200003 80700 add_key("rxrpc") - RxRPC-Key 8
    200004 80700 socket(AF_RXRPC) - Modul-Load 10
    200005 80700 kmod/modprobe-Ausführung 12
    200006 80700 execve /usr/bin/su mit euid=root 6
    200007 200001 + if_matched=200000 CHAIN ESP: vmsplice + splice, gleiche PID, 120s 15
    200008 200001 + if_matched=200004 CHAIN RXRPC: AF_RXRPC + splice, gleiche PID, 120s 15

    Die Kettenregeln 200007 und 200008 sind das Herzstück der Erkennung: Sie feuern, wenn zwei Signale vom selben Prozess innerhalb von 120 Sekunden eintreffen. vmsplice gefolgt von splice aus derselben PID ist die unvermeidliche Kern-Sequenz beider Exploit-Varianten - da führt kein Weg dran vorbei. Level 15 in Wazuh entspricht der höchsten Kritikalitätsstufe.

    Zum Einfügen und Validieren:

    # Regeln für Dirty Frag einbinden
    cat DIRTY-FRAG-Detection-with-Wazuh-4.14.4/rules/local_rules.xml \
        >> /var/ossec/etc/rules/local_rules.xml
    
    # Regeln für Copy Fail einbinden
    cat COPY-FAIL-Detection-with-Wazuh-4.14.4/rules/local_rules.xml \
        >> /var/ossec/etc/rules/local_rules.xml
    
    # Syntaxprüfung - muss mit Exit 0 und ohne Warnungen enden
    /var/ossec/bin/wazuh-analysisd -t 2>&1 | tail -5
    
    # Manager neu starten
    systemctl restart wazuh-manager
    

    Layer 3 - SCA Policy

    Die Security-Configuration-Assessment-Policy oder kurz SCA-Policy (sca/cve-dirty-frag.yml) führt alle 12 Stunden automatisierte Konfigurationschecks auf allen enrollten Agenten aus. Sie prüft, ob die verwundbaren Kernel-Module geladen sind, ob auditd läuft und ob die Sensor-Regeln aktiv sind:

    Check-ID Prüfung Risiko
    43284001 esp4-Modul nicht geladen HIGH
    43284002 esp6-Modul nicht geladen HIGH
    43284003 rxrpc-Modul nicht geladen HIGH
    43284004 Module via modprobe.d disabled HIGH
    43284005 auditd aktiv und läuft HIGH
    43284006 Dirty Frag auditd Sensor-Regeln deployed HIGH

    Ein frisches, noch nicht abgesichertes System erreicht einen Score von 50% - die Module sind zufällig nicht geladen, aber der Detection-Stack fehlt noch.

    Die Policy wird auf dem Manager deployed und per agent.conf an alle Agenten verteilt:

    # Policy auf Manager kopieren
    cp DIRTY-FRAG-Detection-with-Wazuh-4.14.4/sca/cve-dirty-frag.yml \
       /var/ossec/etc/shared/default/
    
    chown root:wazuh /var/ossec/etc/shared/default/cve-dirty-frag.yml
    chmod 660        /var/ossec/etc/shared/default/cve-dirty-frag.yml
    

    In /var/ossec/etc/shared/default/agent.conf:

    <agent_config>
      <sca>
        <policies>
          <policy>/var/ossec/etc/shared/cve-dirty-frag.yml</policy>
        </policies>
      </sca>
    </agent_config>
    

    Da die SCA-Policy c:lsmod- und c:systemctl-Checks ausführt, muss auf jedem Agenten Remote Command Execution einmalig aktiviert werden:

    echo "sca.remote_commands=1" >> /var/ossec/etc/local_internal_options.conf
    systemctl restart wazuh-agent
    

    Deployment Schritt für Schritt

    Schritt 1: auditd installieren und aktivieren
    # Ubuntu / Debian
    apt install auditd audispd-plugins -y
    systemctl enable --now auditd
    auditctl -s | grep enabled   # muss "enabled 1" zeigen
    
    # RHEL / Amazon Linux
    yum install audit -y
    systemctl enable --now auditd
    
    # SUSE
    zypper install audit -y
    systemctl enable --now auditd
    
    Schritt 2: auditd Sensor-Regeln deployen
    # Dirty Frag Regeln
    cp DIRTY-FRAG-Detection-with-Wazuh-4.14.4/auditd/cve-dirty-frag.rules \
       /etc/audit/rules.d/
    
    # Copy Fail Regeln
    cp COPY-FAIL-Detection-with-Wazuh-4.14.4/auditd/cve-2026-31431.rules \
       /etc/audit/rules.d/
    
    # Laden und verifizieren
    augenrules --load
    auditctl -l | grep -E "dirty_frag|copy_fail"
    
    Erwartete Ausgabe (9 Dirty Frag + Copy Fail Regeln):
    -a always,exit -F arch=b64 -S vmsplice -F auid>=1000 -F auid!=-1 -F key=dirty_frag_vmsplice
    -a always,exit -F arch=b32 -S vmsplice -F auid>=1000 -F auid!=-1 -F key=dirty_frag_vmsplice
    -a always,exit -F arch=b64 -S splice   -F auid>=1000 -F auid!=-1 -F key=dirty_frag_splice
    ...
    
    Schritt 3: auditd-Log in Wazuh einbinden

    In /var/ossec/etc/ossec.conf auf jedem überwachten Host (oder per agent.conf verteilen):

    <localfile>
      <log_format>audit</log_format>
      <location>/var/log/audit/audit.log</location>
    </localfile>
    

    Schritt 4: Wazuh-Regeln deployen (siehe Layer 2 oben)

    Schritt 5: SCA-Policy deployen (siehe Layer 3 oben)

    Validierung

    Vor dem Scharfschalten empfiehlt sich ein wazuh-logtest mit synthetischen auditd-Events. Das prüft, ob die Regeln korrekt feuern, ohne einen echten Exploit auszuführen:

    # Signal 1: vmsplice -> Regel 200000 erwartet
    echo 'type=SYSCALL msg=audit(1778261582.230:1155): arch=c000003e syscall=316 \
    success=yes exit=8 a0=3 a1=7fff00000000 a2=1 a3=0 items=0 ppid=1000 pid=93321 \
    auid=1000 uid=1000 gid=1000 euid=1000 suid=1000 fsuid=1000 egid=1000 sgid=1000 \
    fsgid=1000 tty=pts0 ses=58 comm="exp" exe="/home/kr/exp" subj=unconfined \
    key="dirty_frag_vmsplice"' | /var/ossec/bin/wazuh-logtest 2>&1 | grep -E "rule|level|200"
    

    Erwartete Ausgabe:

    Rule id: '200000'
    Rule level: '10'
    Rule description: 'Dirty Frag CVE-2026-43284/43500: vmsplice()'
    

    Für den Chain-Test (200007 - das eigentliche Alarmsignal):

    # Zwei Events in einer Pipe - gleiche PID, vmsplice + splice
    printf 'type=SYSCALL msg=audit(1777570010.000:200): arch=c000003e syscall=316 \
    success=yes exit=8 a0=3 a1=7fff00000000 a2=1 a3=0 items=0 ppid=1000 pid=55001 \
    auid=1000 uid=1000 gid=1000 euid=1000 suid=1000 fsuid=1000 egid=1000 sgid=1000 \
    fsgid=1000 tty=pts0 ses=58 comm="exp" exe="/home/kr/exp" key="dirty_frag_vmsplice"\n\
    type=SYSCALL msg=audit(1777570011.000:201): arch=c000003e syscall=275 success=yes \
    exit=4 a0=4 a1=5 a2=6 a3=0 items=0 ppid=1000 pid=55001 auid=1000 uid=1000 \
    gid=1000 euid=1000 suid=1000 fsuid=1000 egid=1000 sgid=1000 fsgid=1000 tty=pts0 \
    ses=58 comm="exp" exe="/home/kr/exp" key="dirty_frag_splice"\n' \
    | /var/ossec/bin/wazuh-logtest 2>&1 | grep -E "rule|level|200"
    

    Erwartete Ausgabe:

    Rule id: '200000'  Rule level: '10'   <- vmsplice Signal
    Rule id: '200007'  Rule level: '15'   <- CHAIN ESP CONFIRMED - SOFORT UNTERSUCHEN
    

    Nach einer echten Exploit-Ausführung (im Lab!) kann so geprüft werden, ob auditd alle Events aufgezeichnet hat:

    ausearch -k dirty_frag_vmsplice   --start today 2>/dev/null | grep "exe=" | head -5
    ausearch -k dirty_frag_ns_escape  --start today 2>/dev/null | grep "exe=" | head -5
    ausearch -k dirty_frag_execve_su  --start today 2>/dev/null | grep "EUID=" | head -5
    
    # Wazuh Alerts prüfen
    grep -E "200002|200005|200006|200007|200008" /var/ossec/logs/alerts/alerts.log | tail -10
    

    Active Response - Den Exploit-Prozess sofort killen

    Sobald Regel 200007 oder 200008 feuert, ist die Exploit-Kette am Laufen. Ein manueller Eingriff dauert zu lange - hier kommt Wazuhs Active Response ins Spiel.

    In Wazuh 4.x übergibt das Framework den kompletten Alert als JSON an das Active-Response-Skript via stdin. Das Skript liest data.audit.pid aus dem JSON und killt den Exploit-Prozess inkl. Parent.

    Das Skript wird auf dem Agenten (dem überwachten Host) abgelegt:

    # /var/ossec/active-response/bin/dirty-frag-kill.sh
    # M. Meister - Dirty Frag / Copy Fail: Exploit-Prozess beenden
    
    #!/bin/bash
    
    LOG="/var/ossec/logs/active-responses.log"
    
    # Alert-JSON von Wazuh via stdin lesen und PID extrahieren
    PID=$(python3 -c "
    import json, sys
    try:
        d = json.load(sys.stdin)
        print(d['parameters']['alert']['data']['audit']['pid'])
    except Exception:
        print('')
    " 2>/dev/null)
    
    if [ -z "$PID" ]; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') dirty-frag-kill: keine PID im Alert gefunden" >> "$LOG"
        exit 1
    fi
    
    # PID muss numerisch sein
    if ! [[ "$PID" =~ ^[0-9]+$ ]]; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') dirty-frag-kill: ungültige PID '$PID'" >> "$LOG"
        exit 1
    fi
    
    # Parent-PID des Exploit-Prozesses bestimmen
    PPID=$(ps -o ppid= -p "$PID" 2>/dev/null | tr -d ' ')
    EXE=$(readlink -f /proc/"$PID"/exe 2>/dev/null || echo "unbekannt")
    
    echo "$(date '+%Y-%m-%d %H:%M:%S') dirty-frag-kill: KILL PID=$PID PPID=$PPID EXE=$EXE" >> "$LOG"
    
    # Exploit-Prozess killen
    kill -9 "$PID"  2>/dev/null && \
        echo "$(date '+%Y-%m-%d %H:%M:%S') dirty-frag-kill: PID=$PID erfolgreich beendet"  >> "$LOG"
    
    # Parent killen (ausser init/systemd), um Respawn zu verhindern
    if [ -n "$PPID" ] && [ "$PPID" -gt 2 ]; then
        kill -9 "$PPID" 2>/dev/null && \
            echo "$(date '+%Y-%m-%d %H:%M:%S') dirty-frag-kill: PPID=$PPID erfolgreich beendet" >> "$LOG"
    fi
    
    # Kernel-Module entladen, sofern noch geladen
    for mod in rxrpc esp4 esp6; do
        if lsmod | grep -q "^${mod} "; then
            rmmod "$mod" 2>/dev/null && \
                echo "$(date '+%Y-%m-%d %H:%M:%S') dirty-frag-kill: Modul $mod entladen" >> "$LOG"
        fi
    done
    
    exit 0
    

    Berechtigungen setzen:

    chmod 750   /var/ossec/active-response/bin/dirty-frag-kill.sh
    chown root:wazuh /var/ossec/active-response/bin/dirty-frag-kill.sh
    

    In /var/ossec/etc/ossec.conf auf dem Wazuh-Manager einbinden:

    <!-- Dirty Frag / Copy Fail: Exploit-Prozess killen -->
    <command>
      <name>dirty-frag-kill</name>
      <executable>dirty-frag-kill.sh</executable>
      <timeout_allowed>no</timeout_allowed>
    </command>
    
    <active-response>
      <disabled>no</disabled>
      <command>dirty-frag-kill</command>
      <location>local</location>
      <!-- Dirty Frag Chains + Copy Fail Highest-Level Rules -->
      <rules_id>200007,200008,199607</rules_id>
    </active-response>
    

    <location>local</location> bedeutet: das Skript läuft auf dem Agenten, der den Alert ausgelöst hat - also genau dort, wo der Exploit abläuft. 199607 ist die höchste Chain-Regel des Copy Fail Regelsets - die tatsächliche ID sollte aus dem jeweiligen Repository verifiziert werden.

    Wichtig: Active Response ist kein Allheilmittel. Wenn der Exploit bereits execve(/usr/bin/su) aufgerufen hat (Regel 200006), ist die Page-Cache-Korruption bereits geschehen. Die Process-Kill-Antwort ist am wirkungsvollsten bei den frühen Chain-Signalen 200007/200008 - also bevor Root erlangt wurde. Das demonstriert auch, warum eine schnelle, automatisierte Antwort gegenüber manueller Triage einen echten Unterschied macht.

    Active Response - Host-Netzwerk-Isolierung

    Bei einem bestätigten Compromise oder kritischen Alarm empfiehlt sich eine vollständige Netzwerk-Isolierung des Hosts. Das zweite Skript sperrt alle Verbindungen via iptables - mit einer wichtigen Ausnahme: Die Verbindung zum Wazuh-Manager bleibt offen, damit der Agent weiter Telemetrie sendet und ferngesteuert werden kann. Das habe ich bis jetzt noch nicht getestet, aber es scheint mir sinnvoll dies zu implementieren.

    # /var/ossec/active-response/bin/dirty-frag-isolate.sh
    # M. Meister - Host-Netzwerk-Isolierung bei LPE-Alarm (Wazuh Manager bleibt erreichbar)
    
    #!/bin/bash
    
    LOG="/var/ossec/logs/active-responses.log"
    
    # Wazuh-Manager-IP aus agent config lesen
    MANAGER_IP=$(grep -oP '(?<=<address>)[^<]+' /var/ossec/etc/ossec.conf 2>/dev/null | head -1)
    
    if [ -z "$MANAGER_IP" ]; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') dirty-frag-isolate: FEHLER - Manager-IP nicht ermittelbar" >> "$LOG"
        exit 1
    fi
    
    echo "$(date '+%Y-%m-%d %H:%M:%S') dirty-frag-isolate: Isolierung gestartet, Manager=$MANAGER_IP" >> "$LOG"
    
    # Bestehende Regeln sichern (für manuelle Wiederherstellung)
    iptables-save > /var/ossec/logs/iptables-pre-isolate-"$(date +%s)".bak 2>/dev/null
    
    # INPUT/OUTPUT/FORWARD leeren
    iptables -F INPUT
    iptables -F OUTPUT
    iptables -F FORWARD
    
    # Loopback immer erlauben
    iptables -A INPUT  -i lo -j ACCEPT
    iptables -A OUTPUT -o lo -j ACCEPT
    
    # Wazuh Manager: bidirektional erlauben (Port 1514 UDP/TCP Agent-Kommunikation)
    iptables -A INPUT  -s "$MANAGER_IP" -j ACCEPT
    iptables -A OUTPUT -d "$MANAGER_IP" -j ACCEPT
    
    # Established/Related Verbindungen zum Manager durchlassen
    iptables -A INPUT  -m state --state ESTABLISHED,RELATED -s "$MANAGER_IP" -j ACCEPT
    iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -d "$MANAGER_IP" -j ACCEPT
    
    # Alles andere: DROP
    iptables -P INPUT   DROP
    iptables -P OUTPUT  DROP
    iptables -P FORWARD DROP
    
    echo "$(date '+%Y-%m-%d %H:%M:%S') dirty-frag-isolate: Host isoliert. Nur $MANAGER_IP zugelassen." >> "$LOG"
    
    # Optional: Kernel-Module entladen
    for mod in rxrpc esp4 esp6 algif_aead; do
        rmmod "$mod" 2>/dev/null && \
            echo "$(date '+%Y-%m-%d %H:%M:%S') dirty-frag-isolate: Modul $mod entladen" >> "$LOG"
    done
    
    exit 0
    
    chmod 750        /var/ossec/active-response/bin/dirty-frag-isolate.sh
    chown root:wazuh /var/ossec/active-response/bin/dirty-frag-isolate.sh
    

    In /var/ossec/etc/ossec.conf auf dem Manager:

    <!-- Dirty Frag / Copy Fail: Netzwerk-Isolierung -->
    <command>
      <name>dirty-frag-isolate</name>
      <executable>dirty-frag-isolate.sh</executable>
      <timeout_allowed>no</timeout_allowed>
    </command>
    
    <active-response>
      <disabled>no</disabled>
      <command>dirty-frag-isolate</command>
      <location>local</location>
      <rules_id>200007,200008,199607</rules_id>
    </active-response>
    

    Manager neu starten, damit die Active-Response-Konfiguration aktiv wird:

    systemctl restart wazuh-manager
    

    Die Isolierung lässt sich bei Bedarf manuell rückgängig machen:

    # Auf dem betroffenen Agenten - Sicherung wiederherstellen
    iptables-restore < /var/ossec/logs/iptables-pre-isolate-*.bak
    
    # Oder alle Regeln flushen und Policies zurücksetzen
    iptables -F && iptables -P INPUT ACCEPT && iptables -P OUTPUT ACCEPT && iptables -P FORWARD ACCEPT
    
    Überlegung zum Produktivbetrieb: Wer auf dem überwachten Host nftables statt iptables einsetzt oder SSH-Zugang für die manuelle Forensik erhalten muss, passt die ACCEPT-Regeln entsprechend an. Auf Systemen mit aktiven IPsec-Tunnels (strongSwan/Libreswan) sollte vor dem Deployen der Isolierungsregel geprüft werden, ob esp4/esp6 wirklich entladen werden dürfen - das zieht bestehende VPN-Verbindungen unweigerlich nach unten.

    Das Thema Active Response mit KI-gestützter Incident-Analyse lässt sich weiter vertiefen - wie das aussehen kann, beschreibt der Artikel Wazuh on Steroids: AI-Powered Incident Analysis On-Demand.

    Wazuh on Steroids: AI-Powered Incident Analysis On-Demand
    Upgrade Wazuh with an AI-powered active response for on-demand, deep-dive incident analysis.

    Fazit

    Dirty Frag und Copy Fail machen deutlich, dass traditionelle dateibasierte Integritätsprüfung gegen moderne Page-Cache-Exploits strukturell blind ist - nur verhaltensbasierte Syscall-Überwachung durch auditd kombiniert mit Wazuh-Chain-Regeln liefert zuverlässige Echtzeiterkennung. Mit den Active-Response-Skripten lässt sich der Detect-to-Respond-Zeitraum auf Sekunden reduzieren, bevor ein Angreifer seinen Root-Zugang konsolidieren kann.