Volver a todos los artículos

Cómo se calcula el hash de Windows Prefetch

Un nombre como NOTEPAD.EXE-1B4A5887.pf parece sugerir que los ocho caracteres hexadecimales son una suma de control. No lo son. Son un hash de la ruta de lanzamiento del ejecutable, codificada como UTF-16, con prefijo \DEVICE\HARDDISKVOLUME{n}\. El contenido binario de notepad.exe jamás entra en el cálculo. Dos copias del binario idéntico en C:\Windows\System32\notepad.exe y C:\Users\analyst\notepad.exe producen dos archivos .pf distintos porque sus rutas difieren.

Esta es la razón completa por la que Prefetch puede distinguir psexec.exe en C:\Program Files\ de psexec.exe depositado en C:\Users\victim\AppData\Local\Temp\. El hash de ruta es el identificador por ubicación de lanzamiento.

Tres algoritmos, tres eras

La función se ha reemplazado dos veces en la historia del SO:

  • Windows XP / Server 2003. El hash original de SuperFetch. Cálculo rodante simple sobre la ruta UTF-16.
  • Windows Vista / 2008. Misma familia, multiplicador constante distinto, seed inicial distinto. Los hashes de Vista no coinciden con los de XP para la misma ruta y viceversa.
  • Windows 7 en adelante. "Hash Function 5" en la terminología de Microsoft. Todavía en uso en Windows 10 y Windows 11. Pliega grupos de bytes de la ruta UTF-16 mediante un bucle multiply-and-XOR, enmascara a 32 bits, y eso se renderiza como los ocho caracteres hexadecimales del nombre.

La cadena que se alimenta a los tres incluye un prefijo \DEVICE\HARDDISKVOLUME{n}\ y la ruta del archivo en UTF-16 LE en mayúsculas. En versiones posteriores de Windows hay algunas peculiaridades sobre cómo entran los argumentos de línea de comandos y ciertos formatos de volumen en el cálculo, pero para el caso común la ruta es exactamente lo que cabría esperar.

Por qué importa en la práctica

Un archivo Prefetch plantado es uno de los trucos antiforense más baratos: copiar un .pf de otro host al objetivo. La ruta dentro del payload SCCA es la que tenía en la máquina origen; el hash del nombre es lo que la máquina origen calculó. Un archivo plantado no tendrá un hash que case con su propia ruta embebida cuando se recalcula bajo el algoritmo del destino, especialmente entre versiones mayores de Windows.

La comprobación es mecánica:

  1. Parsea el payload SCCA.
  2. Extrae la ruta del ejecutable (el campo Executable filename más la información de volumen).
  3. Reconstruye la cadena canónica UTF-16 LE en mayúsculas con prefijo \DEVICE\HARDDISKVOLUME{n}\.
  4. Pásala por el algoritmo correspondiente al campo de versión del payload (v17 usa la función XP, v23 la de Vista, v26/v30/v31 usan Hash Function 5).
  5. Compara contra los ocho caracteres del nombre.

Una discrepancia es concluyente. O bien el archivo fue traído desde una máquina con una versión de SO distinta, o alguien lo fabricó a mano y se equivocó de algoritmo.

Cuando el hash es lo único que queda

Los payloads SCCA modernos ya no guardan una cadena de ruta cruda como lo hacía XP. Guardan el nombre del ejecutable (sin ruta), los números de serie de volumen y la lista de métricas de archivos de todo lo que el binario tocó. La pregunta "desde dónde se ejecutó esto" muchas veces hay que responderla desde el hash del nombre combinado con la sección de información de volumen. Combina esto con los registros de volumen de la MFT y los seriales de unidad de los LNK, que llevan el mismo número de serie NTFS, y normalmente puedes fijar el binario a un volumen físico o extraíble específico.

Si el binario vivía en un USB que ya fue retirado y el serial de volumen no coincide con ningún volumen del host, el hash del nombre es tu última pista. Invertir la función hash en la dirección obvia (no puedes, es unidireccional), o más útilmente, hashear las rutas candidatas desde las que crees que se ejecutó el binario y buscar coincidencia. Los profesionales mantienen pequeñas tablas de hashes esperados para ubicaciones comunes de tooling de atacantes precisamente por esto.

Notas de implementación

Implementaciones open-source de los tres algoritmos viven en la documentación de libscca de libyal y en el crate Rust frnsc-prefetch. Las funciones de Vista y Win7+ son lo bastante cortas como para inlinear, alrededor de una docena de líneas cada una, sin meter una dependencia. PECmd expone la ruta parseada; recalcular el hash a partir de ahí es un one-liner.

El parser de este sitio aún no verifica el hash automáticamente. Expone tanto la ruta del ejecutable parseada como el sufijo del nombre para que cruces a mano. Añadir un flag de discordancia está en la lista.

Lecturas adicionales

  • libyal, documentación del formato libscca: el escrito público más exhaustivo sobre los tres algoritmos.
  • Yogesh Khatri, publicaciones sobre el hashing de Prefetch entre versiones de Windows: ejemplos prácticos con vectores de prueba conocidos.