diff --git a/Regeln.md b/Regeln.md new file mode 100644 index 0000000..bd84fa6 --- /dev/null +++ b/Regeln.md @@ -0,0 +1,1964 @@ +# SIEM-lite Regel-Dokumentation + +Stand: 2026-04-27 +Projekt: `siem-backend` / `SIEM-lite Security Operations` + +Diese Dokumentation beschreibt die im Backend implementierten Detection-Regeln, ihre Datenbasis, Schwellenwerte, Statuslogik, Suppression-Mechanismen und empfohlene Bewertung im SOC. + +--- + +## 1. Überblick + +Das Backend nimmt Windows Eventlog-Daten von Agents über `/ingest` entgegen, normalisiert wichtige Felder aus dem Event-XML und speichert sie in MySQL. In regelmäßigen Intervallen läuft ein Detection-Loop, der verschiedene statische, dynamische, Baseline- und UEBA-Regeln auswertet. + +Der zentrale Detection-Loop befindet sich in: + +```go +func (s *server) runDetectionsOnce() +``` + +Aktuell vorgesehene Regeln: + +```go +agent_offline +failed_logon_spike +reboot_spike +new_event_id +password_spray +success_after_failures +new_source_ip_for_user +dynamic_rules +baseline_anomaly +baseline_update +ueba_admin_new_host +ueba_offhours_login +ueba_first_privileged_use +ueba_new_user_context +ueba_update +host_risk_score +``` + +--- + +## 2. Datenbasis + +### 2.1 Tabelle `event_logs` + +Die meisten Regeln basieren auf normalisierten Windows-Events in `event_logs`. + +Wichtige Felder: + +| Feld | Bedeutung | +|---|---| +| `hostname` | Hostname des meldenden Systems oder aus dem Event-XML | +| `channel_name` | Windows Eventlog-Channel, z. B. `Security`, `System`, `Application` | +| `event_id` | Windows Event ID | +| `target_user` | Zielbenutzer, meist aus `TargetUserName` | +| `subject_user` | ausführender Benutzer, meist aus `SubjectUserName` | +| `src_ip` | Quell-IP aus `IpAddress` | +| `workstation` | Workstation aus `WorkstationName` | +| `logon_type` | Windows LogonType | +| `process_name` | Prozessname, sofern vorhanden | +| `ts` | Event-Zeitpunkt | +| `received_at` | Empfangszeitpunkt | +| `msg` | Rohes Event-XML | +| `msg_sha256` | Hash des Event-XML | + +### 2.2 Tabelle `detections` + +Alle Regeln schreiben Findings in die Tabelle `detections`. + +Wichtige Felder: + +| Feld | Bedeutung | +|---|---| +| `rule_name` | Name der Regel | +| `severity` | `info`, `low`, `medium`, `high`, `critical` | +| `hostname` | betroffener Host | +| `channel_name` | Eventlog-Channel | +| `event_id` | relevante Event ID | +| `score` | numerischer Risiko-/Anomalie-Score | +| `window_start` | Beginn des betrachteten Zeitfensters | +| `window_end` | Ende des betrachteten Zeitfensters | +| `summary` | menschenlesbare Zusammenfassung | +| `details_json` | technische Details als JSON | +| `status` | SOC-Bewertung | +| `analyst_note` | Analystenkommentar | +| `reviewed_by` | Bearbeiter | +| `reviewed_at` | Bewertungszeitpunkt | +| `is_false_positive` | Flag für False Positive | +| `is_legitimate` | Flag für legitimes/plausibles Verhalten | + +--- + +## 3. Globale Konfiguration + +Die wichtigsten Regelparameter werden per Environment-Variablen gesetzt. + +| Variable | Default | Bedeutung | +|---|---:|---| +| `DETECTION_INTERVAL` | `1m` | Intervall des Detection-Loops | +| `OFFLINE_AFTER` | `10m` | Agent gilt nach dieser Zeit als offline | +| `OFFLINE_ALERT_MAX` | `120m` | Maximales Offline-Alter für Offline-Alerts | +| `FAILED_LOGON_WINDOW` | `5m` | Zeitfenster für fehlgeschlagene Logons | +| `FAILED_LOGON_THRESHOLD` | `25` | Mindestanzahl fehlgeschlagener Logons pro Host | +| `REBOOT_WINDOW` | `15m` | Zeitfenster für Reboot-Spikes | +| `REBOOT_THRESHOLD` | `3` | Mindestanzahl Reboot-/Shutdown-Events | +| `PASSWORD_SPRAY_WINDOW` | `5m` | Zeitfenster für Password-Spray | +| `PASSWORD_SPRAY_MIN_USERS` | `5` | Mindestanzahl unterschiedlicher Zielbenutzer | +| `PASSWORD_SPRAY_MIN_ATTEMPTS` | `15` | Mindestanzahl Fehlversuche | +| `SUCCESS_AFTER_FAILURE_WINDOW` | `10m` | Zeitfenster für Erfolg nach Fehlversuchen | +| `NEW_SOURCE_IP_LOOKBACK` | `720h` / 30 Tage | Rückblick für bekannte Quell-IPs | +| `NEW_SOURCE_IP_WINDOW` | `10m` | aktuelles Fenster für neue Quell-IP | +| `BASELINE_ENABLED` | `true` | aktiviert Baseline-Regeln | +| `BASELINE_WINDOW` | `5m` | Baseline-Bucket-Zeitfenster | +| `BASELINE_MIN_SAMPLES` | `24` | Mindestanzahl Baseline-Samples | +| `BASELINE_MIN_COUNT` | `10` | Mindestanzahl Events für Baseline-Alert | +| `BASELINE_MEDIUM_Z` | `2.5` | Z-Score ab Medium | +| `BASELINE_HIGH_Z` | `4.0` | Z-Score ab High | +| `BASELINE_SUPPRESS_FOR` | `1h` | automatische Unterdrückung gleicher Baseline-Findings | +| `UEBA_ENABLED` | `true` | aktiviert UEBA-Regeln | +| `UEBA_LOOKBACK` | `720h` / 30 Tage | UEBA-Rückblick | +| `UEBA_NEW_CONTEXT_WINDOW` | `10m` | Fenster für neue Kontexte | +| `RISK_SCORE_WINDOW` | `24h` | Zeitraum für Host Risk Score | +| `TZ` | `Europe/Berlin` | Anzeige-/Bewertungszeitzone | + +--- + +## 4. Severity-Logik + +### 4.1 `severityFromScore` + +Mehrere Regeln nutzen diese Score-zu-Severity-Logik: + +```go +func severityFromScore(score, low, medium, high, critical float64) string +``` + +Beispielaufruf: + +```go +severityFromScore(score, 1.0, 2.0, 4.0, 8.0) +``` + +Bedeutung: + +| Score | Severity | +|---:|---| +| `>= 8.0` | `critical` | +| `>= 4.0` | `high` | +| `>= 2.0` | `medium` | +| `>= 1.0` | `low` | +| `< 1.0` | `info` | + +### 4.2 Host Risk Severity + +Der Host Risk Score nutzt eine separate Einteilung: + +| Risk Score | Severity | +|---:|---| +| `>= 120` | `critical` | +| `>= 60` | `high` | +| `>= 20` | `medium` | +| `>= 5` | `low` | +| `< 5` | `info` | + +--- + +# 5. Regel: `agent_offline` + +## Zweck + +Erkennt Agents, die länger als `OFFLINE_AFTER` nicht mehr gesehen wurden, aber noch nicht älter als `OFFLINE_ALERT_MAX` offline sind. + +## Datenbasis + +Tabelle: `agents` + +Relevante Felder: + +- `hostname` +- `last_seen` +- `is_enabled` + +## Logik + +Ein Agent wird gemeldet, wenn: + +```sql +is_enabled = 1 +AND last_seen < now - OFFLINE_AFTER +AND last_seen >= now - OFFLINE_ALERT_MAX +``` + +## Default-Werte + +| Parameter | Default | +|---|---:| +| `OFFLINE_AFTER` | `10m` | +| `OFFLINE_ALERT_MAX` | `120m` | + +## Detection + +| Feld | Wert | +|---|---| +| Rule | `agent_offline` | +| Severity | `low` | +| Score | abhängig von Offline-Dauer | +| Channel | leer | +| EventID | `0` | + +## Beispiel-Summary + +```text +Agent CLIENT01 ist seit 17 Minuten offline +``` + +## SOC-Bewertung + +Empfohlene Bewertung: + +- `legitimate`, wenn Gerät heruntergefahren, neu installiert oder absichtlich deaktiviert wurde. +- `investigating`, wenn Server oder kritischer Client unerwartet offline ist. +- `suppressed`, wenn bestimmte Systeme dauerhaft nicht überwacht werden sollen. + +--- + +# 6. Regel: `failed_logon_spike` + +## Zweck + +Erkennt Hosts mit ungewöhnlich vielen fehlgeschlagenen Logons innerhalb kurzer Zeit. + +## Datenbasis + +Tabelle: `event_logs` + +Windows Event: + +| Channel | EventID | +|---|---:| +| `Security` | `4625` | + +## Logik + +Gruppierung nach Host: + +```sql +channel_name = 'Security' +AND event_id = 4625 +AND ts >= window_start +AND ts < window_end +GROUP BY hostname +HAVING COUNT(*) >= FAILED_LOGON_THRESHOLD +``` + +## Default-Werte + +| Parameter | Default | +|---|---:| +| `FAILED_LOGON_WINDOW` | `5m` | +| `FAILED_LOGON_THRESHOLD` | `25` | + +## Score + +```text +score = count / FAILED_LOGON_THRESHOLD +``` + +Severity wird über `severityFromScore(score, 1.0, 2.0, 4.0, 8.0)` berechnet. + +## Detection + +| Feld | Wert | +|---|---| +| Rule | `failed_logon_spike` | +| EventID | `4625` | +| Channel | `Security` | +| Severity | score-basiert | + +## Beispiel-Summary + +```text +Host DC01 hatte 48 fehlgeschlagene Logons in 5 Minuten +``` + +## Typische Ursachen + +- Brute-Force-Versuch +- falsch gespeichertes Passwort in Diensten +- altes Passwort in RDP-/VPN-/Outlook-Sessions +- Scanner oder Monitoring mit falschen Credentials +- Lockout-Situation nach Passwortwechsel + +## SOC-Bewertung + +- `investigating`, wenn unbekannte Quelle, viele Accounts oder externe IP beteiligt. +- `legitimate`, wenn bekannter Dienst nach Passwortwechsel betroffen ist. +- `false_positive`, wenn Event-Parsing oder Testdaten Ursache sind. + +--- + +# 7. Regel: `reboot_spike` + +## Zweck + +Erkennt Hosts mit mehreren Reboot-/Shutdown-Events in kurzer Zeit. + +## Datenbasis + +Tabelle: `event_logs` + +Windows Events: + +| Channel | EventID | Bedeutung | +|---|---:|---| +| `System` | `1074` | geplanter Neustart/Shutdown | +| `System` | `6005` | Eventlog-Service gestartet | +| `System` | `6006` | Eventlog-Service beendet | + +## Logik + +```sql +channel_name = 'System' +AND event_id IN (1074, 6005, 6006) +AND ts >= window_start +AND ts < window_end +GROUP BY hostname +HAVING COUNT(*) >= REBOOT_THRESHOLD +``` + +## Default-Werte + +| Parameter | Default | +|---|---:| +| `REBOOT_WINDOW` | `15m` | +| `REBOOT_THRESHOLD` | `3` | + +## Score + +```text +score = count / REBOOT_THRESHOLD +``` + +## Detection + +| Feld | Wert | +|---|---| +| Rule | `reboot_spike` | +| Channel | `System` | +| Severity | score-basiert | + +## Beispiel-Summary + +```text +Host CLIENT01 hatte 4 Reboot-/Shutdown-Events in 15 Minuten +``` + +## Typische Ursachen + +- Patchinstallation +- Treiberproblem +- instabiler Client +- Stromproblem +- absichtlicher Neustart durch Admin +- Malware/Manipulation eher selten, aber möglich + +--- + +# 8. Regel: `new_event_id` + +## Zweck + +Erkennt, wenn ein Host erstmals eine bestimmte EventID in einem bestimmten Channel sendet. + +## Datenbasis + +Tabelle: `event_logs` + +## Logik + +Die Regel betrachtet nur das aktuelle Detection-Intervall und prüft, ob es davor für denselben Host, Channel und EventID bereits Events gab. + +Vereinfacht: + +```sql +WHERE e.ts >= window_start +AND e.ts < window_end +AND NOT EXISTS ( + SELECT 1 + FROM event_logs old + WHERE old.hostname = e.hostname + AND old.channel_name = e.channel_name + AND old.event_id = e.event_id + AND old.ts < window_start +) +GROUP BY e.hostname, e.channel_name, e.event_id +``` + +## Default-Werte + +| Parameter | Default | +|---|---:| +| `DETECTION_INTERVAL` | `1m` | + +## Score + +```text +score = 1.0 + log10(count + 1) +``` + +## Severity + +| Bedingung | Severity | +|---|---| +| `count >= 10` | `high` | +| sonst | `medium` | + +## Detection + +| Feld | Wert | +|---|---| +| Rule | `new_event_id` | +| Channel | aus Event | +| EventID | aus Event | + +## Beispiel-Summary + +```text +Host CLIENT01 sendet erstmals Event-ID 7045 im Channel System +``` + +## Typische Ursachen + +- neue Software +- neue Windows-Funktion +- neues Audit-Policy-Setting +- Treiberinstallation +- Service-Installation +- sicherheitsrelevante Aktivität, wenn EventID auffällig ist + +## SOC-Bewertung + +Besonders prüfen bei: + +- `System 7045` Service Installation +- `Security 1102` Auditlog gelöscht +- `Security 4720` User erstellt +- `Security 4697` Service installiert +- `Security 4698` Scheduled Task erstellt + +--- + +# 9. Regel: `password_spray` + +## Zweck + +Erkennt mögliche Password-Spray-Angriffe anhand vieler fehlgeschlagener Logons gegen mehrere verschiedene Benutzer von derselben Quell-IP. + +## Datenbasis + +Tabelle: `event_logs` + +Windows Event: + +| Channel | EventID | +|---|---:| +| `Security` | `4625` | + +## Logik + +Gruppierung nach Host und Quell-IP: + +```sql +channel_name = 'Security' +AND event_id = 4625 +AND src_ip <> '' +AND src_ip <> '-' +AND src_ip <> '::1' +AND src_ip <> '127.0.0.1' +AND target_user <> '' +AND target_user <> '-' +GROUP BY hostname, src_ip +HAVING COUNT(*) >= PASSWORD_SPRAY_MIN_ATTEMPTS + AND COUNT(DISTINCT target_user) >= PASSWORD_SPRAY_MIN_USERS +``` + +## Default-Werte + +| Parameter | Default | +|---|---:| +| `PASSWORD_SPRAY_WINDOW` | `5m` | +| `PASSWORD_SPRAY_MIN_USERS` | `5` | +| `PASSWORD_SPRAY_MIN_ATTEMPTS` | `15` | + +## Score + +```text +score = max( + attempts / PASSWORD_SPRAY_MIN_ATTEMPTS, + users / PASSWORD_SPRAY_MIN_USERS +) +``` + +Severity wird über `severityFromScore(score, 1.0, 2.0, 4.0, 8.0)` berechnet. + +## Detection + +| Feld | Wert | +|---|---| +| Rule | `password_spray` | +| Channel | `Security` | +| EventID | `4625` | + +## Beispiel-Summary + +```text +Möglicher Password-Spray auf DC01 von 10.10.10.50: 30 Fehlversuche gegen 12 Benutzer +``` + +## Typische Ursachen + +- echter Password-Spray +- Scanner mit falschem Passwort +- altes Passwort in zentralem Dienst +- falsch konfigurierte Applikation +- VPN-/RADIUS-/LDAP-Fehlversuche + +## Empfohlene Prüfung + +- Quell-IP identifizieren. +- Prüfen, ob Quell-IP intern, VPN, Server oder extern ist. +- Betroffene Benutzer auf Lockout oder spätere erfolgreiche Logons prüfen. +- In Kombination mit `success_after_failures` hoch priorisieren. + +--- + +# 10. Regel: `success_after_failures` + +## Zweck + +Erkennt erfolgreiche Logons, denen kurz zuvor fehlgeschlagene Logons für denselben Benutzer vorausgingen. + +## Datenbasis + +Tabelle: `event_logs` + +Windows Events: + +| EventID | Bedeutung | +|---:|---| +| `4625` | fehlgeschlagener Logon | +| `4624` | erfolgreicher Logon | + +## Logik + +Ein erfolgreicher Logon wird verdächtig, wenn vorher im konfigurierten Fenster ein passender fehlgeschlagener Logon existiert. + +Vereinfacht: + +```sql +s.event_id = 4624 +AND EXISTS ( + SELECT 1 + FROM event_logs f + WHERE f.hostname = s.hostname + AND f.event_id = 4625 + AND f.target_user = s.target_user + AND f.ts >= DATE_SUB(s.ts, INTERVAL ? SECOND) + AND f.ts < s.ts +) +``` + +Die Quell-IP wird berücksichtigt, wenn sie vorhanden ist. + +## Default-Wert + +| Parameter | Default | +|---|---:| +| `SUCCESS_AFTER_FAILURE_WINDOW` | `10m` | + +## Score + +```text +score = 2.0 + log10(success_count + 1) +``` + +## Severity + +Aktuell fest: + +```text +high +``` + +## Detection + +| Feld | Wert | +|---|---| +| Rule | `success_after_failures` | +| Channel | `Security` | +| EventID | `4624` | +| Severity | `high` | + +## Beispiel-Summary + +```text +Erfolgreicher Logon nach Fehlversuchen auf CLIENT01 für Benutzer max.mustermann +``` + +## Typische Ursachen + +- Benutzer hat sich vertippt und danach korrekt angemeldet +- Angreifer hat Passwort erraten +- Passwort-Spray mit anschließendem Treffer +- Passwortänderung und gespeicherte Sessions + +## Empfohlene Bewertung + +Diese Regel sollte priorisiert werden, wenn zusätzlich eines davon zutrifft: + +- neue Quell-IP +- ungewöhnlicher Host +- privilegierter Benutzer +- außerhalb Arbeitszeit +- mehrere Zielbenutzer betroffen +- externer oder unbekannter Ursprung + +--- + +# 11. Regel: `new_source_ip_for_user` + +## Zweck + +Erkennt erfolgreiche Logons eines Benutzers von einer bisher unbekannten Quell-IP. + +## Datenbasis + +Tabelle: `event_logs` + +Windows Event: + +| Channel | EventID | +|---|---:| +| `Security` | `4624` | + +## Logik + +Die Regel betrachtet erfolgreiche Logons im aktuellen Fenster und prüft, ob dieselbe Quell-IP für denselben Benutzer auf demselben Host im Lookback-Zeitraum bereits bekannt war. + +```sql +event_id = 4624 +AND src_ip NOT IN ('', '-', '::1', '127.0.0.1') +AND NOT EXISTS ( + SELECT 1 + FROM event_logs old + WHERE old.hostname = e.hostname + AND old.event_id = 4624 + AND old.target_user = e.target_user + AND old.src_ip = e.src_ip + AND old.ts >= lookback_start + AND old.ts < window_start +) +``` + +## Default-Werte + +| Parameter | Default | +|---|---:| +| `NEW_SOURCE_IP_WINDOW` | `10m` | +| `NEW_SOURCE_IP_LOOKBACK` | `30d` | + +## Score + +```text +score = 1.5 + log10(count + 1) +``` + +## Severity + +| Bedingung | Severity | +|---|---| +| `count >= 5` | `high` | +| sonst | `medium` | + +## Detection + +| Feld | Wert | +|---|---| +| Rule | `new_source_ip_for_user` | +| Channel | `Security` | +| EventID | `4624` | + +## Beispiel-Summary + +```text +Benutzer max.mustermann meldet sich auf CLIENT01 von neuer Quell-IP 10.10.50.20 an +``` + +## Typische Ursachen + +- neuer Client +- VPN-Wechsel +- DHCP-Wechsel +- RDP von ungewohntem System +- kompromittierter Account + +--- + +# 12. Regel: `dynamic_rules` + +## Zweck + +Ermöglicht frei konfigurierbare Regeln über die Weboberfläche und Tabelle `detection_rules`. + +## Datenbasis + +Tabelle: + +```text +detection_rules +``` + +Ausgewertet gegen: + +```text +event_logs +``` + +## Regeltypen + +Es gibt zwei Betriebsarten: + +1. Einzelereignis-Regel +2. Threshold-Regel + +### 12.1 Einzelereignis-Regel + +Wird verwendet, wenn: + +```text +threshold_count <= 1 +ODER +threshold_window_seconds <= 0 +``` + +Sie prüft Events im aktuellen `DETECTION_INTERVAL`. + +### 12.2 Threshold-Regel + +Wird verwendet, wenn: + +```text +threshold_count > 1 +UND +threshold_window_seconds > 0 +``` + +Sie zählt passende Events im angegebenen Zeitfenster pro Host. + +## Konfigurierbare Felder + +| Feld | Bedeutung | +|---|---| +| `name` | Regelname | +| `description` | Beschreibung | +| `severity` | Severity | +| `channel` | ein oder mehrere Channels, kommasepariert | +| `event_ids` | ein oder mehrere EventIDs, kommasepariert | +| `match_field` | optionales Feld für Filter | +| `match_operator` | `eq`, `contains`, `in` | +| `match_value` | Vergleichswert | +| `threshold_count` | Mindestanzahl Events | +| `threshold_window_seconds` | Zeitfenster | +| `suppress_for_seconds` | Suppression-Zeit | +| `enabled` | aktiv/inaktiv | + +## Unterstützte Match-Felder + +| `match_field` | DB-Spalte | +|---|---| +| `hostname` | `hostname` | +| `channel` | `channel_name` | +| `event_id` | `event_id` | +| `target_user` | `target_user` | +| `subject_user` | `subject_user` | +| `src_ip` | `src_ip` | +| `workstation` | `workstation` | +| `process_name` | `process_name` | +| `msg` | `msg` | + +## Unterstützte Operatoren + +| Operator | Bedeutung | +|---|---| +| `eq` | exakter Vergleich | +| `contains` | Teilstring-Suche | +| `in` | Wert ist in kommaseparierter Liste enthalten | + +## Detection-Name + +Dynamische Regeln werden mit Prefix gespeichert: + +```text +dynamic_ +``` + +Beispiel: + +```text +dynamic_security_log_cleared +``` + +## Beispiel-Regeln + +### Auditlog gelöscht + +| Feld | Wert | +|---|---| +| Name | `security_log_cleared` | +| Severity | `critical` | +| Channel | `Security` | +| Event IDs | `1102` | +| Threshold Count | `1` | +| Suppress Seconds | `3600` | + +### Neuer lokaler Benutzer + +| Feld | Wert | +|---|---| +| Name | `local_user_created` | +| Severity | `high` | +| Channel | `Security` | +| Event IDs | `4720` | +| Threshold Count | `1` | + +### Service installiert + +| Feld | Wert | +|---|---| +| Name | `service_installed` | +| Severity | `high` | +| Channel | `System,Security` | +| Event IDs | `7045,4697` | + +--- + +# 13. Regel: `baseline_event_rate_anomaly` + +## Zweck + +Erkennt statistische Abweichungen bei Event-Häufigkeiten je Host, Channel, EventID, Wochentag und Stunde. + +## Komponenten + +Die Baseline besteht aus zwei Teilen: + +1. `baseline_update` +2. `baseline_anomaly` + +## 13.1 `baseline_update` + +Aktualisiert die Statistik in `baseline_event_stats`. + +Gruppierung: + +```text +hostname +channel_name +event_id +hour_of_day +day_of_week +``` + +Es wird ein Online-Mittelwert mit M2/Stddev gepflegt. + +## 13.2 `baseline_anomaly` + +Vergleicht aktuelle Counts gegen die gespeicherte Baseline. + +## Datenbasis + +Tabellen: + +- `event_logs` +- `baseline_event_stats` +- `baseline_exclusions` +- `detections` + +## Default-Werte + +| Parameter | Default | +|---|---:| +| `BASELINE_WINDOW` | `5m` | +| `BASELINE_MIN_SAMPLES` | `24` | +| `BASELINE_MIN_COUNT` | `10` | +| `BASELINE_MEDIUM_Z` | `2.5` | +| `BASELINE_HIGH_Z` | `4.0` | +| `BASELINE_SUPPRESS_FOR` | `1h` | + +## Berechnung + +```text +z = (current_count - avg_count) / stddev_count +``` + +## Voraussetzungen für Alert + +Ein Alert entsteht nur, wenn: + +```text +sample_count >= BASELINE_MIN_SAMPLES +count >= BASELINE_MIN_COUNT +stddev_count > 0 +z >= BASELINE_MEDIUM_Z +``` + +## Severity + +| Bedingung | Severity | +|---|---| +| `z >= BASELINE_HIGH_Z` | `high` | +| `z >= BASELINE_MEDIUM_Z` | `medium` | + +## Detection + +| Feld | Wert | +|---|---| +| Rule | `baseline_event_rate_anomaly` | +| Score | Z-Score | +| Severity | z-score-basiert | + +## Beispiel-Summary + +```text +Baseline-Anomalie auf DC01: Security EventID 4625 kam 80-mal in 5 Minuten, normal 12.40 ± 5.10, z=13.25 +``` + +## Ausschlüsse + +Baseline-Lernen wird übersprungen, wenn: + +- passender Eintrag in `baseline_exclusions` aktiv ist +- ein `confirmed_incident` im aktuellen Fenster existiert + +## UI-Bewertung + +In der Detection-UI kann über `Baseline` gesteuert werden: + +| Aktion | Effekt | +|---|---| +| `nicht lernen: 24h` | temporärer Baseline-Ausschluss | +| `nicht lernen: 7 Tage` | temporärer Baseline-Ausschluss | +| `nicht lernen: 30 Tage` | temporärer Baseline-Ausschluss | +| `nicht lernen: dauerhaft` | permanenter Baseline-Ausschluss | + +Bei `confirmed_incident` wird automatisch ein 7-Tage-Ausschluss erzeugt, sofern keine andere Baseline-Aktion gewählt wurde. + +--- + +# 14. Regel: `ueba_admin_new_host` + +## Zweck + +Erkennt, wenn sich ein privilegierter Benutzer erstmals auf einem Host anmeldet. + +## Datenbasis + +Tabellen: + +- `event_logs` +- `ueba_user_baseline` +- `privileged_users` + +Windows Event: + +| Channel | EventID | +|---|---:| +| `Security` | `4624` | + +## Privilegierte Benutzer + +Ein Benutzer gilt als privilegiert, wenn: + +1. er in `privileged_users` aktiviert ist, oder +2. sein Name einem Admin-Muster entspricht: + +```text +adm-* +*-adm +*.adm +``` + +Maschinenkonten werden ignoriert. + +## Logik + +Es werden erfolgreiche Logons im aktuellen UEBA-Fenster betrachtet. Für Benutzer/Host-Kombinationen wird geprüft, ob es im Lookback bereits einen passenden Baseline-Kontext gab. + +## Default-Werte + +| Parameter | Default | +|---|---:| +| `UEBA_NEW_CONTEXT_WINDOW` | `10m` | +| `UEBA_LOOKBACK` | `30d` | + +## Score und Severity + +| Bedingung | Score | Severity | +|---|---:|---| +| `count < 3` | `6.0` | `high` | +| `count >= 3` | `9.0` | `critical` | + +## Detection + +| Feld | Wert | +|---|---| +| Rule | `ueba_admin_new_host` | +| Channel | `Security` | +| EventID | `4624` | + +## Beispiel-Summary + +```text +UEBA: Privilegierter Benutzer adm.max meldet sich erstmals auf Host SERVER01 an +``` + +## Prometheus-Metriken + +Bei neuer Detection wird erhöht: + +```text +siem_privileged_new_host_total{user,host} +``` + +## SOC-Bewertung + +Diese Regel ist besonders relevant, wenn: + +- der Host ein Client statt Admin-Jump-Host ist +- der Login außerhalb Arbeitszeit erfolgt +- vorher Fehlversuche auftraten +- die Quell-IP neu ist +- der Benutzer Domain Admin oder Server Admin ist + +--- + +# 15. Regel: `ueba_new_user_context` + +## Zweck + +Erkennt neue Login-Kontexte für normale Benutzer. + +Ein Kontext besteht aus: + +```text +username + hostname + src_ip + workstation +``` + +## Datenbasis + +Tabellen: + +- `event_logs` +- `ueba_user_baseline` + +Windows Event: + +| Channel | EventID | +|---|---:| +| `Security` | `4624` | + +## Logik + +Ein Alert entsteht, wenn für einen erfolgreichen Logon im aktuellen Fenster kein bekannter Baseline-Kontext im Lookback existiert. + +## Default-Werte + +| Parameter | Default | +|---|---:| +| `UEBA_NEW_CONTEXT_WINDOW` | `10m` | +| `UEBA_LOOKBACK` | `30d` | + +## Score und Severity + +| Bedingung | Score | Severity | +|---|---:|---| +| `count < 5` | `2.0` | `medium` | +| `count >= 5` | `4.0` | `high` | + +## Detection + +| Feld | Wert | +|---|---| +| Rule | `ueba_new_user_context` | +| Channel | `Security` | +| EventID | `4624` | + +## Beispiel-Summary + +```text +UEBA: Benutzer max.mustermann meldet sich in neuem Kontext an: Host=CLIENT01 IP=10.10.20.30 Workstation=CLIENT99 +``` + +## Typische Ursachen + +- neuer Arbeitsplatz +- VPN +- DHCP-Wechsel +- Remotezugriff +- Helpdesk-Anmeldung +- kompromittierter Account + +--- + +# 16. Regel: `ueba_update` + +## Zweck + +Aktualisiert die UEBA-Baseline für Benutzerkontexte. + +## Datenbasis + +Tabelle: + +```text +ueba_user_baseline +``` + +Quelle: + +```text +event_logs +``` + +## Logik + +Erfolgreiche Logons im aktuellen UEBA-Fenster werden in die Baseline übernommen. + +Kontext: + +```text +username +hostname +src_ip +workstation +``` + +Bei neuem Kontext: + +```sql +INSERT INTO ueba_user_baseline (...) +``` + +Bei bekanntem Kontext: + +```sql +last_seen = UTC_TIMESTAMP(6) +seen_count = seen_count + VALUES(seen_count) +``` + +## Wichtig + +Die Reihenfolge im Detection-Loop ist relevant. + +Empfohlen: + +```text +ueba_admin_new_host +ueba_offhours_login +ueba_first_privileged_use +ueba_new_user_context +ueba_update +``` + +So werden neue Kontexte zuerst erkannt und danach gelernt. + +--- + +# 17. Regel: `ueba_offhours_login` + +## Zweck + +Erkennt erfolgreiche Benutzeranmeldungen außerhalb der definierten Arbeitszeit. + +## Aktuelle Arbeitszeit + +```text +06:00 bis 20:00 Uhr +``` + +Außerhalb dieser Zeit wird geprüft. + +## Datenbasis + +Tabelle: + +```text +event_logs +``` + +Windows Event: + +| Channel | EventID | +|---|---:| +| `Security` | `4624` | + +## Empfohlene Filter + +Um Rauschen durch technische Accounts zu vermeiden, sollten technische Accounts ausgeschlossen werden. + +### Empfohlene Go-Hilfsfunktion + +```go +func isNoiseAccount(username string) bool { + u := normalizeUsername(username) + + if u == "" || isMachineAccount(u) { + return true + } + + switch u { + case "system", + "localsystem", + "local service", + "network service", + "anonymous logon", + "dwm-1", + "dwm-2", + "dwm-3", + "umfd-0", + "umfd-1", + "umfd-2", + "umfd-3": + return true + } + + return false +} +``` + +`NT AUTHORITY\SYSTEM` wird durch `normalizeUsername()` zu `system` und damit sauber ignoriert. + +## Empfohlener SQL-Filter + +```sql +AND target_user <> '' +AND target_user <> '-' +AND target_user NOT LIKE '%$' +AND logon_type IN ('2', '7', '10', '11') +AND LOWER(target_user) NOT IN ( + 'system', + 'localsystem', + 'local service', + 'network service', + 'anonymous logon' +) +``` + +## Relevante LogonTypes + +| LogonType | Bedeutung | Bewertung | +|---:|---|---| +| `2` | Interactive | relevant | +| `7` | Unlock | meist relevant | +| `10` | RemoteInteractive/RDP | relevant | +| `11` | CachedInteractive | relevant | +| `3` | Network | oft Rauschen | +| `5` | Service | meist Rauschen | + +## Score und Severity + +Empfohlene Logik: + +| Bedingung | Score | Severity | +|---|---:|---| +| `count < 5` | `2.0` | `medium` | +| `count >= 5` | `4.0` | `high` | + +## Detection + +| Feld | Wert | +|---|---| +| Rule | `ueba_offhours_login` | +| Channel | `Security` | +| EventID | `4624` | + +## Beispiel-Summary + +```text +UEBA: Login außerhalb der Arbeitszeit: Benutzer max.mustermann auf Host CLIENT01 +``` + +## Typische legitime Ursachen + +- Bereitschaftsdienst +- geplante Wartung +- Remote-Arbeit +- automatisierte Admin-Tätigkeit +- Zeitzonen-/Serverzeitproblem + +## Typische verdächtige Ursachen + +- kompromittierte Zugangsdaten +- RDP-Zugriff nach Feierabend +- laterale Bewegung +- Admin-Account außerhalb normaler Betriebszeit + +--- + +# 18. Regel: `ueba_first_privileged_use` + +## Zweck + +Erkennt, wenn ein Benutzer erstmals privilegierte Rechte verwendet. + +## Datenbasis + +Tabellen: + +- `event_logs` +- `user_privilege_baseline` + +Windows Event: + +| Channel | EventID | +|---|---:| +| `Security` | `4672` | + +Event `4672` steht für „Special privileges assigned to new logon“. + +## Logik + +Für jedes `4672`-Event im Fenster wird geprüft, ob der Benutzer bereits in `user_privilege_baseline` existiert. + +Wenn nicht: + +1. Detection erzeugen +2. Benutzer in Baseline übernehmen + +## Empfohlene Tabelle + +```sql +CREATE TABLE IF NOT EXISTS user_privilege_baseline ( + username VARCHAR(255) NOT NULL PRIMARY KEY, + first_seen DATETIME(6) NOT NULL DEFAULT UTC_TIMESTAMP(6), + last_seen DATETIME(6) NOT NULL DEFAULT UTC_TIMESTAMP(6), + seen_count BIGINT NOT NULL DEFAULT 1 +); +``` + +## Detection + +| Feld | Wert | +|---|---| +| Rule | `ueba_first_privileged_use` | +| Channel | `Security` | +| EventID | `4672` | +| Severity | `high` | +| Score | `6.0` | + +## Beispiel-Summary + +```text +UEBA: Benutzer adm.max nutzt erstmals privilegierte Rechte auf Host SERVER01 +``` + +## Wichtiger Hinweis + +Diese Regel ist nur sinnvoll, wenn die Baseline gepflegt wird. Sonst wird derselbe Benutzer immer wieder als „erstmals privilegiert“ erkannt. + +--- + +# 19. Regel: `host_risk_score` + +## Zweck + +Aggregiert offene Detections pro Host zu einem Host-Risiko-Score. + +## Datenbasis + +Tabelle: + +```text +detections +``` + +Ausgabe: + +```text +host_risk_scores +``` + +## Zeitfenster + +| Parameter | Default | +|---|---:| +| `RISK_SCORE_WINDOW` | `24h` | + +## Ignorierte Detection-Status + +Diese Status werden nicht in den Risk Score einbezogen: + +```text +false_positive +suppressed +legitimate +resolved +plausible +``` + +## Severity-Gewichte + +| Severity | Gewicht | +|---|---:| +| `critical` | `25` | +| `high` | `10` | +| `medium` | `2` | +| `low` | `0.3` | +| `info` | `0.05` | +| sonst | `0.2` | + +## Status-Modifikatoren + +| Status | Wirkung | +|---|---| +| `confirmed_incident` | `+75` zusätzlich pro Gruppe | +| `investigating` | Gewicht `* 2` | +| `acknowledged` | Gewicht `* 0.5` | +| `open` | Gewicht `* 0.35` | + +## Dämpfung + +Gleiche Events zählen nicht linear, sondern gedämpft: + +```text +score += weight * sqrt(count) +``` + +Dadurch erzeugen 100 gleiche offene Events nicht 100-faches Risiko. + +## Severity aus Risk Score + +| Risk Score | Severity | +|---:|---| +| `>= 120` | `critical` | +| `>= 60` | `high` | +| `>= 20` | `medium` | +| `>= 5` | `low` | +| `< 5` | `info` | + +## Ausgabe-Felder + +| Feld | Bedeutung | +|---|---| +| `hostname` | Host | +| `risk_score` | berechneter Score | +| `severity` | abgeleitete Severity | +| `open_detections` | offene relevante Detections | +| `high_detections` | Anzahl High | +| `critical_detections` | Anzahl Critical | +| `confirmed_incidents` | bestätigte Incidents | +| `last_detection_at` | letzter relevanter Detection-Zeitpunkt | + +--- + +# 20. Suppression-Mechanismen + +## 20.1 Detection-Suppression + +Tabelle: + +```text +detection_suppressions +``` + +Die Funktion: + +```go +isDetectionSuppressed(ctx, det) +``` + +prüft vor dem Insert, ob eine passende aktive Suppression existiert. + +Match-Kriterien: + +```text +rule_name +hostname oder leer +channel_name oder leer +event_id oder 0 +expires_at IS NULL oder expires_at > now +enabled = 1 +``` + +Wenn Suppression aktiv ist, wird keine Detection erzeugt. + +## 20.2 Dynamic Rule Suppression + +Dynamische Regeln prüfen zusätzlich `suppress_for_seconds`. + +Dadurch wird verhindert, dass dieselbe dynamische Regel pro Host zu oft auslöst. + +## 20.3 Baseline-Suppression + +Baseline-Anomalien werden über `BASELINE_SUPPRESS_FOR` zeitlich gedämpft. + +## 20.4 Baseline-Exclusion + +Tabelle: + +```text +baseline_exclusions +``` + +Diese Tabelle verhindert, dass bestimmte Events in die Baseline eingelernt werden. + +Nützlich bei: + +- bestätigten Incidents +- Wartungsfenstern +- bekannten Ausnahmesituationen +- Testläufen +- Rollouts + +--- + +# 21. Detection-Status + +Unterstützte Status: + +| Status | Bedeutung | +|---|---| +| `open` | neu/offen | +| `acknowledged` | gesehen, noch nicht untersucht | +| `investigating` | in Untersuchung | +| `plausible` | plausibel, aber nicht unbedingt dauerhaft legitim | +| `legitimate` | legitim/erwartet | +| `false_positive` | Fehlalarm | +| `resolved` | erledigt | +| `suppressed` | bewusst unterdrückt | +| `confirmed_incident` | bestätigter Sicherheitsvorfall | + +## Auswirkungen + +| Status | Wirkung | +|---|---| +| `false_positive` | `is_false_positive = true`, aus Risk Score ausgeschlossen | +| `legitimate` | `is_legitimate = true`, aus Risk Score ausgeschlossen | +| `plausible` | aus Risk Score ausgeschlossen | +| `resolved` | aus Risk Score ausgeschlossen | +| `suppressed` | aus Risk Score ausgeschlossen | +| `confirmed_incident` | stark erhöhter Risk Score, Baseline-Lernen wird temporär verhindert | + +--- + +# 22. Privileged Users + +## Zweck + +Die Tabelle `privileged_users` erweitert die automatische Erkennung privilegierter Benutzer. + +## UI + +Pfad: + +```text +/ui/privileged-users +``` + +Funktionen: + +- Benutzer hinzufügen +- Grund dokumentieren +- aktivieren/deaktivieren + +## Automatische Erkennung + +Auch ohne Tabelle gelten Benutzer als privilegiert, wenn sie folgendem Namensschema entsprechen: + +```text +adm-* +*-adm +*.adm +``` + +## Maschinenkonten + +Maschinenkonten werden ignoriert: + +```text +*$ +``` + +--- + +# 23. Empfohlene Dynamic Rules für Windows Security Monitoring + +Diese Regeln lassen sich über `/ui/rules` pflegen. + +## 23.1 Security Audit Log gelöscht + +| Feld | Wert | +|---|---| +| Name | `security_log_cleared` | +| Severity | `critical` | +| Channel | `Security` | +| Event IDs | `1102` | +| Threshold | `1` | +| Suppress | `3600` | + +## 23.2 Benutzer erstellt + +| Feld | Wert | +|---|---| +| Name | `user_created` | +| Severity | `high` | +| Channel | `Security` | +| Event IDs | `4720` | + +## 23.3 Benutzer aktiviert + +| Feld | Wert | +|---|---| +| Name | `user_enabled` | +| Severity | `medium` | +| Channel | `Security` | +| Event IDs | `4722` | + +## 23.4 Benutzer deaktiviert + +| Feld | Wert | +|---|---| +| Name | `user_disabled` | +| Severity | `medium` | +| Channel | `Security` | +| Event IDs | `4725` | + +## 23.5 Benutzer gelöscht + +| Feld | Wert | +|---|---| +| Name | `user_deleted` | +| Severity | `high` | +| Channel | `Security` | +| Event IDs | `4726` | + +## 23.6 Sicherheitsgruppe erstellt + +| Feld | Wert | +|---|---| +| Name | `security_group_created` | +| Severity | `medium` | +| Channel | `Security` | +| Event IDs | `4727,4731` | + +## 23.7 Mitglied zu Sicherheitsgruppe hinzugefügt + +| Feld | Wert | +|---|---| +| Name | `security_group_member_added` | +| Severity | `high` | +| Channel | `Security` | +| Event IDs | `4728,4732,4756` | + +## 23.8 Mitglied aus Sicherheitsgruppe entfernt + +| Feld | Wert | +|---|---| +| Name | `security_group_member_removed` | +| Severity | `medium` | +| Channel | `Security` | +| Event IDs | `4729,4733,4757` | + +## 23.9 Konto gesperrt + +| Feld | Wert | +|---|---| +| Name | `account_locked` | +| Severity | `medium` | +| Channel | `Security` | +| Event IDs | `4740` | + +## 23.10 Kerberos Pre-Auth fehlgeschlagen + +| Feld | Wert | +|---|---| +| Name | `kerberos_preauth_failed` | +| Severity | `low` | +| Channel | `Security` | +| Event IDs | `4771` | +| Threshold Count | `10` | +| Threshold Window Seconds | `300` | + +## 23.11 Service installiert + +| Feld | Wert | +|---|---| +| Name | `service_installed` | +| Severity | `high` | +| Channel | `System,Security` | +| Event IDs | `7045,4697` | + +## 23.12 Scheduled Task erstellt + +| Feld | Wert | +|---|---| +| Name | `scheduled_task_created` | +| Severity | `medium` | +| Channel | `Security` | +| Event IDs | `4698` | + +## 23.13 Audit Policy geändert + +| Feld | Wert | +|---|---| +| Name | `audit_policy_changed` | +| Severity | `high` | +| Channel | `Security` | +| Event IDs | `4719` | + +--- + +# 24. Empfohlene Indizes + +Für Performance sollten mindestens diese Indizes vorhanden sein. + +```sql +CREATE INDEX idx_event_logs_ts ON event_logs (ts); +CREATE INDEX idx_event_logs_host_ts ON event_logs (hostname, ts); +CREATE INDEX idx_event_logs_channel_event_ts ON event_logs (channel_name, event_id, ts); +CREATE INDEX idx_event_logs_security_logon ON event_logs (channel_name, event_id, target_user, src_ip, ts); +CREATE INDEX idx_event_logs_host_channel_event_ts ON event_logs (hostname, channel_name, event_id, ts); + +CREATE INDEX idx_detections_created ON detections (created_at); +CREATE INDEX idx_detections_rule_host_created ON detections (rule_name, hostname, created_at); +CREATE INDEX idx_detections_status_created ON detections (status, created_at); +CREATE INDEX idx_detections_host_status_created ON detections (hostname, status, created_at); + +CREATE INDEX idx_agents_enabled_lastseen ON agents (is_enabled, last_seen); + +CREATE INDEX idx_ueba_user_baseline_lookup +ON ueba_user_baseline (username, hostname, src_ip, workstation, first_seen, last_seen); + +CREATE INDEX idx_baseline_event_stats_lookup +ON baseline_event_stats (hostname, channel_name, event_id, hour_of_day, day_of_week); + +CREATE INDEX idx_detection_suppressions_lookup +ON detection_suppressions (enabled, rule_name, hostname, channel_name, event_id, expires_at); + +CREATE INDEX idx_baseline_exclusions_lookup +ON baseline_exclusions (enabled, hostname, channel_name, event_id, expires_at); +``` + +--- + +# 25. Empfohlene SOC-Priorisierung + +## Sofort prüfen + +- `confirmed_incident` +- `critical` +- `success_after_failures` +- `password_spray` +- `security_log_cleared` +- `ueba_admin_new_host` +- `ueba_first_privileged_use` + +## Hoch priorisieren + +- `new_source_ip_for_user` bei privilegierten Benutzern +- `ueba_offhours_login` bei Admin-Konten +- `baseline_event_rate_anomaly` mit hohem Z-Score +- `service_installed` auf Clients oder Domain Controllern +- `scheduled_task_created` außerhalb Wartungsfenster + +## Eher Rauschen / Kontextabhängig + +- `agent_offline` bei normalen Clients +- `reboot_spike` während Patchfenster +- `new_event_id` direkt nach Audit-Policy-Änderungen +- `ueba_new_user_context` bei VPN-/DHCP-Änderungen +- `ueba_offhours_login` ohne LogonType-Filter + +--- + +# 26. Bekannte Rauschquellen + +## SYSTEM / technische Accounts + +Besonders bei `4624` können technische Accounts sehr viele Events erzeugen. + +Empfohlene Ausschlüsse: + +```text +SYSTEM +NT AUTHORITY\SYSTEM +LOCAL SERVICE +NETWORK SERVICE +ANONYMOUS LOGON +DWM-* +UMFD-* +Maschinenkonten mit $ +``` + +## LogonType + +Für echte Benutzeranmeldungen sind meist relevant: + +```text +2, 7, 10, 11 +``` + +Oft rauschanfällig: + +```text +3, 5 +``` + +## Patchfenster + +Während Patchfenstern können diese Regeln anschlagen: + +- `reboot_spike` +- `new_event_id` +- `baseline_event_rate_anomaly` +- `agent_offline` + +Empfehlung: + +- Batch-Bewertung auf `plausible` +- temporäre Baseline-Exclusion +- temporäre Suppression für bekannte Regeln + +--- + +# 27. Empfohlene Weiterentwicklung + +## 27.1 Regelkonfiguration für Off-Hours + +Aktuell ist die Arbeitszeit hart im Code: + +```text +06:00 bis 20:00 +``` + +Empfohlen wäre eine Konfiguration über ENV: + +```text +OFFHOURS_ENABLED=true +WORK_HOUR_START=6 +WORK_HOUR_END=20 +OFFHOURS_LOGON_TYPES=2,7,10,11 +``` + +## 27.2 Noise-Accounts in Tabelle auslagern + +Statt hartem Code könnte eine Tabelle genutzt werden: + +```sql +CREATE TABLE ignored_accounts ( + username VARCHAR(255) NOT NULL PRIMARY KEY, + reason VARCHAR(255) NULL, + enabled BOOLEAN NOT NULL DEFAULT TRUE, + created_at DATETIME(6) NOT NULL DEFAULT UTC_TIMESTAMP(6), + updated_at DATETIME(6) NOT NULL DEFAULT UTC_TIMESTAMP(6) ON UPDATE UTC_TIMESTAMP(6) +); +``` + +## 27.3 Dynamic Rules um Negativfilter erweitern + +Nützlich wären: + +- `exclude_field` +- `exclude_operator` +- `exclude_value` + +Beispiel: + +```text +target_user NOT IN system,local service,network service +``` + +## 27.4 MITRE ATT&CK Mapping + +Jede Detection könnte um MITRE-Technik erweitert werden: + +| Regel | Mögliche Technik | +|---|---| +| `password_spray` | T1110.003 Password Spraying | +| `success_after_failures` | T1110 Brute Force | +| `service_installed` | T1543.003 Windows Service | +| `scheduled_task_created` | T1053.005 Scheduled Task | +| `security_log_cleared` | T1070.001 Clear Windows Event Logs | +| `ueba_admin_new_host` | T1078 Valid Accounts | + +--- + +# 28. Kurze Betriebscheckliste + +## Täglich + +- SOC Dashboard prüfen +- Top Host Risk Scores prüfen +- offene `critical` und `high` Detections bewerten +- False Positives markieren +- legitime Wartungsereignisse als `plausible` oder `legitimate` markieren + +## Wöchentlich + +- häufige False Positives auswerten +- Suppressions prüfen +- Baseline-Exclusions prüfen +- Dynamic Rules nachschärfen +- neue EventIDs bewerten + +## Monatlich + +- Privileged Users prüfen +- UEBA-Baseline-Qualität prüfen +- Indizes und Query-Laufzeiten prüfen +- Prometheus/Grafana-Dashboards kontrollieren +- Retention-Konzept prüfen + +--- + +# 29. Glossar + +| Begriff | Bedeutung | +|---|---| +| Detection | Ein ausgelöster Regel-Treffer | +| Suppression | Unterdrückung bekannter oder akzeptierter Detections | +| Baseline | gelernter Normalzustand | +| UEBA | User and Entity Behavior Analytics | +| Z-Score | statistischer Abstand zum Mittelwert | +| Host Risk Score | aggregierter Risikowert pro Host | +| LogonType | Windows-Klassifikation der Anmeldung | +| `4624` | erfolgreicher Logon | +| `4625` | fehlgeschlagener Logon | +| `4672` | Special Privileges Assigned | +| `1102` | Security Audit Log gelöscht | +| `7045` | Service installiert | + +--- + +# 30. Kurzfazit + +Das Regelwerk kombiniert klassische EventID-Regeln, dynamische Regeln, Baseline-Anomalien und UEBA-Kontextregeln. + +Die wichtigsten Qualitätshebel sind: + +1. technische Accounts konsequent ausschließen, +2. LogonTypes sauber filtern, +3. Baselines nicht mit Incidents trainieren, +4. Status sauber pflegen, +5. legitime Wartungsfenster als `plausible` oder `legitimate` markieren, +6. echte Incidents als `confirmed_incident` markieren, +7. Dynamic Rules regelmäßig nachschärfen. + +Besonders wichtig für die aktuelle `runOffHoursLoginRule`: + +```text +SYSTEM, LOCAL SERVICE, NETWORK SERVICE, ANONYMOUS LOGON und Maschinenkonten sollten ignoriert werden. +Zusätzlich sollte die Regel auf LogonType 2, 7, 10 und 11 begrenzt werden. +```