Skip to content

RecentFileCache-Manipulation erkennen

Wie Angreifer RecentFileCache.bcf unterdrücken, vergiften oder wipen — und die Event-Log-, Scheduled-Task- und Dateisystem-Signale, die sie dabei erwischen.

Veröffentlicht am 4 Min. Lesezeit

Wenn RecentFileCache.bcf für die Triage nützlich ist, ist es für einen Angreifer, der unauffällig bleiben will, auch wert unterdrückt zu werden. Dieser Post geht die vier realistischen Wege durch, das Artefakt zu manipulieren, und die Signale, die jeder davon hinterlässt.

Die vier Unterdrückungsstrategien

  1. Den Application-Experience-Dienst deaktivieren. sc stop AeLookupSvc + sc config AeLookupSvc start= disabled. Neue Ausführungen werden nicht mehr aufgezeichnet.
  2. Die geplante Aufgabe ProgramDataUpdater deaktivieren. Stoppt das periodische Neuschreiben. Existierende Einträge bleiben; neue können noch im Speicher anlaufen, werden aber nicht geflusht.
  3. Die Datei löschen. del C:\Windows\AppCompat\Programs\RecentFileCache.bcf (Elevation nötig). Bis zum nächsten ProgramDataUpdater-Lauf ist das Artefakt einfach weg.
  4. In-Memory-Ausführung. Das Artefakt gar nicht unterdrücken — nur sicherstellen, dass der Loader dich nie sieht. Reflective DLL Injection, Process Hollowing, fileless PowerShell, Missbrauch signierter LOLBins.

Jede hinterlässt einen anderen Fingerabdruck.

Signal: Service-Control-Events

Das Stoppen oder Deaktivieren von AeLookupSvc erzeugt Service-Control-Manager-Events im System-Log:

Event IDSourceWas es anzeigt
7036Service Control ManagerDienstzustandswechsel (z.B. "stopped")
7040Service Control ManagerStarttyp geändert (z.B. auto → disabled)
7045Service Control ManagerNeuer Dienst installiert (selten für AppCompat)

Jage nach AeLookupSvc im Payload-XML des Events. Auf einer gesunden Maschine startet der Dienst beim Boot und bleibt laufen; ein 7036-stopped-Event während der Geschäftszeiten ohne entsprechenden Neustart ist laut.

Get-WinEvent -LogName System -FilterXPath "*[System[(EventID=7036 or EventID=7040)]]" |
  Where-Object { $_.Message -like "*AeLookup*" } |
  Select-Object TimeCreated, Id, Message

Signal: Scheduled-Task-History

Das Deaktivieren von \Microsoft\Windows\Application Experience\ProgramDataUpdater schreibt ins Microsoft-Windows-TaskScheduler/Operational-Log:

Event IDBedeutung
141Aufgabe gelöscht
142Aufgabe deaktiviert
200Aktion gestartet
201Aktion abgeschlossen

Suche nach 141/142, die den ProgramDataUpdater-Aufgabenpfad referenzieren, oder nach einer langen Lücke zwischen 200/201-Events auf einer eingeschalteten Maschine.

Signal: Dateisystem-Zustand

Die Datei selbst verrät die Manipulation, wenn man sie aufmerksam liest:

  • LastWriteTime der Datei weit in der Vergangenheit auf einer täglich genutzten Maschine. Gesunde Systeme sehen etwa alle 24 Stunden einen Schreibvorgang. Eine .bcf, die auf einer täglich benutzten Workstation seit sechs Wochen nicht mehr geschrieben wurde, ist eine Flagge.
  • Datei komplett fehlend auf einem Win7-Endpoint, dessen Logs zeigen, dass ProgramDataUpdater zuvor lief. $LogFile und $UsnJrnl werden die Löschung festhalten; achte auf J: USN_REASON_FILE_DELETE-Events.
  • LastWriteTime der Datei passt exakt zu einem Angreifer-Zeit-Event (Korrelation mit Vorfallsfenster) — möglicherweise gezielter Flush.
  • Null oder fast null Einträge auf einer Maschine, die Monate normaler Nutzeraktivität gesehen hat. Entweder wurde die Datei kürzlich geleert, oder AeLookupSvc ist seit dem letzten Reset aus.

Signal: USN-Journal und $LogFile

Wenn RecentFileCache.bcf gelöscht oder umbenannt wurde, hält das NTFS-USN-Journal es fest. Mit usn-parser parsen:

TIMESTAMP                 REASON                              FILE
2026-05-23T14:09:11Z      FILE_DELETE | CLOSE                 RecentFileCache.bcf
2026-05-23T14:09:12Z      FILE_CREATE | CLOSE                 RecentFileCache.bcf

Ein eng beieinander liegendes Delete + Create auf derselben Datei ist der klassische "Clear by Replacement"-Zug.

$LogFile (geparst mit LogFileParser oder dem $LogFile-Modus von mft-parser) erfasst feiner-granuläre MFT-Operationen und überlebt in manchen Fällen kürzere Fenster als das USN-Journal.

Signal: Inter-Artefakt-Widersprüche

Das reichste Signal ist Uneinigkeit zwischen Artefakten:

  • Prefetch zeigt Ausführung; .bcf zeigt keinen entsprechenden Pfad. Entweder hat die Binary den Loader umgangen (in Memory), oder .bcf wurde manipuliert. Vergleiche die LastWriteTime der Datei mit der letzten Laufzeit des Prefetch.
  • Amcache hat Einträge für Executables, die nicht in .bcf sind. Normal, wenn ProgramDataUpdater sie bereits befördert hat. Verdächtig, wenn die Zeitstempel suggerieren, dass die Beförderung noch nicht hätte stattfinden dürfen.
  • .bcf existiert, enthält aber genau den 20-Byte-Header ohne Records. Ein sauberer Zustand, der natürlich nur direkt nach einem ProgramDataUpdater-Rewrite eintreten kann, ohne dass etwas neu lief — gegen die Datei-mtime und das System-Log prüfen.

Wie In-Memory-Ausführung aussieht (wenn es nichts zu sehen gibt)

Der Sinn von In-Memory-Tradecraft ist, dass keine Datei je die Platte auf eine Weise berührt, die der AppCompat-Hook des Loaders fangen kann. RecentFileCache wird völlig normal aussehen. Lies sein Schweigen nicht als Freispruch. Kombiniere mit:

  • EDR-Telemetrie zu CreateRemoteThread, WriteProcessMemory, ausführbaren Regionen ohne Backing.
  • PowerShell-4104-Script-Block-Logging (falls aktiviert).
  • Sysmon-1 (Process Create) mit den Feldern Command-Line, Parent und Image-Loaded.
  • Memory-Akquise + malfind, dlllist, ldrmodules von Volatility.

Eine kurze Hunt-Query

Detektionsregel im Tagesrhythmus, ausgedrückt in Pseudo-XQL:

service = "AeLookupSvc" AND
event_id IN (7036, 7040) AND
NOT (event_id = 7036 AND state = "running")
| stats count by host, event_id, _time
| where count > 0

Kombiniert mit einer geplanten Prüfung, dass RecentFileCache.bcf existiert und in den letzten 48 Stunden auf jedem Win7-Endpoint modifiziert wurde, fängst du die laute Hälfte der Unterdrückungsversuche. Die leise Hälfte — In-Memory-Ausführung — braucht die andere Hälfte deines Stacks.

Ende der Serie

Damit schließt der Primer. Du hast jetzt das Format, den Lebenszyklus, den Vergleichskontext, den Akquise-Workflow, die Triage-Heuristiken, die Validierungskette und die Manipulationssignale. Der Parser auf dieser Seite ist das Front-End für all das; der Rest lebt in deinem üblichen DFIR-Toolchain.

Verwandte Artikel

Der Lebenszyklus der BCF hängt an einer einzigen geplanten Aufgabe. Verstehen Sie, wann ProgramDataUpdater läuft, wann sie die Datei leert und wie Sie einen deaktivierten Appraiser erkennen.
Das BCF-Format ist ein Header, eine Liste von längen-präfixierten UTF-16LE-Pfaden, und das war's. Hier ist, was jedes Byte bedeutet und warum sich seit 2009 nichts geändert hat.
Ein vom SOC markierter Win7 Endpoint, 14 Pfade in der BCF, drei einer zweiten Betrachtung wert. Eine realistische Korroborationskette und wie viel die BCF tatsächlich beigetragen hat.