Imphash, Rich-Header-Hash und TLSH: Samples gruppieren
Wie Imphash, Rich-Header-Hash und TLSH verwandte Windows-Executables gruppieren, wie sie berechnet werden und wo jedes Verfahren an Grenzen stößt.
Kurz gesagt. Ein SHA-256 ändert sich, sobald sich ein Byte ändert, und kann Ihnen daher nicht sagen, dass zwei Dateien verwandt sind. Drei andere Fingerabdrücke können das: der Imphash (was das Programm importiert), der Rich-Header-Hash (welche Komponenten der Microsoft-Toolchain es gebaut haben) und TLSH (wie ähnlich die Bytes sind). Jeder versagt auf bekannte Weise. Bilden Sie damit Gruppen und bestätigen Sie diese anschließend mit weiteren Belegen.
Imphash: der Import-Fingerabdruck
Mandiant hat den Import-Hash 2014 eingeführt (Tracking Malware with Import Hashing). Die verbreitete Implementierung ist get_imphash() in pefile:
- Für jede importierte DLL in Dateireihenfolge den kleingeschriebenen Namen nehmen und eine Endung
.dll,.ocxoder.sysentfernen. - Für jede Funktion den kleingeschriebenen Namen nehmen. Funktionen, die per Ordinal importiert werden, werden über die pefile-Tabellen für
ws2_32,wsock32undoleaut32benannt und andernfalls alsordNgeschrieben. - Die
dll.function-Paare mit Kommas verbinden und den MD5 bilden.
Da der Linker die Importe in der Reihenfolge schreibt, in der der Code sie verwendet, teilen sich Builds aus demselben Quellbaum meist einen Imphash, während fremde Programme das selten tun. Im Beispiel, das der PE Parser lädt, haben die beiden Builds von m64.exe unterschiedliche SHA-256-Werte, aber denselben Imphash, und die Batch-Tabelle markiert sie als Familie 1.
Wo er versagt: bei gepackten Dateien (der Imphash beschreibt den Stub des Packers, den Tausende fremder Samples teilen), bei .NET-Assemblies (sie importieren nur mscoree.dll!_CorExeMain) und bei sehr kleinen Programmen, deren wenige Importe überall vorkommen. Delay-Load-Importe fließen nicht in den Imphash von pefile ein. Siehe den Glossareintrag zum Imphash.
Rich-Header-Hash: der Toolchain-Fingerabdruck
Der Microsoft-Linker schreibt einen undokumentierten Block in den DOS-Stub: eine Liste von comp.id-Werten (Produkt-ID und Build-Nummer jedes Compilers, Assemblers, Linkers und jeder Importbibliothek, die Objektdateien beigesteuert haben) mit jeweils einer Anzahl, XOR-maskiert mit einem Schlüssel und abgeschlossen durch das Wort Rich. Der Schlüssel ist nicht zufällig: Er ist eine Prüfsumme über den DOS-Header und die Einträge, wie Daniel Pistelli in Microsoft's Rich Signature (undocumented) beschreibt.
Daraus ergeben sich zwei Dinge:
- ein Rich-Header-Hash (
get_rich_header_hash()in pefile: MD5 des dekodierten Headers), den Programme teilen, die mit derselben Toolchain-Mischung gebaut wurden – oft dasselbe Projekt; - eine Konsistenzprüfung: Entspricht der gespeicherte Schlüssel nicht der neu berechneten Prüfsumme, wurde der Header bearbeitet oder verpflanzt.
Fälschungen kommen tatsächlich vor. Kaspersky hat gezeigt, dass das Sample von Olympic Destroyer einen aus einer anderen Familie kopierten Rich Header trug, um die Attribution in die Irre zu führen (The devil's in the Rich header). Forschungsarbeiten wie Webster et al., Finding the Needle: A Study of the PE32 Rich Header and Respective Malware Triage (DIMVA 2017), zeigen, wie gut er sich in der Praxis zum Clustern eignet. Der Eintrag zum Rich Header fasst das Format zusammen; der PE Parser dekodiert comp.ids zu Visual-Studio-Releases anhand der öffentlichen Liste des Projekts richprint.
Wo er versagt: Nicht-Microsoft-Toolchains (MinGW, Go, Rust mit GNU-Target, Delphi) schreiben keinen Rich Header, und er kann entfernt oder genullt werden.
TLSH: der Fingerabdruck der Byte-Ähnlichkeit
TLSH (Trend Micro Locality Sensitive Hash) fasst die Verteilung von Byte-Trigrammen in einem Digest aus 70 Hex-Ziffern mit dem Präfix T1 zusammen. Zwei Digests werden über eine Distanz verglichen: 0 bedeutet identisch, kleiner bedeutet ähnlicher. Enge Varianten eines Programms landen meist bei kleinen Distanzen; einen universellen Schwellenwert gibt es nicht, kalibrieren Sie also anhand bekanntermaßen verwandter und nicht verwandter Dateien aus Ihrer eigenen Sammlung. TLSH braucht mindestens 50 Byte mit ausreichender Vielfalt, um einen Digest zu erzeugen.
Die Vergleichsansicht des PE Parser zeigt die TLSH-Distanz zwischen zwei beliebigen geladenen Dateien. ssdeep, der andere verbreitete Fuzzy-Hash, ist nicht enthalten: Seine Referenzimplementierung steht unter der GPL, und wir haben keine permissiv lizenzierte gefunden.
Wo er versagt: Packen oder Komprimieren verändert die Bytes vollständig; große gemeinsame Ressourcen (Icons, eingebettete Laufzeitumgebungen) können fremde Dateien ähnlich erscheinen lassen.
Alles zusammen
| Fingerabdruck | Gruppiert nach | Übersteht Neukompilierung | Übersteht Packen | Fälschbar |
|---|---|---|---|---|
| SHA-256 | exakten Bytes | nein | nein | nein |
| Imphash | Importliste | oft | nein (hasht den Stub) | ja, leicht |
| Rich-Header-Hash | Toolchain-Mischung | oft | manchmal (Stub kann ihn behalten) | ja |
| TLSH | Byte-Verteilung | teilweise | nein | mit Aufwand |
Ein solider Workflow: eine Sammlung nach Imphash und Rich-Hash clustern, in jedem Cluster TLSH-Distanzen und Zeitstempel prüfen (PE-Zeitstempel) und erst dann „gleiche Familie“ in einen Bericht schreiben – mit aufgeführten Belegen.
FAQ
Was ist ein Imphash?
Ein MD5 über die geordnete Liste der importierten Funktionen, geschrieben als kleingeschriebene dll.function-Paare, durch Kommas verbunden. Zwei Builds desselben Programms teilen ihn oft, selbst wenn sich jedes Byte ihres Codes unterscheidet.
Ist der Rich Header für die Attribution verlässlich?
Er ist ein nützliches Indiz, kann aber kopiert oder gefälscht werden: Die Malware Olympic Destroyer trug einen Rich Header, der aus einer anderen Familie stammte. Prüfen Sie, ob seine Prüfsumme konsistent ist, und wägen Sie ihn gegen andere Belege ab.
Warum gibt es im PE Parser kein ssdeep?
Die Referenzimplementierung von ssdeep steht unter der GPL, und wir haben keine permissiv lizenzierte Implementierung gefunden. Daher nutzt das Tool für Ähnlichkeit stattdessen TLSH (Apache-2.0).