Zurück zu allen Beiträgen

Die Liste der Zeitstempel in einer .pf-Datei ist das, was die meisten Analysten lesen. Die Liste der vom Executable berührten Dateien ist das, was sie überfliegen. Diese Reihenfolge ist falsch herum, und ich habe mehr als eine Untersuchung aus Mustern aufgebaut, die ich in der Load-Liste fand und die die Zeitstempel allein nie hätten zutage fördern können.

In diesem Beitrag geht es darum, das Resources-Array zu lesen. Was es erfasst. Was nicht. Und die drei oder vier Formen, die Ihnen sagen, dass etwas nicht stimmt, sobald Sie die richtige Spalte richtig sortieren.

Was die Load-Liste tatsächlich enthält

Der Prefetch-Dienst beobachtet die ersten zehn Sekunden der Lebenszeit eines Prozesses. Jede Datei, für die der Kernel während dieses Fensters einen Pfad auflöst, landet im File-Metrics-Array, mit dem tatsächlichen Pfad als UTF-16LE-String in Section C. Wenn Sie die geparsten Ergebnisse lesen, sehen diese aufgelösten Pfade aus wie \DEVICE\HARDDISKVOLUME2\Windows\System32\kernel32.dll und \DEVICE\HARDDISKVOLUME2\Users\bob\Documents\contract.docx.

Das ist breiter als „geladene DLLs". Es umfasst:

  • Alle DLLs, die der Prozess der Binärdatei geladen hat, einschließlich Delay-Loaded, sofern der Ladevorgang innerhalb des Trace-Fensters geschieht.
  • Vom Prozess (im Sinne von CreateFile) geöffnete Dateien. Insbesondere Lesevorgänge, weil Windows Page Faults verfolgt; einige Schreibvorgänge auch, abhängig von der Version.
  • Konfigurationsdateien, Datendateien, Dokumentdateien, Registry-Hive-Dateien, wenn der Prozess sie direkt über das Dateisystem öffnet statt über die Registry-API.
  • DLLs und Dateien, die von Kindprozessen berührt werden, die die Binärdatei in ihren ersten zehn Sekunden gestartet hat, auf manchen Windows-Builds.

Die Obergrenze liegt bei etwa 1024 Einträgen pro .pf-Datei. Bei sehr geschwätzigen Binärdateien stoßen Sie an die Grenze und der Rest fällt weg. Bei den meisten erhalten Sie die vollständige Menge.

Das Trace-Fenster ist auf etwa zehn Sekunden festgelegt. Eine Binärdatei, die dreißig Sekunden ruhig bleibt und dann ihre echte Nutzlast lädt, hat eine irreführend kleine Load-Liste, weil die Schwerstarbeit außerhalb des Fensters geschah.

Was sie nicht enthält

Schreibvorgänge werden teilweise, aber nicht verlässlich aufgezeichnet. Dateien, die der Prozess erstellt und dann nie wieder geöffnet hat, stehen vielleicht nicht in der Liste. Wenn Sie eine vollständige Aufzeichnung geschriebener Dateien brauchen, brauchen Sie Sysmon Event ID 11 in EVTX oder das USN-Journal.

Die Befehlszeile steht nicht in der Load-Liste. Die an das Executable übergebenen Argumente stehen in keinem Teil der Prefetch-Datei. Wenn die Binärdatei ihre Argumente las und dann basierend darauf Dateien öffnete, erscheinen die resultierenden Pfade. Die Argumente selbst nicht.

Netzwerk-Sockets stehen nicht in der Load-Liste. Prefetch ist ein Dateisystem-Artefakt.

Kinder, die außerhalb des Zehn-Sekunden-Fensters gestartet werden, stehen nicht in der Load-Liste des Elternteils, obwohl sie eigene .pf-Dateien erhalten (vorbehaltlich der üblichen SSD/Server-Einschränkungen).

Muster eins: DLL-Search-Order-Hijacking

Das klassische Erkennungsmuster. Eine vertrauenswürdige Binärdatei wie winword.exe oder mstsc.exe sollte ihre DLLs aus \System32\ laden (und einer kleinen Zahl gut bekannter Verzeichnisse). Eine .pf, deren Load-Liste zeigt, wie die vertrauenswürdige Binärdatei version.dll oder cryptbase.dll aus \AppData\Local\Temp\ oder \Users\Public\ lädt, ist ein Search-Order-Hijack, bis das Gegenteil bewiesen ist.

Die Formen, auf die Sie achten sollten:

\DEVICE\HARDDISKVOLUME2\WINDOWS\SYSTEM32\KERNEL32.DLL    <- normal
\DEVICE\HARDDISKVOLUME2\USERS\PUBLIC\VERSION.DLL          <- nicht normal

In Ermangelung einer bekannt guten Baseline gilt: System-DLLs, die von irgendwo anders als aus \Windows\System32\ (oder \SysWOW64\ für 32-Bit-Prozesse oder \Program Files\<Hersteller>\ für die eigenen, herstellereigenen DLLs) geladen werden, verdienen einen genaueren Blick. Einige davon werden legitime Side-by-Side-Assemblies sein. Die meisten nicht.

Sortieren Sie die Load-Liste nach Pfad-Präfix, gruppieren Sie alles außerhalb von \Windows\ und \Program Files\ und schauen Sie sich an, was übrig bleibt. Auf einem sauberen Host wird das meiste, was übrig bleibt, die eigenen Datendateien der Binärdatei und Benutzerdokumente sein. Auf einem kompromittierten Host werden die abgelegten DLLs offensichtlich sein.

Muster zwei: Malware-Konfigurationspfade

Commodity-Malware neigt dazu, ihre Konfiguration in einer festen Position relativ zu sich selbst oder ihrem Installationsverzeichnis abzulegen. Namen wie config.bin, settings.dat, tox.lic, client.json und key.dat tauchen in Load-Listen mit deprimierender Regelmäßigkeit auf. Der Pfad liegt meist unter \AppData\Roaming\<irgendein Ordner>\, \ProgramData\<irgendein Ordner>\ oder direkt neben der Binärdatei.

Zwei Dinge gibt Ihnen das. Erstens die Existenz einer Konfigurationsdatei an einem bestimmten Pfad zu einer bestimmten Zeit, auch wenn die Datei inzwischen gelöscht ist. Zweitens einen Namen, nach dem Sie den Rest des Hosts durchsuchen können: Wenn \AppData\Roaming\nzhxxk\config.bin in einer .pf-Load-Liste steht, können Sie zu der MFT, dem USN-Journal und der Registry pivotieren, um herauszufinden, wann die Konfiguration geschrieben, geändert und gelöscht wurde.

Ich habe Timelines gebaut, in denen die Prefetch-Load-Liste das Einzige war, was mir sagte, dass je eine Config-Datei existiert hatte. Die Datei war weg, das Verzeichnis war weg, und der einzige überlebende Beweis war der in eine .pf Section C eingebackene Pfad-String.

Muster drei: Dokumentöffnungen

Wenn die Frage lautet „hat dieser Benutzer dieses Dokument geöffnet", kann Prefetch untermauern. Eine .pf für winword.exe oder acrord32.exe, deren Load-Liste \Users\<Benutzer>\Documents\<Dokumentname> oder \Users\<Benutzer>\Downloads\<Dokumentname> enthält, sagt, dass die Anwendung diese Datei während einer ihrer verfolgten Ausführungen geöffnet hat.

Die Vorbehalte: Die Load-Liste sagt Ihnen nicht, welcher Lauf welche Datei geöffnet hat. Wenn die .pf acht Ausführungszeiten zeigt und die Load-Liste drei Dokumente, können Sie nicht direkt zuordnen „Dokument X wurde während Lauf Y geöffnet". Die Liste ist kumulativ über das Trace-Fenster der jüngsten Läufe, wobei ältere Einträge überschrieben werden, sobald die Binärdatei erneut getraced wird.

Für Dokumentöffnungen pro Instanz kombinieren Sie die Prefetch-Belege mit LNK-Dateien, Jump Lists und Offices eigenen MRU-Listen in der Registry. Der Prefetch-Eintrag bestätigt, dass der Dateipfad vom Prozess aufgelöst wurde; die per-User-Artefakte sagen Ihnen, wann und woher der Benutzer ihn aufgerufen hat.

Muster vier: Konfigurations-Disclosure von legitimen Binärdateien

Dieses kommt häufiger in Insider-Threat- und Geistiges-Eigentum-Fällen vor als bei Malware, aber es ist erwähnenswert.

Wenn ein Prozess eine Datei berührt, geht dieser Pfad in die Load-Liste, egal ob die Datei sensibel ist oder nicht. Wenn ein Skript findstr.exe über ein HR-Verzeichnis laufen ließ, zeichnet die .pf für findstr.exe die aufgelösten Pfade der tatsächlich geöffneten Dateien auf. Dasselbe für tar.exe, 7z.exe, xcopy.exe und jedes andere Archiv- oder Kopier-Tool.

Was das in der Praxis bedeutet: Wenn Sie Datenexfiltration unter Verwendung eines bekannten Tools vermuten, ziehen Sie die .pf für dieses Tool und schauen Sie sich die Load-Liste an. Die Dateien, die das Tool berührt hat, werden dort sein. Sie erhalten keine Befehlszeilenargumente, aber eine teilweise Aufzählung der beteiligten Dateien.

Das Muster ist auch zur Erkennung von Reconnaissance nützlich. Eine .pf für whoami.exe oder net.exe ist auf den meisten Hosts normal; eine .pf für nltest.exe mit \Windows\debug\-Pfaden in der Load-Liste ist Reconnaissance, bis das Gegenteil bewiesen ist. Die Load-Liste sagt Ihnen, was das Tool tatsächlich abgefragt hat.

Muster fünf: Temp-Verzeichnis-Archäologie

Die Verzeichnisse \AppData\Local\Temp\ und \Windows\Temp\ sammeln ausführbare Dateien und DLLs an, die Angreifer hinterlassen. Viele davon werden gelöscht, manchmal innerhalb von Sekunden nach ihrer Verwendung. Die .pf-Dateien der Binärdateien, die sie lesen, überleben jedoch.

Eine Prefetch-Load-Liste für rundll32.exe, die \AppData\Local\Temp\evil.dll zeigt, sagt Ihnen, dass diese DLL von rundll32.exe geladen wurde, die DLL zu diesem Moment an diesem Pfad war und (da die .pf für rundll32.exe bei jedem Lauf aktualisiert wird) eine jüngste Ausführung von rundll32 genau das tat. Wenn die Datei nicht mehr da ist, haben Sie Belege für ihre frühere Existenz und Verwendung.

Kombinieren Sie mit den Pfad-Auflösungs-Zeitstempeln der Load-Liste (Startfeldern in Section A) und Sie können die Ladevorgänge innerhalb des Trace-Fensters manchmal ordnen. Die Granularität ist nicht großartig, aber es reicht, um „sofort beim Start geladen" von „gegen Ende des Trace-Fensters geladen" zu unterscheiden.

Effizient mit der Load-Liste arbeiten

Ein Workflow, der sich auszahlt:

  1. Parsen Sie die .pf zu einer flachen CSV mit den Spalten: ausführbare Datei, Pfad, Ausführungszähler, Last Run, geladener Pfad. Eine Zeile pro (ausführbare Datei, geladener Pfad)-Paar.
  2. Filtern Sie Pfade heraus, die mit \Windows\, \Program Files\, \Program Files (x86)\ beginnen. Das ist überwiegend Rauschen auf einem Host, bei dem Sie noch keine Anomalien identifiziert haben.
  3. Sortieren Sie den Rest nach ausführbarer Datei, dann nach Pfad. Schauen Sie, was jede Binärdatei außerhalb der Standardverzeichnisse berührt hat.
  4. Für Binärdateien, die benutzerschreibbare Verzeichnisse (\AppData\, \ProgramData\, \Users\Public\, \Temp\) berührt haben, prüfen Sie, ob die Dateien noch da sind. Paaren Sie mit der MFT.
  5. Für interessante Treffer ziehen Sie die entsprechenden EVTX-Sysmon-EID-11- (File Create) oder EID-7- (Image Load) -Einträge zur Bestätigung.

Schritt 2 ist, was die Load-Liste handhabbar macht. Ein roher Load-Listen-Dump für einen ausgelasteten Host kann hunderttausende Zeilen umfassen. Das Filtern auf Nicht-System-Pfade kürzt das auf etwas, das Sie tatsächlich lesen können.

Was die Load-Liste nicht ist

Die Load-Liste ist kein Prozessverhaltens-Log. Sie ist ein Snapshot von Pfaden, die Windows während eines kurzen Trace-Fensters aufgelöst hat. Behandeln Sie sie als Sicht auf „Dateien, die dieser Prozess berührte" mit hoher Recall und geringer Precision. Einige Einträge sind beiläufig. Einige sind Beweis. Die Kunst ist zu wissen, welches welches ist.

Die gute Nachricht ist, dass die obigen Muster über die meisten Binärdateien und Bedrohungsakteure, die ich in der Praxis gesehen habe, gelten. Sobald Sie einen Nachmittag damit verbracht haben, Load-Listen über ein paar Dutzend Prefetch-Dateien aus einer echten Intrusion zu betrachten, fangen Sie an, die Anomalien zu erkennen, bevor Sie erklären können, warum.

Weiterführende Literatur