Zeitleistenanalyse · Lektion 3 von 5
Erstellen einer Super-Timeline mit Plaso
11 Min. Lesezeit
Ein einzelnes Artefakt verrät Ihnen selten, was geschehen ist. Die Abfolge über viele Artefakte hinweg tut es: Ein Programm wurde ausgeführt, eine Datei geöffnet, ein Laufwerk angeschlossen, eine Kopie erschien auf diesem Laufwerk. Eine Super-Timeline führt Ereignisse aus Dateisystemen, Registry-Hives, Ereignisprotokollen, Browserverläufen und anderen Quellen in einer nach Zeit sortierten Liste zusammen. Diese Lektion erstellt eine solche Timeline mit The Sleuth Kit und mit Plaso, reduziert Millionen von Ereignissen auf die entscheidenden Minuten und erläutert den häufigsten Triage-Fehler: die Kopierzeitpunkte der gesammelten Dateien als Beweis zu behandeln.
Dateisystem-Timelines und Super-Timelines
Eine Dateisystem-Timeline führt ausschließlich die in den Dateisystem-Metadaten enthaltenen Zeitstempel auf: bei NTFS die in Lektion 3.2 behandelten Zeitstempel aus $STANDARD_INFORMATION und $FILE_NAME; bei FAT, ext4 und anderen Dateisystemen deren eigene Zeitfelder. Sie lässt sich schnell erstellen, sagt aber nichts darüber aus, warum sich ein Zeitstempel geändert hat.
Eine Super-Timeline ergänzt die innerhalb von Dateien gespeicherten Zeitstempel: Prefetch-Ausführungszeiten, LastWrite-Zeitstempel von Registry-Schlüsseln, Ereignisprotokolleinträge, LNK- und Sprunglistendaten sowie Browseraufrufe. Jede Zeile trägt dadurch eine Bedeutung, etwa „zuletzt besucht“ oder „zuletzt ausgeführt“. Der Preis dafür ist die Datenmenge: Ein vollständiges Windows-Systemabbild erzeugt üblicherweise Millionen von Ereignissen.
| Aspekt | Dateisystem-Timeline | Super-Timeline |
|---|---|---|
| Quellen | Nur Dateisystem-Metadaten | Dateisystem sowie Artefakte innerhalb von Dateien |
| Typische Werkzeuge | fls + mactime (The Sleuth Kit) | Plaso (log2timeline.py, psort.py) |
| Ereignisbedeutung | MACB-Kennzeichen | timestamp_desc-Text je Ereignis |
| Umfang | Tausende bis Hunderttausende Zeilen | Häufig Millionen von Zeilen |
| Optimaler Einsatz | Schneller Überblick über Dateiaktivitäten auf einem Volume | Rekonstruktion von Benutzer- und Systemaktivitäten |
Die klassische Methode: Bodyfile und mactime
The Sleuth Kit erstellt eine Dateisystem-Timeline in zwei Schritten. Zunächst durchläuft fls -r -m E: -z America/Sao_Paulo -o 2048 usb.E01 > usb.body das Dateisystem rekursiv (-r) und schreibt ein Bodyfile (-m, wobei E: als Präfix vor jeden Pfad gesetzt wird); -z gibt die Zeitzone des ursprünglichen Systems an, die fls zur Umrechnung lokaler FAT-Zeitstempel benötigt. -o 2048 ist der Startsektor der Partition. Anschließend sortiert mactime -b usb.body -d -z UTC > usb.csv das Bodyfile und gibt es als kommagetrennten Text (-d) in UTC (-z) aus.
Das Bodyfile (TSK-3.x-Format) enthält 11 durch senkrechte Striche getrennte Felder: MD5|name|inode|mode_as_string|UID|GID|size|atime|mtime|ctime|crtime. Die vier Zeitangaben sind Sekunden seit der Unix-Epoche. Bei NTFS schreibt fls für jede Datei eine zweite Zeile, in der ($FILE_NAME) an den Namen angehängt ist und die die $FN-Zeitstempel enthält.
Die Ausgabespalten von mactime sind Date (Datum), Size (Größe), Type (Typ), Mode (Modus), UID, GID, Meta und File Name (Dateiname). Type ist die MACB-Zeichenfolge: m für geändert, a für zugegriffen, c für Metadaten geändert, b für angelegt (erstellt). Eine Zeile mit m.cb bedeutet, dass drei der vier Zeitstempel auf dieselbe Sekunde fallen.
Durchgerechnetes Beispiel: einen Bodyfile-Zeitstempel lesen
Eine Bodyfile-Zeile für E:/Plans/agenda.docx enthält crtime = 1.773.479.721.
- 1.773.479.721 ÷ 86.400 = 20.526 Tage, Rest 33.321 Sekunden.
- 20.526 Tage nach 1970-01-01 ist 2026-03-14.
- 33.321 s = 9 h (32.400 s) + 921 s = 9 h 15 min 21 s.
- Ergebnis: 2026-03-14T09:15:21Z.
mactime -z UTCgibt dies alsSat Mar 14 2026 09:15:21aus;-ygibt stattdessen ISO 8601 in UTC aus.
Plaso-Architektur
Plaso („Plaso Langar Að Safna Öllu“) teilt die Arbeit in Extraktion und Ausgabe auf, verbunden durch eine Speicherdatei.
log2timeline.pyöffnet die Quelle über dfVFS, die virtuelle Dateisystemschicht von Plaso (die E01- und Rohabbilder, Partitionen, VSS-Schattenkopien und einfache Verzeichnisse liest). Es wendet Parser auf jede Datei an und schreibt jedes Ereignis in eine Plaso-Speicherdatei (.plaso), die auf SQLite basiert.pinfo.pyberichtet über den Inhalt einer Speicherdatei: die Plaso-Version, jede Extraktionssitzung mit ihrer Befehlszeile, die Ereignisanzahl je Parser und Warnungen bei der Extraktion.psort.pyliest die Speicherdatei, sortiert nach Zeit, entfernt Duplikate, wendet Filter an und schreibt die Ausgabe.psteal.pyführt Extraktion und Ausgabe in einem Schritt aus, zum Beispielpsteal.py --source usb.E01 -o dynamic -w usb.csv. Die getrennten Werkzeuge eignen sich besser für die Fallarbeit: Die Speicherdatei kann erneut gefiltert werden, ohne nochmals extrahieren zu müssen.
Parser und Voreinstellungen. --parsers nimmt eine kommagetrennte Liste von Voreinstellungen, Parsern und Plugins entgegen. Ein vorangestelltes ! schließt einen Eintrag aus. log2timeline.py --info listet alle auf. Nützliche Voreinstellungen sind win7 (Windows Vista und neuer, einschließlich des allgemeinen Satzes win_gen), webhist (Browserverläufe) und linux; winreg ist der Registry-Parser mit all seinen Plugins. Der Parser mft liest eine NTFS-Datei $MFT direkt und gibt sowohl $SI- als auch $FN-Zeitstempel aus; fügen Sie ihn namentlich hinzu, damit die gesammelte $MFT unabhängig davon analysiert wird, was eine Voreinstellung in Ihrer Plaso-Version enthält. Wenn Sie --parsers weglassen, wählt Plaso anhand des erkannten Betriebssystems eine Voreinstellung aus; bei einem unvollständigen Triage-Ordner kann diese Erkennung scheitern, geben Sie die Parser daher selbst an.
Quellen. Eine Quelle kann ein Abbild (--partitions all oder --partitions 1,3 wählt Partitionen aus; --volumes all wählt APFS- oder LVM-Volumes aus; --vss_stores steuert Schattenkopien), ein Verzeichnis wie eine Triage-Sammlung oder eine einzelne Datei sein. Ein erneuter Aufruf von log2timeline.py mit derselben --storage-file (und derselben Plaso-Version) fügt eine neue Sitzung hinzu, sodass mehrere Quellen eine Speicherdatei gemeinsam nutzen können. pinfo.py führt jede Sitzung separat auf.
Ausgabeformate und Spalten
psort.py -o dynamic schreibt CSV mit diesen Standardspalten (andere wählen Sie mit --fields aus):
| Spalte | Inhalt |
|---|---|
datetime | Ereigniszeit in ISO 8601, in der Ausgabezeitzone |
timestamp_desc | Bedeutung dieses Zeitstempels |
source / source_long | Kurzer und langer Quelltyp, etwa FILE oder WEBHIST und eine längere Beschreibung |
message | Menschenlesbare Ereignisbeschreibung |
parser | Parser-Kette, etwa mft oder sqlite/chrome_27_history |
display_name | Die Datei, aus der das Ereignis stammt, wie Plaso sie gesehen hat |
tag | Von Analyse-Plugins oder vom Analysten hinzugefügte Kennzeichnungen |
timestamp_desc ist die entscheidende Spalte. Dieselbe Datei kann Ereignisse für „Erstellungszeit“, „Inhaltsänderungszeit“, „Letzte Zugriffszeit“ und „Metadatenänderungszeit“ erzeugen. Ein Browserverlauf erzeugt „Letzte Besuchszeit“; eine Prefetch-Datei erzeugt „Letzte Ausführungszeit“. Lesen Sie diese Spalte immer, bevor Sie angeben, was ein Zeitstempel beweist.
-o l2tcsv ist das ältere log2timeline-Format mit 17 festen Feldern (date,time,timezone,MACB,source,sourcetype,type,user,host,short,desc,version,filename,inode,notes,format,extra). -o json_line schreibt ein JSON-Objekt je Ereignis und eignet sich für Skripte und Suchplattformen.
Zeitzone. Plaso speichert UTC. Die Ausgabe erfolgt standardmäßig in UTC; --output_time_zone UTC macht dies in Ihren Notizen ausdrücklich deutlich. Manche Quellen speichern lokale Zeit ohne Zeitzone, etwa FAT-Zeitstempel; log2timeline.py --timezone teilt Plaso mit, welche Zeitzone bei deren Extraktion anzunehmen ist. Lektion 3.5 behandelt Zeitzonenfehler ausführlich.
Datenmenge und Stördaten: zuerst die Fragestellung
Millionen von Zeilen lassen sich nicht vollständig lesen, und ein Excel-Arbeitsblatt endet bei 1.048.576 Zeilen. Gehen Sie in dieser Reihenfolge vor:
- Definieren Sie die Fragestellung und das Zeitfenster, bevor Sie
psort.pyausführen, zum Beispiel „Was geschah in den zwei Stunden um den USB-Anschluss herum?“ Entnehmen Sie den zeitlichen Anker einem präzisen Artefakt (Lektion 2.6). - Filtern Sie nach Zeit mit einem Ereignisfilter:
"date > DATETIME('2026-03-14T08:30:00') AND date < DATETIME('2026-03-14T10:30:00')". Geben Sie Filterzeiten in UTC an. - Filtern Sie nach Quelle mit
data_type, zum Beispiel"data_type contains 'chrome'", oder extrahieren Sie nur mit den benötigten Parsern. - Suchen Sie nach Schlüsselwörtern wie einem Dateinamen oder einer Seriennummer.
- Prüfen Sie die Ergebnisse in einem CSV-Betrachter wie Timeline Explorer, bei kleinen Zeitfenstern in einer Tabellenkalkulation oder auf einer kollaborativen Plattform wie Timesketch, die
.plaso-Dateien direkt importiert.
Duplikate, etwa ein Ereignis, das in einem Volume und dessen Schattenkopie vorkommt, werden standardmäßig zusammengeführt; -a (--include_all) behält sie bei.
Triage-Sammlungen: Kopierzeitpunkte sind keine Beweise
Dies ist der wichtigste Vorbehalt in dieser Lektion. Eine Triage-Sammlung ist ein Satz von Dateien, die unter Beibehaltung ihrer ursprünglichen Pfade vom laufenden System in einen Ordner (oder einen Container) kopiert wurden. Wenn Plaso diesen Ordner verarbeitet, liest der Parser filestat die aktuellen Dateisystem-Zeitstempel der Kopien auf dem Datenträger des Analysten. Sofern das Triage-Werkzeug die ursprünglichen Zeitstempel nicht erhalten hat, dokumentieren diese Werte, wann die Dateien gesammelt oder extrahiert wurden, nicht wann der Benutzer sie erstellt oder geändert hat. Selbst Werkzeuge, die Zeitstempel wiederherstellen, können $FN-Zeitstempel nicht wiederherstellen.
Die ursprünglichen NTFS-Zeitstempel bleiben in der gesammelten $MFT erhalten. Analysieren Sie diese mit dem Parser mft und schließen Sie filestat für den Triage-Ordner aus: --parsers 'win7,mft,!filestat'. Verwenden Sie einfache Anführungszeichen, da viele Shells ! innerhalb doppelter Anführungszeichen als Befehl für die Befehlshistorie behandeln. Außerdem zeigt display_name den Pfad innerhalb der Sammlung an, etwa /data/triage/C/Users/ana/...; ordnen Sie ihn in Ihrem Bericht wieder dem ursprünglichen Pfad C:\ zu.
Durchgearbeitetes Beispiel: eine Timeline, zwei Quellen
Der Fallordner /cases/c042 enthält triage/ (die Windows-Sammlung einschließlich C/$MFT) und usb.E01 (eine FAT32-Partition). Die Zeitzone des Systems, die in Lektion 2.2 aus der Registry ausgelesen wurde, ist E. South America Standard Time (America/Sao_Paulo, UTC−3). Plaso läuft im offiziellen Docker-Image, wobei der Fallordner unter /data eingebunden ist.
| Schritt | Befehl |
|---|---|
| Version dokumentieren | docker run --rm log2timeline/plaso log2timeline.py --version |
| Triage-Ordner extrahieren | docker run --rm -v /cases/c042:/data log2timeline/plaso log2timeline.py --parsers 'win7,mft,!filestat' --storage-file /data/case.plaso /data/triage |
| USB-Abbild hinzufügen | docker run --rm -v /cases/c042:/data log2timeline/plaso log2timeline.py --partitions all --timezone Europe/Lisbon --storage-file /data/case.plaso /data/usb.E01 |
| Ergebnis prüfen | docker run --rm -v /cases/c042:/data log2timeline/plaso pinfo.py -v /data/case.plaso |
| Zeitfenster ausgeben | docker run --rm -v /cases/c042:/data log2timeline/plaso psort.py --output_time_zone UTC -o dynamic -w /data/window.csv /data/case.plaso "date > '2026-03-14 08:30:00' AND date < '2026-03-14 10:30:00'" |
pinfo.py zeigt zwei Sitzungen, von null verschiedene Ereigniszahlen für mft, prefetch, chrome_27_history und filestat (nur aus der USB-Sitzung) sowie etwaige Warnungen. Sechs Zeilen aus window.csv zwischen 09:15 und 09:25Z lauten wie folgt (Meldungen gekürzt; datetime auf Sekunden gekürzt und dessen +00:00 als Z geschrieben):
| datetime | timestamp_desc | source | parser | message |
|---|---|---|---|---|
| 2026-03-14T09:15:21Z | Letzte Ausführungszeit | LOG | prefetch | EXCEL.EXE wurde ausgeführt |
| 2026-03-14T09:15:58Z | Erstellungszeit | FILE | mft | \Users\ana\AppData\Roaming\Microsoft\Windows\Recent\budget.xlsx.lnk ($SI) |
| 2026-03-14T09:18:40Z | Inhaltsänderungszeit | FILE | mft | \Users\ana\Documents\budget.xlsx ($SI) |
| 2026-03-14T09:18:40Z | Inhaltsänderungszeit | FILE | filestat | FAT:/Plans/budget.xlsx (usb.E01) |
| 2026-03-14T09:21:12Z | Erstellungszeit | FILE | filestat | FAT:/Plans/budget.xlsx (usb.E01) |
| 2026-03-14T09:23:05Z | Letzte Besuchszeit | WEBHIST | sqlite/chrome_27_history | bing.com/search?q=clear+recent+files |
Die Interpretation: Excel wurde um 09:15:21Z ausgeführt. Die um 09:15:58Z erstellte LNK-Datei kennzeichnet das erste Öffnen von budget.xlsx über diesen Pfad (Lektion 2.4). Das Dokument wurde um 09:18:40Z gespeichert. Auf dem USB-Laufwerk hat die Kopie dieselbe Änderungszeit, aber eine spätere Erstellungszeit, 09:21:12Z: das klassische Muster einer auf einen neuen Datenträger kopierten Datei, da beim Kopieren die Änderungszeit erhalten bleibt und eine neue Erstellungszeit gesetzt wird. Um 09:23:05Z suchte der Benutzer danach, wie sich die zuletzt verwendeten Dateien löschen lassen. Bevor Sie 09:21:12Z im Bericht angeben, bestätigen Sie diesen Zeitpunkt durch einen Geräteanschluss, der diesen Zeitpunkt abdeckt (Partition/Diagnostic-Ereignisse 1006, setupapi.dev.log oder USBSTOR-Anschlusszeiten), sowie durch die Volume-Seriennummer (Lektion 2.6); Lektion 3.4 behandelt diese Verknüpfung von Spuren.
Dokumentation für Wiederholbarkeit
Dokumentieren Sie, wie die Timeline erstellt wurde: die Plaso-Version (und den Tag oder Digest des Docker-Images), jede Befehlszeile, die Parser-Liste, die Zeitzoneneinstellungen, den Hash jeder Quelle und die Ausgabe von pinfo.py. Die Speicherdatei hält jede Extraktionsbefehlszeile fest, Ihre Notizen müssen jedoch auch die psort-Filter abdecken. ISO/IEC 27041 verlangt, dass Sie die Eignung einer Methode für die Fragestellung und ihre Validierung nachweisen. ISO/IEC 27042 verlangt, dass die Analyse wiederholbar und reproduzierbar ist. Ein auf eine bestimmte Version festgelegtes Container-Image ermöglicht es einem anderen Prüfer, dieselben Befehle erneut auszuführen und dieselben Zeilen zu erhalten.
Prüfungsschwerpunkt: Rechnen Sie damit, eine UTC-Zeit aus einer Timeline-Zeile angeben zu müssen; lesen Sie dahertimestamp_descund den Parser, bevor Sie entscheiden, was der Zeitstempel beweist. Sie sollten wissen, dass die Dateisystem-Zeitstempel von Dateien in einer Triage-Sammlung die Sammlung widerspiegeln und dass die ursprünglichen NTFS-Zeitstempel aus der gesammelten$MFTstammen. Sie sollten einen Epochenwert aus einem Bodyfile umrechnen und das Kopiermuster einer späteren Erstellungszeit gegenüber der Änderungszeit erkennen können.
Kernpunkte
- Eine Dateisystem-Timeline enthält nur Metadaten-Zeitstempel; eine Super-Timeline ergänzt Zeitstempel aus dem Inneren von Artefakten und wächst auf Millionen von Ereignissen an.
fls -r -mschreibt ein Bodyfile mit Zeitangaben in Sekunden seit der Epoche;mactime -b body -d -z UTCsortiert es in MACB-Zeilen.log2timeline.pyanalysiert Quellen und schreibt sie in eine SQLite-basierte.plaso-Datei;pinfo.pyprüft sie;psort.pyfiltert, entfernt Duplikate und schreibtdynamic,l2tcsvoderjson_line.- Schließen Sie in einem Triage-Ordner
filestataus und analysieren Sie die gesammelte$MFTmit dem Parsermft. - Definieren Sie zuerst die Fragestellung und das Zeitfenster, filtern Sie in UTC und bestätigen Sie entscheidende Zeilen anhand anderer Quellen.
- Dokumentieren Sie Versionen, Befehlszeilen, Filter und Hashes, damit ein anderer Prüfer die Timeline reproduzieren kann.