Automatisierung und DFIR
Automatisierung und DFIR
Scripting ist im Security-Bereich besonders nützlich, wenn viele Daten schnell durchsucht, normalisiert oder ausgewertet werden müssen.
Die Übungsunterlagen enthalten dafür ein DFIR-Szenario zu Ping-Anrufen.
Szenario
Eine fiktive Firma wurde mit vielen Ping-Anrufen geflutet.
Ziel der Angreifer:
- Mitarbeiter sehen verpasste Anrufe.
- Sie rufen unbekannte Nummern zurück.
- Der Rückruf wird auf Mehrwertnummern weitergeleitet.
- Es entstehen hohe Kosten.
Die Aufgabe ist, ein Anrufjournal auszuwerten und verdächtige Telefonnummern herauszufiltern.
Eingabedaten
Die Datei call_log.txt enthält Zeilen in dieser Art:
2021.04.06 11:17:03: 043498.140572422,
2021.11.27 15:48:05: 043401-38872347,
2021.12.25 15:13:00: 043443///7578623054,
Problem: Telefonnummern sind unterschiedlich formatiert.
Mögliche Trenner:
//////._-
Regeln für Angreifer-Nummern
Aus der Aufgabenstellung:
- Die Vorwahl beginnt mit
0. - Die Vorwahl ist fünf oder sechs Ziffern lang.
- Vorwahl und Nummer sind durch
/,//,///oder.getrennt. - Die dritte Stelle der Nummer von links ist
1oder4. - Die Nummer ist acht bis zehn Zeichen lang.
Nicht alle im Log vorkommenden Trenner sind also für Angreifer-Nummern erlaubt.
Regex-Idee
Ein mögliches Suchmuster:
r"(0\d{4,5})(/|//|///|\.)(\d{2}[14]\d{5,7})"
Erklärung:
| Teil | Bedeutung |
|---|---|
0 | Vorwahl beginnt mit 0 |
\d{4,5} | vier bis fünf weitere Ziffern, also insgesamt fünf oder sechs |
| `(/ | // |
\d{2} | erste zwei Stellen der Nummer |
[14] | dritte Stelle ist 1 oder 4 |
\d{5,7} | restliche Stellen, insgesamt acht bis zehn |
Noch robuster ist es, längere Trenner zuerst zu matchen:
r"(0\d{4,5})(///|//|/|\.)(\d{2}[14]\d{5,7})"
Normalisierung
Die Ausgabe soll einheitlich sein:
Vorwahl/Nummer
Egal ob die Eingabe 043443///7578623054 oder 043498.140572422 war, das Ergebnis wird mit / geschrieben.
normalized = f"{prefix}/{number}"
Duplikate entfernen
Für eindeutige Telefonnummern eignet sich ein Set.
attacker_numbers = set()
attacker_numbers.add(normalized)
Vor dem Schreiben kann sortiert werden:
for number in sorted(attacker_numbers):
fd.write(number + "\n")
Ergebnisdatei schreiben
with open("attacker_numbers.txt", "w", encoding="utf-8") as fd:
for number in sorted(attacker_numbers):
fd.write(number + "\n")
Sortierung macht Ergebnisse reproduzierbar. Das ist wichtig für Reviews und Hashwerte.
Hash berechnen
Die Unterlagen enthalten ein Hilfsskript, das sortierte Inhalte mit SHA-256 hasht.
import hashlib
sorted_content = "".join(sorted_lines).encode("utf-8")
sha256_hash = hashlib.sha256(sorted_content).hexdigest()
Ein Hashwert hilft, eine Ergebnisdatei eindeutig zu prüfen:
- Wurde die Datei verändert?
- Haben zwei Personen dasselbe Ergebnis?
- Kann die Datei nachvollziehbar weitergegeben werden?
Robuster Ablauf
Ein gutes DFIR-Skript arbeitet in klaren Schritten:
- Eingabedatei öffnen.
- Zeilen lesen.
- Muster mit Regex suchen.
- Treffer normalisieren.
- Duplikate entfernen.
- Ergebnisse sortieren.
- Datei schreiben.
- Optional Hash berechnen.
Fehlerbehandlung
Bei Dateioperationen sollte man mit Fehlern rechnen.
try:
with open(path, "r", encoding="utf-8") as fd:
data = fd.read()
except FileNotFoundError:
print(f"Datei nicht gefunden: {path}")
Für echte Tools wäre Logging besser als nur print.
Sicherheitsbezug
Scripting ist in DFIR hilfreich, weil man:
- große Logdateien schneller analysieren kann
- Muster reproduzierbar erkennt
- Ergebnisse normalisiert weitergeben kann
- Fehler durch manuelle Auswertung reduziert
- kleine Spezialwerkzeuge schnell bauen kann
Merksatz
Ein gutes Security-Skript ist nicht nur kurz. Es ist nachvollziehbar, reproduzierbar und verarbeitet Eingaben kontrolliert.
Zuletzt aktualisiert: 6. Juni 2026