Lateral Movement und Amcache: ProgramId-Pivoting über Hosts

Wenn Sie Angreifer-Tooling auf einem Windows-Host bestätigen, ist die nächste Frage immer: wo sonst? Lateral-Movement-Scoping — jeden anderen Host zu identifizieren, den der Angreifer erreichte — ist einer der härtesten Schritte in einer Untersuchung, und Amcache ist eines der nützlichsten Tools dafür.

Der Grund: Amcache speichert zwei hostübergreifende Pivots, die fast kein anderes Windows-Artefakt speichert:

  • Hash — der SHA-1 der ersten 31 MiB jedes PEs, das der Appraiser sah.
  • ProgramId — der 44-Zeichen-Anwendungsidentitäts-Hash, über Hosts hinweg stabil für dieselbe Anwendung.

Eine einzelne verdächtige Hash oder ProgramId auf Host A wird zu einer Abfrage, die Sie gegen die geparsten Amcache-CSVs jedes anderen Hosts ausführen können, den Sie gesammelt haben. Diese Seite ist das vollständige Playbook.

Für die Voraussetzungen siehe Vollständige Amcache-Referenz, Amcache FileId erklärt und Amcache ProgramId erklärt.


Die Sammel-Voraussetzung#

Das Muster funktioniert nur, wenn Sie Amcache von vielen Hosts gesammelt haben auf eine Weise, die es Ihnen erlaubt, über sie hinweg zu joinen. Zwei praktische Sammelmuster:

KAPE-basierte Pro-Host-Sammlung#

Verwenden Sie einen einzelnen Sammelroot mit Pro-Host-Unterordnern:

\\fileshare\incident-042\
├── HOST01\
│   └── Windows\AppCompat\Programs\Amcache.hve (+ Protokolle)
├── HOST02\
│   └── ...
├── HOST03\
│   ...

Parsen Sie mit AmcacheParser, das auf jedes Pro-Host-Verzeichnis zeigt:

Get-ChildItem '\\fileshare\incident-042' -Directory | ForEach-Object {
    $host = $_.Name
    AmcacheParser.exe `
      -f "$($_.FullName)\Windows\AppCompat\Programs\Amcache.hve" `
      --csv "\\fileshare\parsed\$host" `
      --csvf "${host}_amcache.csv" `
      --mp
}

Sie enden mit <host>_amcache_UnassociatedFileEntries.csv pro Host, alle in einem Verzeichnis.

Velociraptor-Flotten-Hunt#

Das Windows.Forensics.Amcache-Artefakt, als Hunt ausgeführt, legt geparste Pro-Host-Ausgaben auf den Velociraptor-Server. Die CSVs sind nach dem Hostnamen des Hosts benannt; dieselben unten stehenden hostübergreifenden Abfragen gelten.


Der Hash-Pivot#

Der einfachste und hochpräziseste Pivot. Sie haben einen bekannt schlechten SHA-1 von Host A; finden Sie jeden anderen Host, der ihn hat.

$badHash = 'da39a3ee5e6b4b0d3255bfef95601890afd80709'
 
Get-ChildItem -Recurse -Filter *_UnassociatedFileEntries.csv |
  ForEach-Object {
    $host = $_.PSChildName.Split('_')[0]
    Import-Csv $_.FullName |
      Where-Object { $_.Hash -eq $badHash } |
      Select-Object @{n='Host';e={$host}}, FullPath, KeyLastWriteTimestamp, Size
  } |
  Sort-Object KeyLastWriteTimestamp

Die Ausgabe ist eine Pro-Host-Timeline, wann das schlechte Binärprogramm auf jedem Host zum ersten Mal erschien. Der früheste Zeitstempel ist Ihr Patient-Zero-Kandidat; nachfolgende Zeitstempel sind die Verbreitung.

Wenn Hash-Treffer übermatchen#

Der Hash-Pivot verpasst Neukompilierungen desselben Tools. Angreifer, die ihren Loader vor jedem Lateral Move neu kompilieren, haben auf jedem Host einen anderen Hash. Für diese greifen Sie auf ProgramId zurück.


Der ProgramId-Pivot#

ProgramId ist nachsichtiger als Hash — es fängt Neukompilierungen ein, die Name/Publisher/Version teilen, selbst wenn sich der Binärinhalt unterscheidet. Siehe Amcache ProgramId erklärt dafür, wie die Identität konstruiert wird.

$badProgramId = '0006fa0b2a9f8a4eb9d7c81e8b1f3c5d3e2a0000ffff'
 
Get-ChildItem -Recurse -Filter *_UnassociatedFileEntries.csv |
  ForEach-Object {
    $host = $_.PSChildName.Split('_')[0]
    Import-Csv $_.FullName |
      Where-Object { $_.ProgramId -eq $badProgramId } |
      Select-Object @{n='Host';e={$host}}, FullPath, Hash, KeyLastWriteTimestamp
  } |
  Sort-Object KeyLastWriteTimestamp

Das findet jeden Host, der irgendein Binärprogramm hat, das sich als dieselbe Anwendung identifiziert — selbst mit unterschiedlichen Inhalts-Hashes. Paaren Sie es mit dem Hash-Pivot: Hash für hochpräzise Treffer, ProgramId für Familien-Treffer.

Wenn ProgramId übermatcht#

ProgramId fängt Fehlalarme ein, wenn der Angreifer eine legitime Anwendungsidentität huckepack nimmt (z. B. Neukompilierung von PsExec.exe-benanntem Tooling, das dieselbe ProgramId wie das echte PsExec bekommt). Paaren Sie es mit Hash zur Disambiguierung; eine Zeile, die ProgramId-mäßig passt, aber mit einem Hash, den niemand sonst in Ihrer Umgebung hat, ist hoch verdächtig.


Der Pfad-Muster-Pivot#

Für bekannte Angreifer-Installationspfadmuster regexen Sie gegen FullPath:

$pattern = '\\AppData\\Roaming\\[a-z0-9]{8}\\update\.exe$'
 
Get-ChildItem -Recurse -Filter *_UnassociatedFileEntries.csv |
  ForEach-Object {
    $host = $_.PSChildName.Split('_')[0]
    Import-Csv $_.FullName |
      Where-Object { $_.FullPath -match $pattern } |
      Select-Object @{n='Host';e={$host}}, FullPath, Hash, ProgramId, KeyLastWriteTimestamp
  }

Nützlich, wenn:

  • Sie die Installationskonvention des Intrusion Sets kennen.
  • Der Angreifer Hashes und Metadaten rotiert, aber Pfadmuster wiederverwendet.
  • Sie Varianten finden möchten, die einen Pfadstil teilen.

Paaren Sie die Treffer mit Hash und ProgramId aus den Pro- Zeilen-Ergebnissen, um eine reichhaltigere Detektion zu bauen.


Zeitreihen-Sicht der Verbreitung#

Sortieren Sie für jeden Pivot die Ergebnisse nach KeyLastWriteTimestamp, um die Verbreitung über die Zeit zu sehen. Ein typisches Muster:

2026-04-01 14:23 HOST01  -- Patient Zero, initialer Zugriff des Angreifers
2026-04-03 09:11 HOST02  -- 2 Tage später
2026-04-03 11:34 HOST07
2026-04-03 14:55 HOST09
2026-04-04 02:08 HOST15  -- Wochenende; Angreifer arbeitet über Nacht
2026-04-04 02:33 HOST22
2026-04-04 02:51 HOST31

Zwei Lesarten:

  1. Die Kadenz (mehrere Hosts innerhalb weniger Stunden voneinander) ist charakteristisch für automatisiertes Lateral-Movement-Tooling (PsExec / WMI / SMB-basiert).
  2. Der nächtliche Burst über Nacht ist das typische Angreifer-Muster: initialer Zugriff während der Geschäftszeiten, dann beschleunigte Bewegung, sobald sie Credentials und Kontrolle haben.

Verwenden Sie diese Muster, um den Rest Ihrer Beweissammlung zeitlich einzugrenzen. Ziehen Sie Sysmon / Security 4624 / 4688 für jeden Host in seinem KeyLastWriteTimestamp ± 1 h-Fenster — Sie bekommen die tatsächlichen Kommandozeilen des Angreifers und Credential-Events mit hoher Präzision.


Kreuzpivotieren von Treiber- und Geräte-Beweisen#

Das hostübergreifende Muster ist nicht auf *_UnassociatedFileEntries.csv beschränkt. Für tiefere Untersuchungen führen Sie dieselben Pivot-Muster aus gegen:

*_DriverBinaries.csv#

Für BYOVD-Untersuchungen — ein verwundbarer Treiber, den der Angreifer auf einem Host geladen hat, ist fast sicher auf den anderen geladen, die er erreichte. Abfragen Sie nach Treiber-Hash oder DriverName:

$badDriver = 'mhyprot2.sys'
 
Get-ChildItem -Recurse -Filter *_DriverBinaries.csv |
  ForEach-Object {
    $host = $_.PSChildName.Split('_')[0]
    Import-Csv $_.FullName |
      Where-Object { $_.DriverName -eq $badDriver } |
      Select-Object @{n='Host';e={$host}}, DriverName, Service, DriverSigned, KeyLastWriteTimestamp
  }

*_DeviceContainers.csv#

Für Untersuchungen, in denen der Angreifer Hardware verbunden hat (selten bei Remote-Angriffen, zentral in Insider-Threat-Fällen) — abfragen Sie nach Manufacturer oder FriendlyName:

$suspiciousVendor = 'HakShop'
 
Get-ChildItem -Recurse -Filter *_DeviceContainers.csv |
  ForEach-Object {
    $host = $_.PSChildName.Split('_')[0]
    Import-Csv $_.FullName |
      Where-Object { $_.Manufacturer -match $suspiciousVendor } |
      Select-Object @{n='Host';e={$host}}, FriendlyName, Manufacturer, KeyLastWriteTimestamp
  }

Siehe USB- und Gerätehistorie aus Amcache für die geräteseitigen Muster im Detail.


Kombination mit Nicht-Amcache-Quellen#

Der Amcache-Pivot verrät Ihnen, wo das Binärprogramm inventarisiert wurde. Um die Ausführung zu bestätigen und die Methode der Bewegung zu identifizieren, korrelieren Sie mit:

  • 4624 (Logon) + 4625 (Failed logon) auf den Ziel-Hosts — wann hat sich der Angreifer authentifiziert und als wer?
  • 4648 (Explicit credential logon) — Lateral Movement mit Credentials (PsExec, RDP mit übergebenen Credentials).
  • Sysmon 1 / 4688 (Process create) mit Elternprozess — hat der Angreiferprozess unter services.exe (PsExec / Remote- Service), unter wmiprvse.exe (WMI) oder unter explorer.exe (interaktiv) gespawnt?
  • Sysmon 3 (Network connect) + Sysmon 22 (DNS query) — ausgehende C2.
  • Velociraptor- / EDR-Prozess-Bäume — dieselben Daten, einfacher zu navigieren.

Ein einzelner Amcache-Pivot, der die Verbreitung scopt, geknüpft an Pro-Host-Authentifizierungs- und -Prozess-Events auf den passenden Hosts, gibt Ihnen eine verteidigungsfähige Timeline aus: wer, wann, von wo, über welches Binärprogramm, mit welchen Credentials.


Wenn der Pivot verfehlt#

Drei Situationen, in denen der hostübergreifende Amcache-Pivot unterperformt:

Der Appraiser ist auf den Ziel-Hosts noch nicht gelaufen#

Wenn der Angreifer sich innerhalb von Stunden nach Ihrer Sammlung seitlich bewegt hat, haben die Appraiser der Ziel-Hosts das Binärprogramm möglicherweise noch nicht inventarisiert. Amcache zeigt sie als sauber. Sammeln Sie 24–48 Stunden später erneut; die Verbreitung wird erscheinen.

Der Angreifer hat Amcache auf jedem erreichten Host gesäubert#

Unüblich (meist, weil es laut ist und die meisten Angreifer sich nicht antun), aber möglich. Verwenden Sie den Volume-Shadow-Copy- Wiederherstellungs-Workflow in Wo Amcache.hve auf der Festplatte liegt auf jedem Host, auf dem Sie Säuberung vermuten.

Der Angreifer hat pro Host unterschiedliche Binärprogramme verwendet#

Wenn der Angreifer Pro-Host-Implants generiert hat (wirklich Pro-Opfer-Malware), versagen Hash- und ProgramId-Pivots konstruktionsbedingt. Pfadmuster und breitere Verhaltensdetektionen (4624-Logon von derselben ungewöhnlichen IP über viele Hosts) werden primär.


Siehe auch#

Um Ihre eigenen gesammelten Hives ohne Installation zu erkunden, legen Sie eine Datei auf der Startseite des Parsers ab — sie parst vollständig in Ihrem Browser.

Verwandte Beiträge

Zurück zu allen Beiträgen