
Sammlung von Hash-Algorithmen, die in Malware verwendet werden
HashDB ist eine von der Community zusammengetragene Bibliothek von Hash-Algorithmen, die in Malware verwendet werden.
HashDB kann als eigenständige Hash-Bibliothek verwendet werden, speist aber auch den von OALabs betriebenen HashDB Lookup Service. Dieser Dienst ermöglicht es Analysten, Hashes umzukehren und gehashte API-Namen und String-Werte abzurufen.
HashDB kann geklont und wie jedes Standard-Python-Modul in deinen Reverse-Engineering-Skripten verwendet werden. Im Folgenden findest du Beispielcode.
>>> import hashdb
>>> hashdb.list_algorithms()
['crc32']
>>> hashdb.algorithms.crc32.hash(b'test')
3632233996
OALabs betreibt einen kostenlosen HashDB Lookup Service, mit dem eine Hashtabelle nach jedem in der HashDB-Bibliothek gelisteten Hash abgefragt werden kann. In den Hashtabellen enthalten sind der vollständige Satz der Windows-APIs sowie viele gängige Strings, die in Malware verwendet werden. Du kannst sogar eigene Strings hinzufügen!
Der HashDB-Lookup-Dienst verfügt über ein IDA-Pro-Plugin, mit dem sich Hash-Lookups direkt aus IDA heraus automatisieren lassen! Der Client kann von GitHub hier heruntergeladen werden.
HashDB verlässt sich auf die Unterstützung der Community, um unsere Hash-Bibliothek aktuell zu halten! Unser Ziel ist es, dass Mitwirkende nicht mehr als fünf Minuten für das Hinzufügen eines neuen Hashes benötigen – vom ersten Commit bis zur PR. Um dieses Ziel zu erreichen, bieten wir den folgenden schlanken Prozess an.
Stelle sicher, dass der Hash-Algorithmus nicht bereits existiert … wir wissen, das klingt albern, aber überprüfe es einfach noch einmal.
Erstelle einen Branch mit einem beschreibenden Namen.
Füge im Verzeichnis /algorithms eine neue Python-Datei mit dem Namen deines Hash-Algorithmus hinzu. Versuche, den offiziellen Namen des Algorithmus zu verwenden, oder falls er einzigartig ist, den Namen der Malware, für die er einzigartig ist.
Verwende die folgende Vorlage, um deinen neuen Hash-Algorithmus einzurichten. Alle Felder sind Pflichtfelder und unterscheiden zwischen Groß- und Kleinschreibung.
#!/usr/bin/env python
DESCRIPTION = "your hash description here"
# Type can be either 'unsigned_int' (32bit) or 'unsigned_long' (64bit)
TYPE = 'unsigned_int'
# Test must match the exact hash of the string 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
TEST_1 = hash_of_string_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
def hash(data):
# your hash code here
Kontrolliere deinen Python-Stil noch einmal genau – wir verwenden Flake8 mit Python 3.9. Du kannst die folgenden Lint-Befehle lokal im Root-Verzeichnis des Git-Repositories ausführen.
pip install flake8
flake8 ./algorithms --count --select=E9,F63,F7,F82 --show-source --statistics
Teste deinen Code lokal mit unserer Test-Suite. Führe die folgenden Befehle lokal im Root-Verzeichnis des Git-Repositories aus. Beachte, dass du pytest als Modul und nicht direkt ausführen musst, andernfalls wird unser Testverzeichnis nicht erkannt.
pip install pytest
python -m pytest
Reiche eine Pull Request ein – dein neuer Algorithmus wird automatisch zum Testen eingereiht und bei Erfolg gemerged.
Das war’s! Dein neuer Hash wird nicht nur in der HashDB-Bibliothek verfügbar sein, sondern es wird auch eine neue Hashtabelle für den HashDB Lookup Service generiert – und du kannst sofort damit beginnen, Hashes umzukehren!
PRs mit Änderungen außerhalb des Verzeichnisses /algorithms sind nicht Teil unserer automatisierten CI und werden einer zusätzlichen Prüfung unterzogen.
Alle Hashes müssen eine gültige Beschreibung im Feld DESCRIPTION haben.
Alle Hashes müssen im Feld TYPE einen Typ von entweder unsigned_int oder unsigned_long haben. HashDB akzeptiert derzeit nur vorzeichenlose (unsigned) 32-Bit- oder 64-Bit-Hashes.
Alle Hashes müssen im Feld TEST_1 den Hash der Zeichenfolge ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 enthalten.
Alle Hashes müssen eine Funktion hash(data) enthalten, die einen Byte-String akzeptiert und einen Hash der Zeichenfolge zurückgibt.
Einige Hash-Algorithmen hashen den Modulnamen und die API getrennt und kombinieren die Hashes zu einem einzigen Modul+API-Hash. Ein Beispiel hierfür ist der Standard-Metasploit-ROR13-Hash. Diese Algorithmen funktionieren nicht mit der Standard-Wortliste und erfordern eine benutzerdefinierte Wortliste, die sowohl den Modulnamen als auch die API enthält. Um diese zu handhaben, erlauben wir benutzerdefinierte Algorithmen, die nur für einige Wörter einen gültigen Hash zurückgeben.
Das Hinzufügen eines benutzerdefinierten API-Hashes erfordert die folgenden zusätzlichen Komponenten.
Das Feld TEST_1 muss auf 4294967294 (-1) gesetzt werden.
Der Hash-Algorithmus muss für alle ungültigen Hashes den Wert 4294967294 zurückgeben.
Ein zusätzliches Feld TEST_API_DATA_1 muss mit einem Beispielwort hinzugefügt werden, das für den Algorithmus gültig ist.
Ein zusätzliches Feld TEST_API_1 muss mit dem Hash des Feldes TEST_API_DATA_1 hinzugefügt werden.
Ein großes Dankeschön an das FLARE-Team für seine Arbeit an shellcode_hashes. Vor vielen Jahren setzte dieses Projekt die Messlatte für schnelles und einfaches Umkehren von Malware-Hashes, und es ist immer noch ein äußerst nützliches Werkzeug. Warum es also duplizieren?
Ehrlich gesagt dreht sich alles um die Wortliste und die Zugänglichkeit. Wir haben eine dramatische Verschiebung hin zur Verwendung von Hashes für alle möglichen Strings in Malware erlebt, und die alte Methode, alle Windows-DLL-Exporte zu hashen, ist einfach nicht mehr gut genug. Wir wollten eine Lösung, die kontinuierlich Millionen von Registry-Schlüsseln und -Werten, Dateinamen und Prozessnamen verarbeiten kann. Und wir wollten diese Daten über eine REST-API verfügbar machen, damit wir sie in unseren Automatisierungs-Workflows nutzen können, nicht nur in unseren statischen Analysetools. Abgesehen davon würden wir ohne shellcode_hashes nicht existieren, also Ehre, wem Ehre gebührt 🙌