Amcache FileId erklärt: das SHA-1-Hash-Format, das Windows speichert

Der FileId-Wert in Root\InventoryApplicationFile ist eines der nützlichsten Felder in der gesamten Amcache-Hive — und eines der am meisten missverstandenen. Es ist der Inhalts-Hash der Datei, aber es ist nicht ganz ein Standard-SHA-1, und es hasht nicht ganz die ganze Datei. Dieser Beitrag ist die vollständige Referenz: was der Wert ist, wie man ihn verwendet, und die Fallen, die neue Analysten erwischen.

Für die breitere Amcache-Referenz siehe die vollständige Amcache-Referenz; für die umliegende Registry-Struktur siehe Amcache-Registry-Struktur.


Wie der Wert aussieht#

Eine typische FileId aus einer echten Hive:

0000da39a3ee5e6b4b0d3255bfef95601890afd80709

Insgesamt 41 Zeichen:

  • Die ersten 4 Zeichen sind immer "0000" — ein festes Typ-Tag.
  • Die verbleibenden 40 Zeichen sind der SHA-1-Hex-Digest der Datei.

Das "0000"-Präfix ist ein historisches Artefakt: Frühe Versionen des Appraisers antizipierten mehrere Hash-Algorithmen (mit jedem Präfix, das angibt, welcher) — in der Praxis wurde aber nur SHA-1 jemals verwendet. Heute ist das Präfix konstant.

Wenn AmcacheParser dieses Feld in seiner CSV ausgibt, teilt er es in zwei Spalten auf:

Spalte Wert
FileId Der vollständige 41-Zeichen-String, Präfix inklusive.
Hash Nur die 40 Hex-Zeichen — der SHA-1 allein.

Verwenden Sie immer Hash (oder entfernen Sie das Präfix selbst), wenn Sie gegen externe Hash-Feeds joinen. VirusTotal, Ihre TI-Feeds und Hash-Allowlist-Datenbanken erwarten einen 40-Zeichen-SHA-1 — sie werden nichts matchen, wenn Sie das "0000"-Präfix einschließen.


Was es tatsächlich hasht#

Das ist die Falle, die fast jeden neuen Amcache-Analysten erwischt:

Amcaches SHA-1 hasht die ersten 31 MiB der Datei, nicht die ganze Datei.

Für Dateien kleiner als 31 MiB (das ist fast alles — die meisten EXEs und DLLs liegen deutlich darunter) entspricht der Präfix-Hash dem Volltext-SHA-1. Sie sind nicht voneinander zu unterscheiden.

Für Dateien größer als 31 MiB ist der Amcache-Hash ein Präfix-Hash, kein Volltext-Hash. Er ist immer noch unterscheidend genug, um einen bestimmten Build eines bestimmten Binärprogramms zu identifizieren, aber es ist nicht derselbe Wert, den Sie von sha1sum über die ganze Datei erhielten.

Warum das wichtig ist#

  • VirusTotal-Matches. Für Dateien unter 31 MiB stimmt der Amcache-SHA-1 mit dem SHA-1 überein, den VirusTotal indexiert. Für größere Dateien (Installer, einige Spiele-Binärdateien, große Enterprise-Software) stimmt er nicht überein, und eine „keine Aufzeichnung"-Antwort von VirusTotal ist bedeutungslos.
  • Benutzerdefinierte Hash-Datenbanken. Wenn Sie eine interne Allowlist bekannter guter Hashes pflegen, stellen Sie sicher, dass Sie dieselbe Art von Hash speichern, gegen die Sie vergleichen werden. Entweder speichern Sie Volltext-SHA-1s (und akzeptieren, dass Vergleiche großer Binärdateien gegen Amcache fehlschlagen) oder pflegen Sie eine parallele Präfix-Hash-Spalte.
  • Erneutes Hashen zur Verifikation. Wenn Sie das ursprüngliche Binärprogramm zur Hand haben und einen Amcache-Hash verifizieren möchten, hashen Sie nur die ersten 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()

Fallen aus der Praxis#

Eine Handvoll Fallstricke, die in echten Fällen auftauchen:

Schließen Sie das "0000"-Präfix nicht in Lookups ein#

# Falsch
search_virustotal('0000da39a3ee5e6b4b0d3255bfef95601890afd80709')
 
# Richtig
search_virustotal('da39a3ee5e6b4b0d3255bfef95601890afd80709')

Die API von VirusTotal erwartet ausdrücklich den blanken Hash. Das Einschließen des Präfix gibt stillschweigend ein leeres Ergebnis zurück — was identisch aussieht zu „diese Datei ist unbekannt" und weit irreführender ist.

Hash-Kollisionen sind theoretisch, aber nicht unmöglich#

SHA-1 hat bekannte Kollisionsangriffe. In einem nicht-adversarialen Kontext ist das irrelevant — eine SHA-1-Kollision gegen einen bestimmten Amcache-Eintrag zu finden, erfordert einen Aufwand, der in keinem Verhältnis zu dem steht, was ein Angreifer gewinnt. Aber für hochkonfidentes Matching in einer hochbrisanten Untersuchung behandeln Sie ein SHA-1-Match nicht als kryptografische Identität. Paaren Sie es mit Dateigröße, Linkdatum und mindestens einem weiteren Feld.

Trauen Sie der FileId einer IsPeFile = False-Zeile nicht#

Amcache zeichnet gelegentlich FileId-Werte für Nicht-PE-Dateien auf, die der Appraiser inventarisiert hat. Der Hash ist immer noch echt, aber der Kontext ist anders — er hasht, was auch immer die Datei ist (ein Skript, eine Konfigurationsdatei), und nachgelagerte Tools, die PE-Datei-Kontext annehmen (PE-bewusste Suchen von VirusTotal, Yara-Regeln gegen PE-Bytes), liefern weniger nützliche Ergebnisse.

Mehrere Zeilen, derselbe Hash#

Wenn Sie denselben Hash-Wert über mehrere Zeilen in *_UnassociatedFileEntries.csv auf demselben Host finden, ist das bedeutsam. Es bedeutet, dass derselbe Binärinhalt an mehreren Pfaden inventarisiert wurde. Häufige Gründe:

  • Der Angreifer hat ein Tool an mehrere Orte kopiert, um zu testen, welcher davon ausführen würde.
  • Ein legitimer Installer hat dieselbe DLL in mehrere Produktverzeichnisse abgelegt.
  • Ein Benutzer hat eine Datei manuell herumkopiert.

Clustern Sie nach Hash, dann schauen Sie sich das Set aus FullPath und KeyLastWriteTimestamp für jede Instanz an. Die Zeitstempel verraten Ihnen die Reihenfolge der Kopien; die Pfade verraten Ihnen die Absicht.

Mehrere Hashes, derselbe FullPath#

Das umgekehrte Muster — derselbe Pfad mit unterschiedlichen Hash-Werten über mehrere Zeilen — bedeutet, dass das Binärprogramm an diesem Pfad zwischen Inventaren geändert wurde. Das ist ein starkes Signal für Binär-Ersetzung:

  • Legitim: Ein Software-Update hat die Datei überschrieben.
  • Verdächtig: Ein Angreifer hat ein System-Binärprogramm oder ein regelmäßig ausgeführtes Benutzer-Tool durch eine trojanisierte Kopie ersetzt.

Sortieren Sie die Zeilen nach KeyLastWriteTimestamp, um zu sehen, wann jeder neue Hash erschien, und korrelieren Sie dann mit Patch-Events oder Sysmon-File Create-Events um diese Zeiten herum.


Pivots, die FileId / Hash verwenden#

Die Pivots, die ihren Schmerz in echten Fällen wert sind:

Hostübergreifende Hash-Jagd#

# Auf einen bekannten bösartigen SHA-1 über jede Host-Amcache-CSV pivotieren
$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 Host

So gelangen Sie von „Wir haben diesen Hash auf einem Host gefunden" zu „Sag mir jeden Host in der Umgebung, der dieses Binärprogramm jemals präsent hatte und wann es erschien".

VirusTotal-Anreicherung einer 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-Ratelimit

Selbst ein Lookup mit geringem Volumen gegen die öffentliche API liefert eine enge Liste bestätigt-böser Hashes auf einem typisch infizierten Host.

Korrelation mit Sysmon-Image Loaded-Events#

Sysmon-Event-ID 7 (Image Loaded) zeichnet den SHA-1 jeder DLL auf, die von jedem Prozess geladen wird. Wenn Sie den Amcache-Hash mit dem Hashes-Feld von Sysmon 7 joinen, sehen Sie genau, welche Prozesse eine bestimmte Angreifer-DLL geladen haben und wann.


Siehe auch#

Wollen Sie die FileId-Werte in Ihrer eigenen Hive sehen, ohne etwas zu installieren? Legen Sie eine Hive auf der Startseite des Parsers ab — sie parst vollständig in Ihrem Browser.

Verwandte Beiträge

Zurück zu allen Beiträgen