Detectando tampering de RecentFileCache
Cómo los atacantes suprimen, envenenan o limpian RecentFileCache.bcf — y las señales en event log, tareas programadas y sistema de archivos que los pillan en el acto.
Si RecentFileCache.bcf es útil para triaje, también vale la pena suprimirlo para un atacante que quiere mantenerse silencioso. Este post recorre las cuatro formas realistas de tamper el artefacto y las señales que cada una deja.
Las cuatro estrategias de supresión
- Deshabilitar el servicio Application Experience.
sc stop AeLookupSvc+sc config AeLookupSvc start= disabled. Nuevas ejecuciones dejan de registrarse. - Deshabilitar la tarea programada ProgramDataUpdater. Detiene la reescritura periódica. Las entradas existentes permanecen; las nuevas pueden seguir acumulándose en memoria pero no se flushearán.
- Borrar el archivo.
del C:\Windows\AppCompat\Programs\RecentFileCache.bcf(requiere elevación). Hasta el próximo ciclo deProgramDataUpdater, el artefacto simplemente desaparece. - Ejecución en memoria. No suprimas el artefacto en absoluto — solo asegúrate de que el loader nunca te vea. Inyección reflectiva de DLL, process hollowing, PowerShell sin archivo, abuso de LOLBins firmados.
Cada uno deja una huella diferente.
Señal: eventos de control de servicio
Detener o deshabilitar AeLookupSvc emite eventos de Service Control Manager en el log System:
| Event ID | Fuente | Qué indica |
|---|---|---|
| 7036 | Service Control Manager | Cambio de estado del servicio (e.g. "stopped") |
| 7040 | Service Control Manager | Tipo de inicio cambiado (e.g. auto → disabled) |
| 7045 | Service Control Manager | Nuevo servicio instalado (raro para AppCompat) |
Caza AeLookupSvc en el XML de payload del evento. En una máquina sana el servicio arranca al boot y se mantiene corriendo; un evento 7036-stopped en horario laboral, sin reinicio correspondiente, es ruidoso.
Get-WinEvent -LogName System -FilterXPath "*[System[(EventID=7036 or EventID=7040)]]" |
Where-Object { $_.Message -like "*AeLookup*" } |
Select-Object TimeCreated, Id, Message
Señal: historial de tareas programadas
Deshabilitar \Microsoft\Windows\Application Experience\ProgramDataUpdater escribe en el log Microsoft-Windows-TaskScheduler/Operational:
| Event ID | Significado |
|---|---|
| 141 | Tarea borrada |
| 142 | Tarea deshabilitada |
| 200 | Acción iniciada |
| 201 | Acción completada |
Busca 141/142 referenciando la ruta de la tarea ProgramDataUpdater, o un hueco largo entre eventos 200/201 en una máquina encendida.
Señal: estado del sistema de archivos
El archivo mismo delata el tampering cuando se lee con atención:
LastWriteTimedel archivo muy en el pasado en una máquina de uso diario. Sistemas sanos ven una escritura aproximadamente cada 24 horas. Un.bcfmodificado por última vez hace seis semanas en una workstation usada a diario es una bandera.- Archivo enteramente ausente en un endpoint Win7 donde los logs muestran que ProgramDataUpdater corrió antes. El
$LogFiley el$UsnJrnlregistrarán el borrado; busca eventosJ: USN_REASON_FILE_DELETE. LastWriteTimedel archivo que coincide exactamente con un evento atacante-tiempo (correlación con la ventana del incidente) — posible flush deliberado.- Cero o casi cero entradas en una máquina con meses de actividad de usuario normal. O el archivo se limpió recientemente, o
AeLookupSvcha estado apagado desde el último reset.
Señal: journal USN y $LogFile
Si RecentFileCache.bcf fue borrado o renombrado, el journal USN de NTFS lo registra. Parsea con usn-parser:
TIMESTAMP REASON FILE
2026-05-23T14:09:11Z FILE_DELETE | CLOSE RecentFileCache.bcf
2026-05-23T14:09:12Z FILE_CREATE | CLOSE RecentFileCache.bcf
Una pareja apretada delete + create sobre el mismo archivo es el clásico "clear by replacement".
$LogFile (parseado con LogFileParser o el modo $LogFile de mft-parser) captura operaciones MFT de grano más fino y sobrevive a ventanas más cortas que el journal USN en algunos casos.
Señal: contradicciones entre artefactos
La señal más rica es el desacuerdo entre artefactos:
- Prefetch muestra ejecución;
.bcfno muestra ninguna ruta correspondiente. O el binario evitó el loader (en memoria), o.bcffue tampered. Verifica elLastWriteTimedel archivo vs el último run del prefetch. - Amcache tiene entradas para ejecutables que no están en
.bcf. Normal siProgramDataUpdaterya los promovió. Sospechoso si los timestamps sugieren que la promoción aún no debería haber ocurrido. .bcfexiste pero contiene exactamente la cabecera de 20 bytes sin registros. Un estado limpio que solo puede ocurrir naturalmente justo después de queProgramDataUpdaterreescribió y nada ha vuelto a ejecutarse — verifica contra el mtime del archivo y el log System.
Cómo se ve la ejecución en memoria (cuando no hay nada que ver)
El punto del tradecraft en memoria es que ningún archivo toca el disco de manera que el hook AppCompat del loader pueda atrapar. RecentFileCache se verá totalmente normal. No leas su silencio como exoneración. Combina con:
- Telemetría EDR sobre
CreateRemoteThread,WriteProcessMemory, regiones ejecutables sin backing. - Logging de script blocks de PowerShell
4104(si está habilitado). - Sysmon
1(process create) con los campos command-line, parent e image-loaded. - Adquisición de memoria +
malfind,dlllist,ldrmodulesde Volatility.
Una pequeña query de caza
Regla de detección a cadencia diaria, expresada en 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
Combinada con una comprobación programada de que RecentFileCache.bcf existe y ha sido modificado en las últimas 48 horas en cada endpoint Win7, atraparás la mitad ruidosa de los intentos de supresión. La mitad silenciosa — ejecución en memoria — necesita la otra mitad de tu stack.
Fin de la serie
Eso cierra el primer. Ahora tienes el formato, el ciclo de vida, el contexto de comparación, el workflow de adquisición, las heurísticas de triaje, la cadena de validación y las señales de tampering. El parser de este sitio es el front-end de todo eso; el resto vive en tu toolchain DFIR habitual.