Amcache FileId erklärt: das SHA-1-Hash-Format, das Windows speichert
FileId in Root\InventoryApplicationFile ist eines der nützlichsten Felder der ganzen Hive und eines der meistmissverstandenen. Es ist ein Inhaltshash. Es ist nicht ganz ein Standard-SHA-1. Es hasht nicht ganz die ganze Datei. Diese Seite ist die vollständige Referenz.
Für den weiteren Kontext siehe die Vollständige Amcache-Referenz. Für die umgebende Registry-Struktur innerhalb der Hive siehe Amcache-Registry-Struktur.
Wie der Wert aussieht#
Ein typisches FileId aus einer realen Hive:
0000da39a3ee5e6b4b0d3255bfef95601890afd80709
41 Zeichen insgesamt:
- Die ersten vier sind immer
"0000". Fester Typ-Tag. - Die übrigen 40 sind der SHA-1-Hex-Digest.
Das "0000"-Präfix ist ein historisches Artefakt. Frühe Appraiser-Builds rechneten mit mehreren Hash-Algorithmen mit unterschiedlichen Präfixen. Ausgeliefert wurde nur SHA-1. Das Präfix ist seit Jahren konstant.
AmcacheParser teilt das in zwei CSV-Spalten auf:
| Spalte | Wert |
|---|---|
FileId |
Voller 41-Zeichen-String mit Präfix. |
Hash |
40 Hex-Zeichen, nur SHA-1. |
Verwenden Sie immer Hash (oder streifen Sie das Präfix selbst ab), wenn Sie gegen externe Feeds joinen. VirusTotal, TI-Feeds, Allowlist-Datenbanken wollen alle 40-Zeichen-SHA-1. Sie matchen stillschweigend nichts, wenn Sie das "0000" mitsenden.
Was es tatsächlich hasht#
Die Falle, die fast jeden neuen Analysten erwischt:
Der SHA-1 hasht die ersten 31 MiB der Datei, nicht die ganze Datei.
Für Dateien kleiner als 31 MiB (was die meisten EXEs und DLLs sind), entspricht der Präfix-Hash dem Vollinhalts-SHA-1. Nicht unterscheidbar.
Für größere Dateien ist Amcaches Wert ein Präfix-Hash. Immer noch unterscheidend genug, um einen bestimmten Build einer bestimmten Binärdatei zu identifizieren. Aber es ist nicht das, was sha1sum Ihnen über die ganze Datei geben würde.
Warum das zählt#
- VirusTotal-Treffer. Unter 31 MiB matcht der Amcache-SHA-1 den SHA-1, den VT indexiert. Größere Dateien (Installer, manche Spiele-Binärdateien, große Enterprise-Software) matchen oft nicht, und eine "kein Eintrag"-Antwort von VT bedeutet nichts Nützliches.
- Eigene Hash-Datenbanken. Wenn Sie eine interne Allowlist pflegen, speichern Sie dieselbe Art Hash, gegen die Sie vergleichen wollen. Entweder Vollinhalts-SHA-1s speichern (und Mismatches bei großen Binärdateien akzeptieren) oder eine parallele Präfix-Hash-Spalte pflegen.
- Verifikation. Wenn Sie die Originalbinärdatei haben und verifizieren möchten, hashen Sie nur die ersten 31 MiB:
import hashlib
PREFIX_BYTES = 31 * 1024 * 1024
def amcache_sha1(path: str) -> str:
h = hashlib.sha1()
with open(path, 'rb') as f:
h.update(f.read(PREFIX_BYTES))
return h.hexdigest()Reale Fallen#
Eine Handvoll Stolperfallen, die in echten Fällen auftauchen.
Das Präfix nicht in Lookups einschließen#
# Falsch
search_virustotal('0000da39a3ee5e6b4b0d3255bfef95601890afd80709')
# Richtig
search_virustotal('da39a3ee5e6b4b0d3255bfef95601890afd80709')VirusTotals API erwartet den nackten Hash. Mit Präfix bekommen Sie still ein leeres Ergebnis, das identisch wie "Datei unbekannt" aussieht. Das verschwendet Triage-Zeit und produziert falsche Befunde.
SHA-1-Kollisionen sind theoretisch, aber nicht unmöglich#
Echte SHA-1-Kollisionsangriffe existieren. In einem nicht-adversarialen Kontext ist das irrelevant. Eine Kollision gegen einen bestimmten Amcache-Eintrag zu finden, ist wild unverhältnismäßig zu dem, was ein Angreifer gewinnt. Aber für ein hochzuverlässiges Matching in einer hochstand-Ermittlung sollten Sie einen SHA-1-Treffer nicht als kryptografische Identität behandeln. Mit Dateigröße, Linkdatum und mindestens einem weiteren Feld kombinieren.
Dem FileId einer Nicht-PE-Zeile nicht trauen#
Amcache erfasst gelegentlich FileId-Werte für Nicht-PE-Dateien, die der Appraiser gesehen hat. Der Hash ist immer noch echt, aber nachgelagerte Tools, die PE-Kontext annehmen (VirusTotals PE-bewusste Suchen, Yara-Regeln gegen PE-Bytes), liefern weniger nützliche Ergebnisse.
Mehrere Zeilen, gleicher Hash#
Wenn Sie denselben Hash über mehrere *_UnassociatedFileEntries.csv-Zeilen auf demselben Host finden, ist das bedeutsam. Derselbe Binärinhalt wurde an mehreren Pfaden inventarisiert. Übliche Gründe:
- Angreifer hat das Tool an mehrere Stellen kopiert, um zu testen, welcher Ort ausgeführt wird.
- Legitimer Installer hat dieselbe DLL in mehrere Produktverzeichnisse abgelegt.
- Benutzer hat eine Datei manuell herumkopiert.
Nach Hash clustern, dann FullPath und KeyLastWriteTimestamp für jede Instanz ansehen. Zeitstempel verraten die Reihenfolge. Pfade verraten die Absicht.
Mehrere Hashes, gleicher FullPath#
Das umgekehrte Muster. Gleicher Pfad, unterschiedlicher Hash über mehrere Zeilen bedeutet, dass die Binärdatei an diesem Pfad sich geändert hat zwischen Inventarisierungen. Starkes Signal für Binärersatz:
- Legitim: Software-Update hat die Datei überschrieben.
- Verdächtig: Angreifer hat eine System-Binärdatei oder ein regelmäßig genutztes User-Tool gegen eine trojanisierte Kopie getauscht.
Die Zeilen nach KeyLastWriteTimestamp sortieren, um zu sehen, wann jeder neue Hash auftauchte. Mit Patch-Events oder Sysmon-File-Create-Events um diese Zeiten korrelieren.
Pivots, die ihre Miete verdienen#
Cross-Host-Hash-Jagd#
# Einen bekannten Bad-SHA-1 über die Amcache-CSVs aller Hosts pivotieren
$badHash = 'da39a3ee5e6b4b0d3255bfef95601890afd80709'
Get-ChildItem -Recurse -Filter *_UnassociatedFileEntries.csv |
ForEach-Object {
Import-Csv $_.FullName |
Where-Object { $_.Hash -eq $badHash } |
Select @{n='Host';e={$_.PSChildName.Split('_')[0]}},
FullPath, KeyLastWriteTimestamp, Size
} |
Sort-Object HostSo gehen Sie von "wir haben diesen Hash auf einem Host gefunden" zu "jeder Host im Bestand, der je diese Binärdatei hatte".
VirusTotal-Anreicherung#
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) # Rate-Limit der öffentlichen VT-APISelbst niedrigvolumig gegen die öffentliche API liefert das eine knappe Liste bestätigt-böser Hashes auf einem typisch infizierten Host.
Sysmon-Image-Loaded-Korrelation#
Sysmon Event ID 7 zeichnet den SHA-1 jeder DLL auf, die von jedem Prozess geladen wurde. Wenn Sie Amcache Hash gegen Sysmon 7s Hashes-Feld joinen, sehen Sie genau, welche Prozesse eine gegebene Angreifer-DLL geladen haben und wann.
Weiterführende Quellen#
- VirusTotal-API-Dokumentation für den v3-Hash-Lookup-Endpunkt.
- Yogesh Khatris Amcache.hve Deep Dive.
- Das HashLookup-Projekt von CIRCL.
Verwandt#
Verwandte Beiträge
- Was ist Amcache FileId? (Glossar)
FileId ist '0000' plus der SHA-1 der ersten 31 MiB der Datei. Streifen Sie das Präfix ab, bevor Sie zu VirusTotal gehen, sonst kommt still nichts zurück.
- Beweise gelöschter Binärdateien aus Amcache wiederherstellen
Amcache überlebt die Binärdateien, die sie erfasst. Pfad, SHA-1, Herausgeber, Linkdatum und Inventarzeit halten sich monatelang, nachdem der Angreifer die Datei gewischt hat. Der praktische Workflow.
- Amcache: die vollständige forensische Referenz der Windows-.hve-Hive
Amcache ist die Hive, in die der Compatibility Appraiser jede PE-Datei auf der Platte einträgt, mit SHA-1, vollständigem Pfad, Herausgeber, Linkdatum und Key-Schreibzeit. Die Referenz, vom Format bis zur Ermittlungspraxis.
- Volatility und Amcache: die Hive aus Speicherabbildern extrahieren
Ein praktischer Leitfaden zur Wiederherstellung von Amcache aus einem Windows-Speicherabbild mit Volatility — wann speicherseitige Wiederherstellung die einzige Option ist, welche Plugins zu verwenden sind und wie an AmcacheParser übergeben wird.