Marcas de tiempo de Amcache explicadas: KeyLastWriteTimestamp vs LinkDate vs el resto
Amcache expone múltiples marcas de tiempo diferentes, y confundirlas es el error más común que cometen los analistas nuevos de Amcache. Datar mal un hallazgo y toda la timeline se derrumba. Esta página es la referencia completa: cada marca de tiempo que Amcache expone, qué representa realmente y sobre cuál deberías pivotar para cualquier pregunta dada.
Para el contexto más amplio de Amcache, ver la referencia completa de Amcache; para la estructura del registro circundante, ver Estructura del registro Amcache.
Las marcas de tiempo de un vistazo#
| Marca de tiempo | Origen | Representa |
|---|---|---|
KeyLastWriteTimestamp |
Metadatos de la clave del registro | Cuándo el appraiser escribió esta entrada por última vez. Lo más cercano a "cuándo registró Amcache esto". |
LinkDate |
PE IMAGE_FILE_HEADER.TimeDateStamp |
Cuándo se compiló / enlazó el binario. Controlable por el atacante. |
InstallDate |
Valor de InventoryApplication |
Cuándo se instaló la aplicación. |
MsiInstallDate |
Valor de InventoryApplicationFile |
Cuándo se instaló el MSI padre (si lo hay). |
LastModified |
Valor del hive (depende del schema) | Un marcador de last-modified, presente en algunas versiones del schema. |
LastWriteTimestamp (legacy Programs) |
Metadatos de la clave del registro | Misma idea que KeyLastWriteTimestamp, pero para el schema legacy Root\Programs. |
La regla más importante:
KeyLastWriteTimestampes el pivote "cuándo se vio esto en este host". Todo lo demás es una pregunta diferente.
KeyLastWriteTimestamp#
Esta es la hora de última escritura a nivel del registro de la clave que contiene la entrada. Es metadato del propio hive del registro — Windows la actualiza cada vez que cambia el contenido de la clave.
Para Root\InventoryApplicationFile\<entry>, el
KeyLastWriteTimestamp se actualiza cada vez que el appraiser
escribe o actualiza esa entrada. En la práctica esto significa:
- La primera vez que el appraiser inventaría un archivo, se
crea la clave y su
KeyLastWriteTimestampes la hora del inventario. - Si los metadatos del archivo cambian entre inventarios (tamaño, hash, versión), la clave se reescribe y la marca de tiempo avanza.
- Si nada cambia entre inventarios, la marca de tiempo se queda donde está — incluso si el appraiser volvió a correr y confirmó que el archivo sigue presente.
Ese último punto importa: KeyLastWriteTimestamp no es "la
hora más reciente en que el appraiser vio este archivo". Es "la
hora más reciente en que el appraiser escribió sobre este
archivo". Para un archivo estable, sin cambios, la marca de tiempo
puede tener semanas o meses aunque el archivo haya estado presente
todo ese tiempo.
Para qué es bueno KeyLastWriteTimestamp#
- Aproximaciones de first-seen. Para un binario que el atacante
dejó nuevo en un host limpio,
KeyLastWriteTimestampes la hora de la corrida del appraiser después del drop. Sujeto a:- el appraiser no corre instantáneamente — hay hasta ~24 h de retraso en estaciones de trabajo, más largo en servidores,
- el binario debe seguir presente en la hora del appraiser (binarios transitorios borrados antes de la siguiente pasada pueden no aparecer nunca),
- la resolución de la marca de tiempo es la que escriba el appraiser — típicamente precisión de segundo.
- Joins por ventana de tiempo. Una vez que tienes una entrada
sospechosa, toma su
KeyLastWriteTimestamp± tu ventana elegida (una hora es un default común) y une todos los demás CSVs (Prefetch, Sysmon, Security 4688) sobre esa ventana. Obtienes la historia completa de lo que ocurrió alrededor del evento de inventario. - Detección de reemplazo binario. Si dos filas de
InventoryApplicationFilecomparten el mismoFullPathpero tienen diferentes valores deHashy diferentes valores deKeyLastWriteTimestamp, el binario en esa ruta cambió entre esos dos momentos. Ordena por marca de tiempo para ver la secuencia.
Para qué no es bueno KeyLastWriteTimestamp#
- "¿Cuándo existió por primera vez este binario en disco?" — esa
es una pregunta del sistema de archivos
(
$STANDARD_INFORMATION.CreationTimeen la MFT).KeyLastWriteTimestampes como mucho un límite superior: el archivo existió en disco no más tarde de la marca de tiempo, pero probablemente antes. - "¿Cuándo se ejecutó este binario?" — Amcache registra presencia, no ejecución. Usa Prefetch.
- Precisión por debajo del segundo. No saques conclusiones de unos pocos cientos de milisegundos.
LinkDate#
El TimeDateStamp del header PE — el valor que el linker estampó
en el IMAGE_FILE_HEADER del binario en hora de compilación/
enlazado. Cada PE tiene uno.
Para qué es bueno LinkDate#
- Agrupar binarios por campaña de build. Si ordenas todos los
PEs no asociados de un host por
LinkDate, ves frecuentemente clusters ajustados: 3–10 binarios todos estampados en el mismo día u hora. Eso suele ser un único atacante compilando su toolkit completo en una sola sesión. - Detectar builds sospechosamente antiguos o nuevos. Un driver compilado en 2014 que aparece por primera vez en tu Amcache hoy es una bandera de BYOVD. Un binario compilado en el futuro es una bandera de juego con el reloj o herramientas descuidadas.
- Confirmar que un build pertenece a la campaña esperada. "Nuestra herramienta interna siempre se linkdate los lunes a las 03:00 UTC; esta es el martes a las 14:00 — investigar."
Para qué no es bueno LinkDate#
- "¿Cuándo apareció este binario en este host?" Controlable por
el atacante. Un atacante puede establecer el
TimeDateStampque quiera en hora de enlazado, y a veces se establece a0deliberadamente (para builds reproducibles) o a una fecha en el pasado (para hacer parecer el binario antiguo/establecido). Confiar enLinkDatecomo pivote de presencia en el host produce hallazgos incorrectos. - Identidad criptográfica.
LinkDatepor sí solo no es único; muchos binarios comparten la misma marca de link.
InstallDate (en InventoryApplication)#
Cuándo se instaló la aplicación, en formato FILETIME del registro. Útil para:
- Cruzar con
KeyLastWriteTimestampen los registros de archivo. Si elKeyLastWriteTimestampde un archivo es significativamente más antiguo que elInstallDatede su aplicación padre, algo es inusual — el archivo parece haber estado en disco antes de que la aplicación existiera según Windows. - Detectar instalaciones silenciosas. Las aplicaciones
instaladas sin interacción del usuario a veces dejan
InstallDatecerca de 1601-01-01 (la época FILETIME) o en fechas futuras poco realistas. Ambas son banderas.
MsiInstallDate (en InventoryApplicationFile)#
La fecha de instalación del MSI padre para archivos que vinieron de
un instalador MSI. Mismo formato FILETIME que InstallDate. Útil
para distinguir archivos que llegaron vía una instalación MSI
correcta de archivos que llegaron vía copia / drop.
LastModified (cuando está presente)#
Algunas versiones del schema de Amcache exponen un valor
LastModified por archivo. No todos los hives lo tienen. Cuando
está presente, trátalo como el tiempo de última modificación del
sistema de archivos tal como el appraiser lo vio en el
inventario — no como autoritativo. El $STANDARD_INFORMATION de
la MFT es la fuente autoritativa.
LastWriteTimestamp en Programs legacy#
El schema legacy Root\Programs expone un LastWriteTimestamp por
entrada que es conceptualmente idéntico a KeyLastWriteTimestamp
en el schema moderno. Aplican las mismas advertencias.
El pivote estándar acotado en el tiempo#
El patrón de investigación en el que la mayoría de los analistas se estandarizan:
- Identifica una fila sospechosa en
*_UnassociatedFileEntries.csv(típicamente vía "PE sin firmar en ruta escribible por usuario"). - Toma su
KeyLastWriteTimestamp. - Define una ventana de una hora centrada en esa marca de tiempo.
- Extrae de esa ventana:
- Todas las demás filas de Amcache (cross-key — drivers, dispositivos, accesos directos).
- Todas las entradas de Prefetch (ejecución definitiva).
- Todos los eventos de creación de proceso Security 4688.
- Todos los eventos de Sysmon
1(process create),7(image load) y11(file create). - Todas las creaciones del sistema de archivos desde la MFT y el journal USN.
- La timeline resultante es la imagen completa de lo que ocurrió alrededor de ese evento de inventario.
Este es el join canónico "¿qué estaba haciendo el atacante en este
minuto?", y KeyLastWriteTimestamp es el ancla que lo hace
posible.
Un ejemplo trabajado#
Ves dos filas de Amcache para la misma ruta:
FullPath: C:\Users\bob\AppData\Local\Temp\notepad.exe
Row A: KeyLastWriteTimestamp = 2026-03-12 14:23:11 UTC
Hash = aaaaaaaa...
LinkDate = 2018-04-03 09:00:00 UTC
Publisher = ""
Row B: KeyLastWriteTimestamp = 2026-04-19 02:14:55 UTC
Hash = bbbbbbbb...
LinkDate = 2018-04-03 09:00:00 UTC
Publisher = ""
Leyendo esto:
LinkDatees idéntico. Ese es elTimeDateStampen el header PE — el atacante reutilizó la misma identidad de build, o usó una plantilla que linkstampa cada build igual. No es evidencia de hora de build.Hashdifiere. Diferente contenido de archivo estuvo en la ruta en los dos momentosKeyLastWriteTimestamp.KeyLastWriteTimestampdifiere. Amcache vio la ruta dos veces, con ~5 semanas de diferencia, con contenido diferente cada vez.
Conclusión: un binario en esta ruta fue reemplazado entre el 12 de marzo y el 19 de abril. Pivota sobre la marca de tiempo del 19 de abril ± 1 h para el evento de drop del nuevo binario; pivota sobre el 12 de marzo ± 1 h para el drop original. Dos eventos de intrusión; una ruta; una entrada de Amcache para encontrar ambos.
Ver también#
- Referencia completa de Amcache — la visión general de alto nivel.
- Estructura del registro Amcache — dónde se sitúa cada marca de tiempo en el hive.
- Amcache FileId explicado — el pivote de hash de contenido que se empareja con las marcas de tiempo.
- Amcache ProgramId explicado — el pivote de identidad de aplicación.
- Columnas de salida de AmcacheParser explicadas — cada campo CSV, en contexto.
Para explorar marcas de tiempo en tu propio hive sin instalar nada, suelta un archivo en la página de inicio del parser — se parsea enteramente en tu navegador.
Artículos relacionados
- Volatility y Amcache: extraer el hive de imágenes de memoria
Una guía práctica para recuperar Amcache de una imagen de memoria de Windows usando Volatility — cuándo la recuperación del lado de memoria es la única opción, qué plugins usar y cómo entregar a AmcacheParser.
- Plugin amcache de RegRipper: qué hace y cuándo usarlo
Una guía práctica del plugin amcache de RegRipper — qué parsea, en qué se diferencia su salida de texto del CSV de AmcacheParser y cuándo recurrir a él en lugar de (o junto con) la herramienta de Zimmerman.
- Las columnas de salida de AmcacheParser explicadas: cada campo CSV decodificado
Referencia campo por campo para la salida CSV de AmcacheParser — FileId, PathHash, ProgramId, LinkDate, BinFileVersion, IsPeFile y cualquier otra columna, con los pivotes que importan en DFIR.
- Guía de descarga de AmcacheParser: fuentes oficiales, mirrors y verificación
Todas las formas de descargar AmcacheParser de Eric Zimmerman — Get-ZimmermanTools, descarga directa, KAPE, Velociraptor — con verificación por suma de control y patrones de instalación en redes aisladas.