Los atacantes saben de Prefetch. Algunos intentan derrotarlo. La mayoría lo intenta y fracasa, porque las cosas que hay que hacer para suprimir Prefetch dejan sus propias marcas, y las cosas que sí se pueden suprimir solo importan si también se limpia todo lo que tocó el binario, que nadie hace por completo.
Este artículo es un repaso de las técnicas antiforense que he visto realmente usadas contra Prefetch, ordenadas según el coste para el atacante y el daño que causan a la investigación.
Deshabilitar el servicio Prefetcher
El enfoque más completo. Pon HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\PrefetchParameters\EnablePrefetcher a 0. Reinicia. Prefetch deja de escribir nuevos archivos .pf para los procesos nuevos.
Tres problemas para el atacante.
Primero, el cambio de registro en sí es ruidoso. El LastWrite de PrefetchParameters se actualiza en el momento en que se escribe el valor. Si tienes logs de transacciones del registro, snapshots VSC, o incluso una línea base del valor en el mismo host antes del incidente, el cambio es visible. El valor forense de "EnablePrefetcher se cambió justo dos horas antes de la ventana sospechosa" es alto.
Segundo, el cambio no surte efecto inmediatamente. El servicio Prefetcher cachea su estado en memoria. Las nuevas entradas Prefetch siguen escribiéndose un tiempo después del cambio de registro, normalmente hasta que se reinicia el sistema o el servicio. Un atacante que cambie el registro y lance sus herramientas treinta segundos después puede haber producido aún archivos .pf. He visto este caso más de una vez.
Tercero, el cambio no borra el directorio Prefetch existente. Todos los archivos .pf previos al cambio siguen ahí. Si el atacante no los borra también, tienes un registro de todo lo que se ejecutó en el host hasta el momento del cambio.
Detección: busca en la hive SYSTEM el LastWrite de PrefetchParameters y compáralo con tu línea de tiempo. Si el valor está en 0 o 1 (cuando la política del host dice que debería ser 3), revisa los snapshots VSC para ver cuándo ocurrió el cambio. Si encuentras un cambio dentro de la ventana sospechosa, eso mismo es un evento que merece investigación, sin importar lo que se hiciera después.
Borrar archivos .pf individuales
La técnica más común, por mucho. Tras ejecutar una herramienta, el atacante simplemente borra C:\Windows\Prefetch\TOOLNAME-XXXXXXXX.pf. Requiere privilegios de administrador (el directorio Prefetch está protegido), pero quien ejecuta herramientas de ataque suele tenerlos.
El borrado tiene éxito. El .pf desaparece. Y la evidencia obvia también.
Lo que sobrevive:
- La MFT. Cada
.pfborrado deja una entrada MFT que perdura hasta que la ranura se reutiliza. La entrada conserva el nombre del archivo, el tamaño, las marcas temporales y (si la entrada sigue residente o el borrado es reciente) a veces el contenido. Un borrado dirigido de un único.pfse quedará visible en la MFT como "archivo borrado, nombre PREFETCH/EVIL-AABBCCDD.pf" hasta que algo más reclame la entrada. - El USN journal. El borrado produce un registro USN
FILE_DELETE|CLOSEcon el nombre del.pf. En un host muy activo el journal rota, pero en la mayoría de los hosts se ven semanas de historial USN. El borrado está ahí. - Las propias marcas temporales NTFS del directorio Prefetch. La hora
Modifieddel directorio se actualiza cada vez que se añade o elimina un archivo. Si tienes una línea base, el borrado es visible. Si tienes VSCs, puedes ver el estado del directorio anterior. - Los demás artefactos que referenciaban el mismo binario. AmCache aún tiene el hash. Shimcache aún tiene el nombre del binario. La MFT aún tiene el binario si no fue también borrado. El historial de ejecución de usuario en el registro aún tiene el programa en
UserAssistoRunMRU. Prefetch es uno entre muchos.
Detección: enumera las entradas MFT borradas del directorio Prefetch. Cualquier nombre .pf en la lista de entradas borradas que no exista en el directorio vivo es un borrado. Combina con registros USN. El nombre del archivo suele darte el nombre del ejecutable; desde ahí puedes pivotar a AmCache, Shimcache y el resto.
He cerrado casos en los que el único artefacto directo de una herramienta conocida del atacante era la entrada MFT de un .pf borrado. El .pf en sí había desaparecido, pero el residuo del borrado nombraba la herramienta sin ambigüedad.
Limpiar todo el directorio Prefetch
Una versión más agresiva: borrar todo en C:\Windows\Prefetch\. Algunos atacantes lo hacen rutinariamente como parte de su limpieza.
Sobreviven los mismos residuos. La MFT ahora muestra docenas o cientos de nombres .pf borrados. El USN journal muestra los borrados en secuencia, a menudo separados por segundos. Las marcas temporales NTFS del directorio se actualizan al momento del wipe.
Un directorio Prefetch vacío (o que contiene solo NTOSBOOT-XXXXXXXX.pf, que se regenera en el arranque) en una estación de trabajo que lleva meses funcionando es una alerta enorme. El estado natural del directorio en un host con tiempo de actividad alto son cientos de archivos. Vacío significa que alguien lo vació.
Detección: cuenta las entradas en el directorio vivo y compáralas con el recuento esperado para la edad y uso del host. Directorios Prefetch vacíos o casi vacíos en hosts antiguos son anomalías que hay que explicar, no hallazgos que aceptar.
El truco de "renombrar antes de ejecutar"
El ataque inteligente. Copia tu herramienta al disco, renómbrala a algo inocuo, ejecútala, luego renómbrala de vuelta o bórrala. La idea: el nombre del .pf embebe el nombre del binario del ejecutable, así que un binario llamado update.exe produce un archivo UPDATE.EXE-XXXXXXXX.pf. Mezclándote con las entradas Prefetch existentes de update.exe del host, te escondes a plena vista.
Esto es parcialmente efectivo y muy detectable.
Lo que funciona para el atacante: el nombre del .pf es genuinamente solo el nombre del ejecutable en el momento de la ejecución. Renombra mimikatz.exe a update.exe antes de ejecutarlo y obtienes UPDATE.EXE-XXXXXXXX.pf, no MIMIKATZ.EXE-XXXXXXXX.pf. Un analista que grepee MIMI en el listado del directorio Prefetch no encontrará nada.
Lo que no funciona para el atacante:
- El hash en el nombre sigue codificando la ruta. Una mimikatz renombrada en
C:\Users\Public\update.exeproduce un hash distinto de laupdate.exelegítima enC:\Program Files\<vendor>\update.exe. Puedes detectar el nombre duplicado con dos hashes diferentes. - La lista de carga sigue delatando al binario. La mimikatz renombrada sigue cargando DLLs del estilo
sekurlsa.dlly tocando rutas adyacentes a LSASS. La Section C del.pfmostrará esas rutas independientemente del nombre del ejecutable. - La ruta del ejecutable que registra Prefetch sigue siendo la ruta real desde la que se ejecutó el binario. Incluso renombrado, el binario vive en algún sitio, y el
.pflo sabe.C:\Users\Public\update.execomo ruta Prefetch en un host dondeupdate.exedebería estar bajo Program Files ya es una anomalía en sí misma.
Detección: nunca busques solo por nombre de ejecutable. Busca en el directorio Prefetch cualquier binario cuya ruta registrada esté fuera de los directorios estándar de sistema o de programa, sin importar el nombre. El conjunto de "binarios con rutas escribibles por el usuario" en un host normal es pequeño. El truco de renombrar añade a ese conjunto; no se mezcla con él.
Modificar archivos .pf in situ
El enfoque avanzado. Algunos atacantes han escrito herramientas que editan archivos Prefetch: reducen el contador de ejecuciones, eliminan una marca temporal de ejecución, depuran una ruta de la lista de carga. He visto esto intentado dos veces en siete años de práctica.
Es muy frágil. El formato del archivo Prefetch tiene offsets internos, campos de tamaño de sección y sumas de control (en algunas versiones). Editar el contador de ejecuciones sin reescribir el resto de la estructura es factible. Editar la lista de carga requiere recalcular offsets en Section A y Section C, y rara vez se hace correctamente.
Detección: validación estructural. Pasa el archivo por un parser estricto que compruebe cada offset y longitud contra los tamaños declarados en el archivo. Herramientas como PECmd marcan archivos inconsistentes, aunque no siempre se niegan a parsearlos. Un .pf cuyos tamaños internos no suman el tamaño en disco, o cuya Section A referencia offsets de cadenas fuera de Section C, está corrupto o manipulado.
No he cazado personalmente una manipulación in situ exitosa en una investigación real. Los intentos que he visto produjeron archivos que rompían invariantes obvios. Dicho esto, la técnica es plausible para un atacante sofisticado, y no asumiría que un archivo Prefetch es canónico solo porque parsea.
Por qué Prefetch sobrevive más que Shimcache
Shimcache solo escribe al apagar. Un atacante que sabe lo que hace puede destruir Shimcache terminando el sistema bruscamente o sobrescribiendo el valor de registro AppCompatCache antes del apagado.
Prefetch escribe continuamente, como efecto secundario de la operación normal. No hay un "flush al apagar" que se pueda saltar. Para evitar que se escriba un .pf, hay que detener el servicio Prefetch antes de que se ejecute el binario, lo que requiere el cambio de registro anterior, que es de por sí ruidoso. Para eliminar un .pf después de escrito, hay que borrarlo, lo que deja residuos en MFT y USN.
Por eso confío más en Prefetch que en Shimcache para afirmaciones de ejecución. No porque Prefetch sea más preciso (Shimcache cubre más binarios en ciertos aspectos), sino porque Prefetch es más difícil de suprimir sin dejar rastro.
Contramedidas del defensor
Si trabajas en defensa, lo siguiente le complica la vida a un atacante que intente limpiar Prefetch:
- Reenvía el USN journal a un SIEM. Incluso un feed muestreado detecta borrados masivos de
.pfen segundos. - Audita escrituras de registro a
PrefetchParametersvía la política de auditoría del registro en EVTX o Sysmon EID 13. Cualquier cambio aEnablePrefetcheroEnableSuperfetchmerece alerta. - Toma snapshot del listado del directorio Prefetch cada noche. Un diff de anoche a esta mañana captura borrados masivos y creaciones masivas.
- Toma snapshot también de las bases de SRUM y AmCache. Defensa en profundidad entre artefactos de ejecución significa que un atacante tiene que limpiar cuatro cosas, no una.
- Bloquea escrituras a
C:\Windows\Prefetch\desde contextos no-SYSTEM mediante reglas WDAC o AppLocker. La mayoría de atacantes correrán como SYSTEM y lo evitarán, pero subir el listón rara vez es esfuerzo perdido.
Lo que le digo a los clientes
Prefetch es el artefacto que los atacantes más a menudo creen haber limpiado y más a menudo no han limpiado. La técnica que sí funciona (deshabilitar, ejecutar, rehabilitar) es la más costosa operativamente, exige timing de reinicio y es la más detectable mediante seguimiento de cambios de registro. La técnica más popular (borrar el .pf tras la ejecución) deja el residuo del que puedes pivotar en MFT, USN y artefactos adyacentes.
Trata un directorio Prefetch vacío o recién podado no como ausencia de evidencia, sino como evidencia de intervención. Después encuentra la intervención.
Lecturas adicionales
- Eric Zimmerman, PECmd: maneja archivos malformados razonablemente bien, útil para comprobaciones de sanidad.
- Microsoft Docs, entradas de registro para parámetros Prefetch: la referencia canónica para las claves de registro relevantes.
- Harlan Carvey, Windows Registry Forensics: contexto más amplio para el lado de registro de la detección antiforense.