← Zurück zum Blog

Timestomping und Anti-Forensik im USN-Journal erkennen

Angreifer, die MFT-Zeitstempel bearbeiten, können sich nicht vor dem Change-Journal verstecken. Wie Abweichungen zwischen $STANDARD_INFORMATION und $FILE_NAME sowie unerwartete BasicInfoChange-Einträge anti-forensische Aktivität sichtbar machen.

4 Min. Lesezeit

Versierte Operatoren löschen nicht nur die Spuren — sie versuchen, das, was sie zurücklassen, zu tarnen. Die häufigste Technik ist Timestomping: NTFS-Zeitstempel einer Datei so editieren, dass sie unscheinbar (oder außerhalb des Untersuchungsfensters) wirkt. Früher hat das funktioniert. Mit eingeschaltetem USN-Journal hinterlässt es klare Signale.

Dieser Beitrag zeigt, was Timestomping mit der Platte macht, wie das Journal es offenlegt und welche weiteren anti-forensischen Maßnahmen man mit demselben Artefakt erwischt.

Kurze Auffrischung zu NTFS-Zeitstempeln

Jeder MFT-Eintrag führt Zeitstempel in zwei Attributen:

  • $STANDARD_INFORMATION (SI): die Zeitstempel, die Userland-Tools und die meisten APIs ändern können. Das, was dir, der Explorer und Get-ChildItem anzeigen. Format dokumentiert in der Microsoft-NTFS-Referenz.
  • $FILE_NAME (FN): die Zeitstempel, die NTFS intern in jedem $FILE_NAME-Attribut setzt. Typischerweise einer pro Name (eine Datei kann mehrere Namen haben, wenn hardlinked). Diese sind deutlich schwerer zu ändern — sie verlangen Kernel-Zugriff oder Spezialwerkzeuge.

Timestomping-Tools (SetMACE, das historische timestomp.exe aus dem Metasploit-Anti-Forensik-Modul, diverse Custom-Implants) zielen meist auf SI-Zeitstempel. Manche zielen inzwischen auch auf FN. In beiden Fällen berühren sie die $MFT — und diese Berührung lässt das Journal aufleuchten.

Was das Journal für eine Zeitstempel-Änderung aufzeichnet

Werden SI-Zeitstempel geschrieben, gibt NTFS einen BasicInfoChange | Close-Eintrag aus. Dieser Eintrag ist der rauchende Colt, weil:

  • Ein legitimer „Touch" einen BasicInfoChange | Close zusammen mit einem DataExtend oder DataOverwrite aus dem eigentlichen Schreibvorgang erzeugt, der die Zeitstempel-Aktualisierung ausgelöst hat.
  • Ein Timestomp einen nackten BasicInfoChange | Close ohne vorangehenden Schreibvorgang auf derselben FileReferenceNumber erzeugt.

Wenn du BasicInfoChange | Close ohne DataOverwrite, DataExtend oder FileCreate in derselben Handle-Session siehst, betrachtest du Metadatenmanipulation — fast immer Timestomping oder Attributänderungen (Read-Only/Hidden-Flags).

Der klassische Vergleich: SI vs FN

Die maßgeblichste Timestomping-Detektion vergleicht für jede Datei die $STANDARD_INFORMATION-Zeitstempel mit den $FILE_NAME-Zeitstempeln. Mandiant-Ermittler schreiben darüber seit Jahren; das historische Mandiant-Timestomping-Whitepaper ist die Referenz, und Brian Carrier behandelt es in File System Forensic Analysis.

Das Journal ergänzt den Vergleich, ersetzt ihn nicht:

  • Der MFT-Vergleich sagt dir, dass Timestomping irgendwann passierte. Er kann nicht sagen, wann.
  • Die BasicInfoChange | Close-Einträge des Journals sagen dir genau wann der SI-Schreibvorgang erfolgte und welcher Prozess-Kontext ihn umgab (gepaart mit Security.evtx 4663).

Eine timestompte Datei sieht in deinen Daten so aus:

  1. Der MFT-Vergleich meldet SI < FN (oder SI in der Zukunft von FN usw.).
  2. Das Journal hat einen BasicInfoChange | Close bei z. B. 2026-04-12 03:08:14 ohne umgebende Schreibvorgänge.
  3. Dieser Zeitstempel ist der, den du in den Bericht schreibst.

$LogFile und Journal sind sich uneinig über MFT-Schreibvorgänge

Das Journal hält Schreibvorgänge auf Datei-Ebene fest; $LogFile hält die zugrundeliegenden MFT-Transaktionen fest. Ein Timestomp erzeugt:

  • Eine MFT-Schreibtransaktion in $LogFile (modifiziert $STANDARD_INFORMATION des Zieleintrags).
  • Einen BasicInfoChange | Close im Journal.

Findest du eine MFT-Update-Transaktion in $LogFile ohne passenden BasicInfoChange | Close im Journal, hat der Operator vielleicht den Journal-Eintrag gelöscht — möglich über fsutil usn deletejournal gefolgt von createjournal, was eigene Spuren hinterlässt.

Weitere anti-forensische Schachzüge, die das Journal erwischt

Das Journal abschalten

fsutil usn deletejournal /D /N C: entfernt das Journal. Nach dem Aufruf:

  • Die Journal-Datei wird leer neu aufgebaut. Einträge davor sind weg.
  • Der MFT-Eintrag von $UsnJrnl wird frisch geschrieben — $LogFile zeichnet die Transaktion auf.
  • Security.evtx zeichnet — sofern SACLs gesetzt waren — einen Sensitive Privilege Use für SeRestorePrivilege oder SeManageVolumePrivilege auf.

Das Journal kann dir nicht sagen, was darin stand, aber das Abschalten ist selbst ein starkes Anti-Forensik-Signal. Siehe die Microsoft-fsutil-usn-Referenz für die Verwaltungsbefehle und ihre Privilegienanforderungen.

Alternative Datenströme

ADS-Verstecken ist älter als ich, und das Journal hält es sauber fest: ein StreamChange-Reason-Bit feuert, wenn ein alternativer Datenstrom hinzugefügt oder entfernt wird. Filter StreamChange, und alle ADS-Create/Modify-Ereignisse auf dem Volume kommen ans Licht. Falschmeldungen sind legitime Zone.Identifier-Streams aus Browser-Downloads — auch sie erzeugen StreamChange-Events, gepaart mit dem FileCreate der Originaldatei.

Hardlink-Tricks

HardLinkChange feuert, wenn Hardlinks hinzugefügt oder entfernt werden. Operatoren nutzen Hardlinks gelegentlich, um eine Datei über zwei Elternverzeichnisse erreichbar zu machen — nützlich, um pfadbasierte Kontrollen zu umgehen. HardLinkChange-Einträge verfolgen und auf FileReferenceNumber pivotieren, um alle Eltern zu sehen.

Reparse-Point-Missbrauch

Reparse Points (Junctions, Symlinks, Mount Points) können einen Pfad woanders hin umlenken. ReparsePointChange leuchtet, wenn einer hinzugefügt oder geändert wird. Suche Reparse Points in $Recycle.Bin, \Users\Default oder anderen „sollte-nicht-angefasst-werden"-Stellen.

Was du so nicht erwischst

Eine kurze Liste anti-forensischer Schachzüge, die das Journal komplett umgehen:

  • Von externem Medium booten und die Platte umschreiben — hat das laufende OS nie berührt.
  • Userland-Umschreiben mit gleicher Inhaltslänge (Overwrite am selben Offset, kein SI-Update). Erzeugt DataOverwrite-Einträge, der ursprüngliche Inhalt geht aber verloren. Das Journal sieht den Schreibvorgang, nicht, was davor stand.
  • Das Journal abschalten, bevor der Operator irgendetwas anderes tut. Das Journal kann nur aufzeichnen, was während seiner Aktivzeit geschah.

Dafür brauchst du entweder $LogFile, Shadow Copies oder Off-Host-Telemetrie. Das Journal ist ein starker Zeuge, nicht der einzige.

Ein praktischer Scan

Der schnellste Screen für Timestomping auf einem geparsten Journal:

  1. Auf Einträge mit Reason exakt BasicInfoChange | Close filtern.
  2. Für jeden die letzten 5 Minuten an Einträgen auf derselben FileReferenceNumber betrachten. Wenn weder DataOverwrite, DataExtend, FileCreate noch Rename darunter sind, markieren.
  3. Für markierte Einträge das SI-vs-FN-Delta in der MFT berechnen. Nach größtem Delta sortieren.

Oben auf der Liste steht meistens dein Timestomping. Die restlichen Einträge sind Operationen wie der Explorer, der das „Versteckt"-Attribut umlegt, oder Skripte, die Attribute anfassen — kontextabhängig, aber für eine typische Untersuchung selten interessant.