Amcache ProgramId erklärt: die 44-Zeichen-Anwendungsidentität
Das ProgramId-Feld in Root\InventoryApplicationFile und
Root\InventoryApplication ist Amcaches logische
Anwendungsidentität. Es ist ein 44-Zeichen-Hex-String, der eine
Anwendung eindeutig identifiziert — und entscheidend ist er
deterministisch: Dieselbe Anwendung auf einem anderen Host
erhält typischerweise dieselbe ProgramId. Das macht es zu einem
der nützlichsten hostübergreifenden Pivots im gesamten
Windows-DFIR-Werkzeugkasten.
Diese Seite ist die vollständige Referenz: was der Wert ist, wie Windows ihn konstruiert, wie man ihn in einer Einzelhost-Untersuchung verwendet und wie man ihn in einem Hunt über eine Umgebung pivotiert.
Für den breiteren Amcache-Kontext siehe die vollständige Amcache-Referenz; für die umliegende Registry-Struktur siehe Amcache-Registry-Struktur.
Wie der Wert aussieht#
Eine typische ProgramId aus einer echten Hive:
0006fa0b2a9f8a4eb9d7c81e8b1f3c5d3e2a0000ffff
44 Hex-Zeichen, kein Präfix, keine Trennzeichen. Jeder Eintrag in
InventoryApplicationFile trägt einen; jeder Eintrag in
InventoryApplication ist nach einem geschlüsselt. Die beiden
verlinken über den gemeinsamen Wert: Die ProgramId einer Datei
sagt Ihnen, zu welcher installierten Anwendung sie gehört.
Struktur der 44 Zeichen#
Der Wert ist kein einzelner einheitlicher Hash. Er kodiert mehrere Komponenten, in grober Form:
- Ein Typ- / Versions-Tag (die führenden paar Zeichen).
- Ein Hash der identifizierenden Attribute der Anwendung — primär Name, Publisher, Version und Sprache.
- Ein abschließender Diskriminator (oft
0000ffffoder ähnlich), der von Windows für die interne Klassifizierung verwendet wird.
Die genaue Konstruktion hat sich über Windows-Builds verschoben und ist von Microsoft nicht vollständig dokumentiert. Für DFIR-Zwecke sind die praktischen Regeln:
- Zwei Einträge mit derselben
ProgramIdbetreffen dieselbe Anwendung. - Die
ProgramIdist über Hosts hinweg stabil für dieselbe Anwendungs-Installation — Office 365 auf Host A und derselbe Office-365-Build auf Host B teilen eineProgramId. - Die
ProgramIdist nicht stabil über große Versions-Upgrades — ein Upgrade der Anwendung ändert in der Regel ihreProgramId.
ProgramId auf einem einzelnen Host verwenden#
Die Hauptverwendung ist das Verknüpfen einer Datei mit ihrem Anwendungsdatensatz.
Datei → Anwendung#
Sie haben eine verdächtige Zeile in
*_UnassociatedFileEntries.csv gefunden. Ihre ProgramId ist
0006fa0b2a9f8a4eb9d7c81e8b1f3c5d3e2a0000ffff.
Schlagen Sie dieselbe ProgramId in
*_AssociatedFileEntries.csv und im übergeordneten
Anwendungskatalog nach (dem Registry-Schlüssel
Root\InventoryApplication\<ProgramId> oder der äquivalenten CSV,
falls Ihr Parser eine ausgibt). Sie erhalten typischerweise:
- Den Anzeigenamen und Publisher der Anwendung.
- Das Installationsdatum.
- Die Installationsquelle (manchmal eine Download-URL).
- Die vollständige Liste der mit dieser Anwendung verknüpften Dateien.
Das ist unbezahlbar, wenn ein Angreifer ein Tool ablegt, das sich
als legitime Anwendung tarnt. Der Dateiname und die Metadaten der
Datei sagen möglicherweise „AdobeReaderUpdater.exe / Adobe Inc.",
aber ihre ProgramId passt entweder zu keinem installierten
Adobe-Produkt (verdächtig) oder passt zu einer anderen
Anwendung, als ihr Name vermuten lässt (sehr verdächtig).
Anwendung → Dateien#
Der umgekehrte Pivot ist gleichermaßen nützlich. Sie haben einen
verdächtigen Anwendungsdatensatz in InventoryApplication
gefunden — vielleicht einen portablen Build von etwas mit
Publisher "" und ungewöhnlicher Installationsquelle. Nehmen Sie
seine ProgramId und listen Sie jede Datei auf, die sie teilt:
$pid = '0006fa0b2a9f8a4eb9d7c81e8b1f3c5d3e2a0000ffff'
Import-Csv .\HOST_amcache_UnassociatedFileEntries.csv |
Where-Object { $_.ProgramId -eq $pid } |
Select-Object FullPath, Hash, KeyLastWriteTimestamp
Import-Csv .\HOST_amcache_AssociatedFileEntries.csv |
Where-Object { $_.ProgramId -eq $pid } |
Select-Object FullPath, Hash, KeyLastWriteTimestampSie erhalten den vollständigen Datei-Fußabdruck dieser Anwendung, wie der Appraiser sie sah — jede EXE, DLL und PE, die der Appraiser auf diese Anwendung zurückführte. Für Angreifer-Tooling ist das oft der schnellste Weg, das vollständige Set abgelegter Binärdateien aus einer einzelnen beobachteten Datei aufzuzählen.
Hostübergreifendes Pivotieren mit ProgramId#
Hier glänzt ProgramId als Hunt-Primitiv. Da die Identität über
Hosts hinweg stabil ist für dieselbe Anwendung, wird eine einzelne
verdächtige ProgramId auf einem Host zu einer Abfrage, die Sie
gegen die Amcache jedes anderen Hosts ausführen können:
$pid = '0006fa0b2a9f8a4eb9d7c81e8b1f3c5d3e2a0000ffff'
Get-ChildItem -Recurse -Filter *_UnassociatedFileEntries.csv |
ForEach-Object {
$rows = Import-Csv $_.FullName |
Where-Object { $_.ProgramId -eq $pid }
if ($rows) {
$host = $_.PSChildName.Split('_')[0]
foreach ($r in $rows) {
[pscustomobject]@{
Host = $host
Path = $r.FullPath
Hash = $r.Hash
When = $r.KeyLastWriteTimestamp
}
}
}
} |
Sort-Object WhenDas ist der Lateral-Movement-Pivot. Wenn ein einzelner Host eine
verdächtige ProgramId hat, sagt Ihnen diese Abfrage über Ihre
gesammelten Amcache-CSVs hinweg jeden anderen Host, auf dem
dieselbe Anwendung jemals erschienen ist, mit Pfaden und Zeiten —
in der Regel ein engeres Signal als reine Hash-Pivots, weil die
ProgramId kleine Variationen des Binärprogramms überlebt
(erneutes Signieren, Neukompilierung mit demselben
Namen/Publisher/Version).
Für das vollständige Lateral-Movement-Playbook siehe
Lateral Movement und Amcache-ProgramId-Pivoting.
Wann ProgramId am nützlichsten ist#
Ein paar Ermittlungsmuster, in denen ProgramId der richtige
Pivot ist:
Dieselbe Familie, mehrere Builds#
Ein Angreifer kompiliert sein Tool möglicherweise mehrfach mit
denselben Namens-, Publisher- und Versions-Metadaten — nur das
Binärprogramm ändert sich. Die Hashes unterscheiden sich. Die
ProgramId ist dieselbe. Hashing allein verfehlt die Familie;
ProgramId fängt sie ein.
Umbenannte Binärprogramme#
mimikatz.exe → svchost64.exe → update.exe. Der Dateiname
ändert sich; die eingebetteten PE-Metadaten sind dieselben. Wenn
der Angreifer sich nicht die Mühe gemacht hat, die Versionsinfo-
Ressource zu säubern, bleibt die ProgramId dieselbe.
Über eine Umgebung neu bereitgestellte Tools#
Der Angreifer legt dasselbe Tool auf 20 Hosts ab, während er
seitlich vorrückt. Hashes können übereinstimmen, Pfade in der Regel
nicht. Die ProgramId ist der konsistenteste Identifikator über
alle 20 Hosts.
Wann ProgramId der falsche Pivot ist#
Ein paar Fälle, in denen ProgramId unterperformt:
Tools mit rotierenden Metadaten#
Wenn der Angreifer mit jedem Mal mit anderen
Namens-/Publisher-/Versions-Werten neu kompiliert, erhält jeder
Build eine andere ProgramId. Für diese ist der
Datei-Inhalts-Hash (der SHA-1 in Hash) der bessere
hostübergreifende Pivot, weil mindestens eine Komponente des
Builds identisch ist.
Living-off-the-land-Binärprogramme#
net.exe, psexec.exe, certutil.exe — missbrauchte legitime
Tools. Jeder Host, der irgendeines davon ausgeführt hat, hat
dieselbe ProgramId dafür. ProgramId-Treffer sind hier praktisch
bedeutungslos. Pivotieren Sie stattdessen auf Kommandozeile
(4688 / Sysmon 1) oder auf den Pfad, von dem das LOLBIN
ausgeführt wurde.
Wirklich neuartige Binärprogramme#
Eine Datei, die zum allerersten Mal irgendwo auftaucht, hat eine
ProgramId, die kein anderer Host teilt. Ohne ein Korpus zum
Vergleich leistet ProgramId nichts; Hash plus
Publisher = '' and IsPeFile = True and FullPath unter \Users\
ist der funktionierende Triage-Filter.
Häufige Verwechslungen#
Zwei Dinge, die ProgramId nicht ist:
Kein Hash des Binärprogramms#
Hash (oder FileId) ist der Inhalts-Hash. ProgramId ist ein
Anwendungsidentitäts-Hash, berechnet aus Metadaten, nicht aus den
Bytes des Binärprogramms. Zwei völlig verschiedene Binärprogramme
mit identischen Metadaten erhalten dieselbe ProgramId; dasselbe
Binärprogramm, neu kompiliert mit anderen Metadaten, erhält eine
andere ProgramId.
Kein Identifikator pro Host#
Ein häufiger Fehler ist anzunehmen, dass ProgramId eine
spezifische Installation identifiziert. Tut es nicht. Wenn ein
Benutzer Notepad++ auf fünf Hosts installiert, teilen diese fünf
Hosts eine ProgramId für Notepad++. Um Installationen zu
unterscheiden, benötigen Sie Installationsdaten, -quellen oder
-pfade zusätzlich zur ProgramId.
Wo ProgramId in der Ausgabe von AmcacheParser lebt#
AmcacheParser stellt ProgramId in jeder Kategorie-CSV bereit, die
es hat:
| CSV | Verwendung von ProgramId |
|---|---|
*_UnassociatedFileEntries.csv |
Die Anwendung, zu der eine Datei sich zugehörig erklärt (auch wenn der übergeordnete Anwendungsdatensatz fehlt). |
*_AssociatedFileEntries.csv |
Die Anwendung, mit der die Datei wirklich assoziiert ist. |
*_ProgramEntries.csv |
Die eigene Identität der Anwendung (Legacy-Schema). |
*_ShortcutEntries.csv |
Die Anwendung, auf die die Verknüpfung zeigt. |
Für Pivots ist das Standardmuster: Identifizieren Sie eine
verdächtige Zeile in UnassociatedFileEntries, nehmen Sie ihre
ProgramId und führen Sie die obigen Abfragemuster aus.
Siehe auch#
- Vollständige Amcache-Referenz — die High-Level-Übersicht.
- Amcache-Registry-Struktur —
wo
ProgramIdin der Hive sitzt. - Amcache FileId erklärt — der
Inhalts-Hash-Identifikator, der
ProgramIdergänzt. - Amcache-Zeitstempel erklärt
— wie Sie Ihre
ProgramId-Pivots zeitlich eingrenzen. - Lateral Movement und Amcache-
ProgramId-Pivoting — das vollständige hostübergreifende Hunt-Playbook.
Um ProgramId-Werte in Ihrer eigenen Hive zu erkunden, ohne etwas
zu installieren, legen Sie eine Datei auf der
Startseite des Parsers ab — sie verlässt nie Ihren Browser.
Verwandte Beiträge
- 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.
- RegRipper amcache-Plugin: was es tut und wann man es verwendet
Ein praktischer Leitfaden zum amcache-Plugin von RegRipper — was es parst, wie sich seine Text-Ausgabe von AmcacheParsers CSV unterscheidet und wann man darauf zurückgreift statt (oder zusätzlich zum) Zimmerman-Tool.
- Was ist Amcache ProgramId? (Glossar)
ProgramId ist der 44-stellige Anwendungs-Identitäts-Hash, den Amcache jeder logischen Anwendung zuweist. Dieselbe ProgramId auf verschiedenen Hosts bedeutet dieselbe Anwendungsinstallation.
- AmcacheParser-Ausgabespalten erklärt: jedes CSV-Feld dekodiert
Eine Feld-für-Feld-Referenz für die CSV-Ausgabe von AmcacheParser — FileId, PathHash, ProgramId, LinkDate, BinFileVersion, IsPeFile und jede andere Spalte, mit den Pivots, die in DFIR zählen.