From 91bf9ed3fcd3d4196063edaec63306025f6d4ff0 Mon Sep 17 00:00:00 2001 From: groot Date: Thu, 30 Apr 2026 08:39:24 +0200 Subject: [PATCH] Neuer Fix --- main.go | 92 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 35 deletions(-) diff --git a/main.go b/main.go index db10937..ed1be28 100644 --- a/main.go +++ b/main.go @@ -4963,42 +4963,51 @@ func buildSQLMatchCondition(r DynamicRule) (string, []any) { } func (s *server) runDetectionsOnce() { - ctx, cancel := context.WithTimeout(context.Background(), s.cfg.DetectionInterval) - defer cancel() - - if err := s.detector.updateAgentMetrics(ctx); err != nil { - s.logger.Printf("update agent metrics: %v", err) + type ruleSpec struct { + name string + timeout time.Duration + fn func(context.Context) error } - rules := []struct { - name string - fn func(context.Context) error - }{ - {"agent_offline", s.detector.runAgentOfflineRule}, - {"failed_logon_spike", s.detector.runFailedLogonSpikeRule}, - {"reboot_spike", s.detector.runRebootSpikeRule}, - {"new_event_id", s.detector.runNewEventIDRule}, - {"password_spray", s.detector.runPasswordSprayRule}, - {"success_after_failures", s.detector.runSuccessAfterFailuresRule}, - {"new_source_ip_for_user", s.detector.runNewSourceIPForUserRule}, - {"dynamic_rules", s.detector.runDynamicRules}, + rules := []ruleSpec{ + {"agent_offline", 15 * time.Second, s.detector.runAgentOfflineRule}, + {"failed_logon_spike", 45 * time.Second, s.detector.runFailedLogonSpikeRule}, + {"reboot_spike", 30 * time.Second, s.detector.runRebootSpikeRule}, + {"new_event_id", 60 * time.Second, s.detector.runNewEventIDRule}, + {"password_spray", 60 * time.Second, s.detector.runPasswordSprayRule}, + {"success_after_failures", 90 * time.Second, s.detector.runSuccessAfterFailuresRule}, + {"new_source_ip_for_user", 90 * time.Second, s.detector.runNewSourceIPForUserRule}, + {"dynamic_rules", 60 * time.Second, s.detector.runDynamicRules}, - {"ueba_admin_new_host", s.detector.runAdminNewHostRule}, - {"ueba_offhours_login", s.detector.runOffHoursLoginRule}, - {"ueba_first_privileged_use", s.detector.runFirstTimePrivilegedRule}, - {"ueba_new_user_context", s.detector.runUEBANewUserContextRule}, - {"ueba_update", s.detector.runUEBABaselineUpdate}, + {"ueba_admin_new_host", 90 * time.Second, s.detector.runAdminNewHostRule}, + {"ueba_offhours_login", 60 * time.Second, s.detector.runOffHoursLoginRule}, + {"ueba_first_privileged_use", 60 * time.Second, s.detector.runFirstTimePrivilegedRule}, + + // Diese Regel ist bei dir aktuell der Problemfall. + {"ueba_new_user_context", 180 * time.Second, s.detector.runUEBANewUserContextRule}, + + {"ueba_update", 120 * time.Second, s.detector.runUEBABaselineUpdate}, } for _, rule := range rules { start := time.Now() - if err := rule.fn(ctx); err != nil { - s.logger.Printf("rule %s error: %v", rule.name, err) + + ctx, cancel := context.WithTimeout(context.Background(), rule.timeout) + err := rule.fn(ctx) + cancel() + + dur := time.Since(start) + + if err != nil { + s.logger.Printf("rule %s error after %s: %v", rule.name, dur, err) s.detector.ruleErrorsTotal.WithLabelValues(rule.name).Inc() continue } + + s.logger.Printf("rule %s completed in %s", rule.name, dur) + s.detector.ruleLastRunGauge.WithLabelValues(rule.name).Set(float64(time.Now().Unix())) - s.detector.ruleRuntimeHist.WithLabelValues(rule.name).Observe(time.Since(start).Seconds()) + s.detector.ruleRuntimeHist.WithLabelValues(rule.name).Observe(dur.Seconds()) } } @@ -5061,6 +5070,8 @@ func (d *detector) runUEBANewUserContextRule(ctx context.Context) error { return nil } + start := time.Now() + windowEnd := time.Now().UTC() windowStart := windowEnd.Add(-d.cfg.UEBANewContextWindow) @@ -5079,23 +5090,21 @@ WHERE e.channel_name = 'Security' AND e.target_user <> '' AND e.target_user <> '-' AND e.target_user NOT LIKE '%$' - AND LOWER(e.target_user) NOT IN ( - 'system', - 'localsystem', - 'local service', - 'network service', - 'anonymous logon' - ) GROUP BY e.hostname, e.target_user, e.src_ip, e.workstation ` rows, err := d.db.QueryContext(ctx, q, windowStart, windowEnd) if err != nil { - return err + return fmt.Errorf("query ueba_new_user_context after %s: %w", time.Since(start), err) } defer rows.Close() + rowCount := 0 + newCount := 0 + for rows.Next() { + rowCount++ + var host, user, srcIP, workstation string var firstSeen time.Time var count int @@ -5118,6 +5127,8 @@ GROUP BY e.hostname, e.target_user, e.src_ip, e.workstation continue } + newCount++ + score := 2.0 severity := "medium" @@ -5162,9 +5173,20 @@ GROUP BY e.hostname, e.target_user, e.src_ip, e.workstation } } - return rows.Err() -} + if err := rows.Err(); err != nil { + return err + } + d.logger.Printf( + "ueba_new_user_context processed rows=%d new_contexts=%d window=%s duration=%s", + rowCount, + newCount, + d.cfg.UEBANewContextWindow, + time.Since(start), + ) + + return nil +} func riskWeight(severity string) float64 { switch severity { case "critical":