Amcache FileId explicado: el formato de hash SHA-1 que almacena Windows
El valor FileId en Root\InventoryApplicationFile es uno de los
campos más útiles de todo el hive Amcache — y uno de los más
malentendidos. Es el hash de contenido del archivo, pero no es del
todo un SHA-1 estándar, y no hashea del todo el archivo
completo. Este post es la referencia completa: qué es el valor,
cómo usarlo y las trampas que cazan a los analistas nuevos.
Para la referencia más amplia de Amcache, ver la referencia completa de Amcache; para la estructura del registro circundante, ver Estructura del registro Amcache.
Cómo se ve el valor#
Un FileId típico de un hive real:
0000da39a3ee5e6b4b0d3255bfef95601890afd80709
41 caracteres en total:
- Los primeros 4 caracteres son siempre
"0000"— una etiqueta de tipo fija. - Los 40 caracteres restantes son el digest hex SHA-1 del archivo.
El prefijo "0000" es un artefacto histórico: las primeras
versiones del appraiser anticipaban múltiples algoritmos de hash
(con cada prefijo indicando cuál) pero en la práctica solo se llegó
a usar SHA-1. Hoy el prefijo es constante.
Cuando AmcacheParser expone este campo en su CSV, lo divide en dos columnas:
| Columna | Valor |
|---|---|
FileId |
La cadena completa de 41 caracteres, prefijo incluido. |
Hash |
Solo los 40 caracteres hexadecimales — el SHA-1 solo. |
Usa siempre Hash (o quita el prefijo tú mismo) cuando hagas
joins contra feeds externos de hash. VirusTotal, tus feeds de TI
y las bases de datos de allowlist de hash esperan un SHA-1 de 40
caracteres — no coincidirá con nada si incluyes el prefijo
"0000".
Qué hashea realmente#
Esta es la trampa que caza a casi todo analista nuevo de Amcache:
El SHA-1 de Amcache hashea los primeros 31 MiB del archivo, no el archivo completo.
Para archivos menores de 31 MiB (que es casi todo — la mayoría de EXEs y DLLs están muy por debajo), el hash de prefijo equivale al SHA-1 del archivo completo. Son indistinguibles entre sí.
Para archivos mayores de 31 MiB, el hash de Amcache es un hash
de prefijo, no un hash de contenido completo. Sigue siendo lo
bastante distintivo para identificar un build específico de un
binario específico, pero no es el mismo valor que obtendrías con
sha1sum sobre el archivo completo.
Por qué esto importa#
- Coincidencias en VirusTotal. Para archivos por debajo de 31 MiB, el SHA-1 de Amcache coincide con el SHA-1 que VirusTotal indexa. Para archivos más grandes (instaladores, algunos binarios de juegos, software empresarial grande) no coincidirá, y una respuesta de "sin registro" de VirusTotal no significa nada.
- Bases de datos personalizadas de hash. Si mantienes una allowlist interna de hashes conocidos como buenos, asegúrate de estar almacenando el mismo tipo de hash con el que vas a comparar. O almacena SHA-1 de contenido completo (y acepta que las comparaciones con Amcache para binarios grandes fallarán) o mantén una columna paralela de hash de prefijo.
- Recompilar para verificación. Si tienes el binario original a mano y quieres verificar que un hash de Amcache coincide, hashea solo los primeros 31 MiB:
import hashlib
PREFIX_BYTES = 31 * 1024 * 1024 # 31 MiB
def amcache_sha1(path: str) -> str:
h = hashlib.sha1()
with open(path, 'rb') as f:
h.update(f.read(PREFIX_BYTES))
return h.hexdigest()Trampas del mundo real#
Un puñado de obstáculos que aparecen en casos reales:
No incluyas el prefijo "0000" en las búsquedas#
# Mal
search_virustotal('0000da39a3ee5e6b4b0d3255bfef95601890afd80709')
# Bien
search_virustotal('da39a3ee5e6b4b0d3255bfef95601890afd80709')La API de VirusTotal espera específicamente el hash desnudo. Incluir el prefijo devuelve un resultado vacío silenciosamente — lo que se ve idéntico a "este archivo es desconocido" y es mucho más engañoso.
Las colisiones de hash son teóricas pero no imposibles#
SHA-1 tiene ataques de colisión conocidos. En un contexto no adversarial esto es irrelevante — encontrar una colisión SHA-1 contra una entrada específica de Amcache requiere un esfuerzo desproporcionadamente mayor al que gana un atacante. Pero para coincidencias de alta confianza en una investigación de altas apuestas, no trates una coincidencia SHA-1 como identidad criptográfica. Empareja con tamaño del archivo, fecha de link y al menos otro campo.
No confíes en el FileId de una fila con IsPeFile = False#
Amcache ocasionalmente registra valores FileId para archivos no-PE
inventariados por el appraiser. El hash sigue siendo real, pero el
contexto es diferente — está hasheando lo que sea el archivo (un
script, un archivo de configuración), y las herramientas downstream
que asumen contexto de archivo PE (búsquedas PE-aware de
VirusTotal, reglas Yara contra bytes PE) devolverán resultados menos
útiles.
Múltiples filas, mismo hash#
Si encuentras el mismo valor Hash en múltiples filas
*_UnassociatedFileEntries.csv en el mismo host, eso es
significativo. Significa que el mismo contenido binario fue
inventariado en múltiples rutas. Razones comunes:
- El atacante copió una herramienta a varias ubicaciones para probar cuál ejecutaría.
- Un instalador legítimo dejó la misma DLL en múltiples directorios de productos.
- Un usuario copió un archivo manualmente.
Agrupa por Hash, luego mira el conjunto de FullPath y
KeyLastWriteTimestamp para cada instancia. Las marcas de tiempo
te dicen la secuencia de copias; las rutas te dicen la intención.
Múltiples hashes, mismo FullPath#
El patrón opuesto — la misma ruta con diferentes valores Hash en
múltiples filas — significa que el binario en esa ruta cambió
entre inventarios. Esta es una señal fuerte de reemplazo binario:
- Legítimo: una actualización de software sobrescribió el archivo.
- Sospechoso: un atacante reemplazó un binario del sistema o una herramienta de usuario que se ejecuta regularmente con una copia troyanizada.
Ordena las filas por KeyLastWriteTimestamp para ver cuándo
apareció cada nuevo hash, luego correlaciona con eventos de parche
o eventos de Sysmon File Create alrededor de esos momentos.
Pivotes que usan FileId / Hash#
Los pivotes que se ganan su trabajo en casos reales:
Caza de hash entre hosts#
# Pivotar un SHA-1 conocido como malicioso a través del CSV Amcache de cada host
$badHash = 'da39a3ee5e6b4b0d3255bfef95601890afd80709'
Get-ChildItem -Recurse -Filter *_UnassociatedFileEntries.csv |
ForEach-Object {
Import-Csv $_.FullName |
Where-Object { $_.Hash -eq $badHash } |
Select-Object @{n='Host';e={$_.PSChildName.Split('_')[0]}},
FullPath, KeyLastWriteTimestamp, Size
} |
Sort-Object HostAsí pasas de "encontramos este hash en un host" a "dime cada host del entorno que ha tenido alguna vez este binario presente, y cuándo apareció."
Enriquecimiento con VirusTotal de un CSV#
import csv, requests, time
API = 'https://www.virustotal.com/api/v3/files/'
HEADERS = {'x-apikey': '<your-key>'}
seen = set()
with open('HOST_amcache_UnassociatedFileEntries.csv', newline='') as f:
for row in csv.DictReader(f):
h = row['Hash']
if not h or h in seen:
continue
seen.add(h)
r = requests.get(API + h, headers=HEADERS)
if r.status_code == 200:
stats = r.json()['data']['attributes']['last_analysis_stats']
if stats.get('malicious', 0) > 0:
print(h, stats, row['FullPath'])
time.sleep(15) # VT public API rate limitIncluso una búsqueda de bajo volumen contra la API pública produce una lista ajustada de hashes confirmados como malos en un host típico infectado.
Correlación con eventos Image Loaded de Sysmon#
El ID de evento 7 de Sysmon (Image Loaded) registra el SHA-1 de
cada DLL cargada por cada proceso. Unir Hash de Amcache al campo
Hashes del Sysmon 7 te dice exactamente qué procesos cargaron
una DLL dada del atacante, y cuándo.
Ver también#
- Referencia completa de Amcache — la visión general de alto nivel.
- Estructura del registro Amcache
— dónde se sitúa
FileIden el hive. - Amcache ProgramId explicado
— el otro identificador único en
InventoryApplicationFile. - Marcas de tiempo de Amcache explicadas
— cómo pivotar coincidencias de
FileIden el tiempo. - Columnas de salida de AmcacheParser explicadas — las columnas CSV circundantes.
¿Quieres ver los valores FileId en tu propio hive sin instalar
nada? Suelta un hive 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.
- ¿Qué es Amcache FileId? (glosario)
FileId es el identificador de 41 caracteres que Amcache almacena para cada archivo — '0000' + el SHA-1 hex de los primeros 31 MiB del archivo.
- 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.