Erkennungsregeln mit Splunk SPL erstellen
Übersicht
Die Splunk Search Processing Language (SPL) ist die primäre Abfragesprache in Splunk Enterprise Security, mit der Korrelationssuchen erstellt werden, die verdächtige Ereignisse und Muster erkennen. Eine gut ausgearbeitete Erkennungsregel aggregiert, korreliert und reichert Sicherheitsereignisse an, um für SOC-Analysten umsetzbare Notable Events zu generieren. Enterprise SIEMs decken im Durchschnitt nur 21 % der MITRE ATT&CK-Techniken ab, weshalb fundierte SPL-Regelerstellung für die Schließung von Erkennungslücken unerlässlich ist.
Wann verwenden
- Beim Bereitstellen oder Konfigurieren der Fähigkeiten zur Erstellung von Erkennungsregeln mit Splunk SPL in Ihrer Umgebung
- Bei der Einrichtung von Sicherheitskontrollen, die auf Compliance-Anforderungen abgestimmt sind
- Beim Aufbau oder der Verbesserung der Sicherheitsarchitektur für diesen Bereich
- Bei der Durchführung von Sicherheitsbewertungen, die diese Implementierung erfordern
Voraussetzungen
- Splunk Enterprise Security (ES) bereitgestellt und konfiguriert
- Zugriff auf die Splunk Search & Reporting App mit entsprechenden Rollen
- Verständnis der Datenmodelle des Common Information Model (CIM)
- Vertrautheit mit den Techniken des MITRE ATT&CK Frameworks
- Kenntnisse der Logquellen und Datenflüsse der Organisation
Kern-SPL-Erkennungsregelmuster
1. Schwellenwertbasierte Erkennung
Erkennt Ereignisse, die eine definierte Anzahl innerhalb eines Zeitfensters überschreiten.
index=wineventlog sourcetype=WinEventLog:Security EventCode=4625
| stats count as failed_logins dc(TargetUserName) as unique_users by src_ip
| where failed_logins > 10 AND unique_users > 3
| eval severity="high"
| eval description="Brute-Force-Angriff erkannt von ".src_ip." mit ".failed_logins." fehlgeschlagenen Anmeldungen über ".unique_users." Konten hinweg"
2. Sequenzbasierte Erkennung (Fehlgeschlagene Anmeldung gefolgt von Erfolg)
Korreliert eine Ereignissequenz, die einen erfolgreichen Brute-Force-Angriff anzeigt.
index=wineventlog sourcetype=WinEventLog:Security (EventCode=4625 OR EventCode=4624)
| eval login_status=case(EventCode=4625, "failure", EventCode=4624, "success")
| stats count(eval(login_status="failure")) as failures count(eval(login_status="success")) as successes latest(_time) as last_event by src_ip, TargetUserName
| where failures > 5 AND successes > 0
| eval description="Konto ".TargetUserName." durch Brute-Force von ".src_ip." kompromittiert"
| eval urgency="critical"
3. Anomalieerkennung mit Basislinienvergleich
Vergleicht aktuelle Aktivitäten mit einem Basislinienzeitraum, um Spitzen zu erkennen.
index=proxy sourcetype=squid
| bin _time span=1h
| stats count as current_count by src_ip, _time
| join src_ip type=left [
search index=proxy sourcetype=squid earliest=-7d@d latest=-1d@d
| stats avg(count) as avg_count stdev(count) as stdev_count by src_ip
]
| eval threshold=avg_count + (3 * stdev_count)
| where current_count > threshold
| eval deviation=round((current_count - avg_count) / stdev_count, 2)
| eval description="Anomaler Webverkehr von ".src_ip." - ".deviation." Standardabweichungen über der Basislinie"
4. Erkennung lateraler Bewegung
Identifiziert potenzielle laterale Bewegung mithilfe von Windows-Anmeldeereignissen.
index=wineventlog sourcetype=WinEventLog:Security EventCode=4624 Logon_Type=3
| where NOT match(TargetUserName, ".*\$$\$")
| stats dc(dest) as unique_hosts values(dest) as hosts by src_ip, TargetUserName
| where unique_hosts > 5
| eval severity=case(unique_hosts > 20, "critical", unique_hosts > 10, "high", true(), "medium")
| eval description=TargetUserName." hat von ".src_ip." über Netzwerkanmeldung auf ".unique_hosts." eindeutige Hosts zugegriffen"
5. Erkennung von Datengefährdung
Überwacht auf große ausgehende Datentransfers.
index=firewall sourcetype=pan:traffic action=allowed direction=outbound
| stats sum(bytes_out) as total_bytes_out dc(dest_ip) as unique_destinations by src_ip, user
| eval total_mb=round(total_bytes_out/1048576, 2)
| where total_mb > 500 OR unique_destinations > 50
| lookup asset_lookup ip as src_ip OUTPUT asset_category, asset_owner
| eval severity=case(total_mb > 2000, "critical", total_mb > 1000, "high", true(), "medium")
| eval description=user." hat ".total_mb."MB an ".unique_destinations." eindeutige Ziele übertragen"
6. Erkennung verdächtiger PowerShell-Ausführungen
Erkennt codierte oder verschleierte PowerShell-Befehle.
index=wineventlog sourcetype=WinEventLog:Security EventCode=4104
| where match(ScriptBlockText, "(?i)(encodedcommand|invoke-expression|iex|downloadstring|frombase64string|net\.webclient|invoke-webrequest|bitstransfer|invoke-mimikatz|invoke-shellcode)")
| eval decoded_length=len(ScriptBlockText)
| stats count values(ScriptBlockText) as commands by Computer, UserName
| where count > 0
| eval severity="high"
| eval mitre_technique="T1059.001"
| eval description="Verdächtige PowerShell-Ausführung auf ".Computer." durch ".UserName
Korrelationssuchen in Splunk ES erstellen
Schritt-für-Schritt-Prozess
- Anwendungsfall definieren: Auf MITRE ATT&CK-Technik abbilden und das zu erkennende Verhalten definieren
- Datenquellen identifizieren: Bestimmen, welche Indexes und Sourcetypes relevante Ereignisse enthalten
- Basis-Suche schreiben: SPL erstellen, das relevante Ereignisse extrahiert
- Aggregation hinzufügen:
stats,eventstatsoderstreamstatszur Zusammenfassung verwenden - Schwellenwerte anwenden: Bedingungen mit der
where-Klausel setzen, die Normal von Anomal unterscheiden - Kontext anreichern: Lookups für Asset-Informationen, Identitätsdaten und Bedrohungsinformationen hinzufügen
- Notable Event konfigurieren: Schweregrad, Dringlichkeit und Beschreibungsfelder setzen
- Planen und testen: Gegen historische Daten ausführen und die Erkennungsgenauigkeit validieren
Vorlage für die Konfiguration von Korrelationssuchen
| tstats summariesonly=true count from datamodel=Authentication
where Authentication.action=failure
by Authentication.src, Authentication.user, _time span=5m
| rename "Authentication.*" as *
| stats count as total_failures dc(user) as unique_users values(user) as targeted_users by src
| where total_failures > 20 AND unique_users > 5
| lookup dnslookup clientip as src OUTPUT clienthost as src_dns
| lookup asset_lookup ip as src OUTPUT priority as asset_priority, category as asset_category
| eval urgency=case(asset_priority=="critical", "critical", asset_priority=="high", "high", true(), "medium")
| eval rule_name="Brute-Force gegen mehrere Konten"
| eval rule_description="Mehrere Authentifizierungsfehler von ".src." gegen ".unique_users." eindeutige Konten"
| eval mitre_attack="T1110.001 - Passwort-Raten"
Best Practices zur Anreicherung
| lookup identity_lookup identity as user OUTPUT department, manager, risk_score as user_risk
| lookup asset_lookup ip as src_ip OUTPUT asset_name, asset_category, asset_priority, asset_owner
| lookup threatintel_lookup ip as src_ip OUTPUT threat_type, threat_confidence, threat_source
| eval context=case(
isnotnull(threat_type), "Bekannte Bedrohung: ".threat_type,
user_risk > 80, "Hochrisikobenutzer: Risikoscore ".user_risk,
asset_priority=="critical", "Kritisches Asset: ".asset_name,
true(), "Standardkontext"
)
Leistungsoptimierung
Datenmodelle mit tstats verwenden
| tstats summariesonly=true count from datamodel=Network_Traffic
where All_Traffic.action=allowed
by All_Traffic.src_ip, All_Traffic.dest_ip, All_Traffic.dest_port, _time span=1h
| rename "All_Traffic.*" as *
Zeitbereiche eingrenzen und indexierte Felder nutzen
index=wineventlog source="WinEventLog:Security" EventCode=4688
earliest=-15m latest=now()
| where NOT match(New_Process_Name, "(?i)(svchost|csrss|lsass|services)")
Zusammenfassungsindizierung für historische Basislinien verwenden
| tstats count from datamodel=Authentication where Authentication.action=failure by Authentication.src, _time span=1h
| collect index=summary source="auth_failure_baseline" marker="report_name=auth_failure_hourly"
Testen und Validieren
Gegen bekannte Angriffsmuster testen
| makeresults count=1
| eval src_ip="10.0.0.50", failed_logins=25, unique_users=8, severity="high"
| eval description="Test-Brute-Force-Erkennung"
| append [
search index=wineventlog sourcetype=WinEventLog:Security EventCode=4625
earliest=-24h latest=now()
| stats count as failed_logins dc(TargetUserName) as unique_users by src_ip
| where failed_logins > 10 AND unique_users > 3
| eval severity="high"
]
Erkennungsmetriken berechnen
index=notable
| search rule_name="Brute Force*"
| stats count as total_alerts count(eval(status_label="Closed - True Positive")) as true_positives count(eval(status_label="Closed - False Positive")) as false_positives by rule_name
| eval precision=round(true_positives / (true_positives + false_positives) * 100, 2)
| eval fpr=round(false_positives / total_alerts * 100, 2)
MITRE ATT&CK Mapping
| Technik-ID | Technikname | SPL-Erkennungsansatz |
|---|---|---|
| T1110.001 | Passwort-Raten | Schwellenwert auf EventCode 4625 nach src_ip |
| T1059.001 | PowerShell | Mustervergleich auf EventCode 4104 ScriptBlockText |
| T1021.002 | SMB/Windows-Admin-Freigaben | Anmeldetyp 3 mit dc(dest)-Schwellenwert |
| T1048 | Exfiltration über C2 | bytes_out-Aggregation über Zeitfenster |
| T1053.005 | Geplanter Task | EventCode 4698 mit verdächtigen Befehlsmustern |
| T1003.001 | LSASS-Speicher | Prozesszugriff auf lsass.exe über Sysmon EventCode 10 |