SafePay gehört zu den Ransomware-Gruppen, die seit Ende 2024 vermehrt in Erscheinung treten, auch im DACH-Raum. Im Rahmen eines aktuellen Incident-Response-Falls hatten wir die Gelegenheit, sowohl den Encryptor als auch den zugehörigen Decryptor statisch zu analysieren. In diesem Beitrag zeigen wir, wie SafePay Dateien verschlüsselt, wie das Dateiformat aufgebaut ist und welche handwerklichen Fehler sich im Code finden. Einige davon können Betroffenen im Ernstfall tatsächlich helfen.
Das Sample im Überblick
Der Encryptor liegt als 32-Bit-DLL vor, die über regsvr32 gestartet wird. Die Parameter werden über den /i:-Schalter an den Export DllInstall übergeben. Schon auf den ersten Blick ist das Sample sorgfältig verschleiert:
- Keine echte Import-Tabelle. Die DLL importiert eine Handvoll harmloser Funktionen, ruft sie aber nie auf. Der entsprechende Codepfad in
DllMainist an eine Bedingung geknüpft, die nie eintritt (hinstDLL == 0). Die Imports dienen nur dazu, die DLL unauffälliger aussehen zu lassen. - API-Auflösung per Hash. Rund 110 Windows-Funktionen aus acht DLLs werden zur Laufzeit über einen PEB-Walk und CRC32-Hashes der Funktionsnamen gefunden.
- Stack-Strings mit XOR. Sämtliche Texte, von DLL-Namen über Kommandozeilen bis zu Logmeldungen, werden byteweise auf den Stack geschrieben und zur Laufzeit entschlüsselt. Als Schlüsselbyte dient dabei ein Byte aus dem
MZ-Header vonkernel32.dll. Der Schlüssel steht also nie im Binary selbst. - Verschlüsselte Konfiguration. Public Key, Ausschlusslisten, Kill-Listen und Erpressertext liegen in einem als
.debuggetarnten Abschnitt. Entschlüsselt werden sie mit dem Kommandozeilenparameter-pass=. Ohne korrektes Passwort beendet sich die Ransomware sofort, eine Prüfsumme verifiziert das Ergebnis.
Der letzte Punkt verdient Beachtung: Ein Sample, das ohne Passwort gar nicht erst startet, entzieht sich vielen automatisierten Sandboxen. Für die Forensik heißt das umgekehrt: Wer die Kommandozeile aus EDR-, Sysmon- oder Prozess-Logs rekonstruieren kann, kann auch die Konfiguration lesen.
Das Kryptoschema: hybrid, pro Datei, ohne gespeicherte Schlüssel
SafePay setzt auf ein modernes, hybrides Verfahren, das in seinen Grundzügen dem Muster vieler aktueller Ransomware-Familien folgt. Das Herzstück ist ein elliptischer Schlüsseltausch über Curve25519 (X25519).
Schritt 1: Ein Schlüsselpaar pro Datei
Für jede einzelne Datei erzeugt der Encryptor mit RtlGenRandom 32 Zufallsbytes und bereitet sie nach RFC 7748 als X25519-Private-Key auf („Clamping“). Daraus berechnet er den zugehörigen Public Key. Dieses Schlüsselpaar existiert nur für diese eine Datei. Man spricht von einem ephemeren Schlüssel.
Schritt 2: Schlüsseltausch mit dem Angreifer-Key
In der Konfiguration steckt der Public Key der Angreifer. Mit ihm und dem ephemeren Private Key berechnet der Encryptor ein gemeinsames Geheimnis:
S = X25519(ephemerer Private Key, Public Key der Angreifer)
Die Eigenschaft, die Ransomware hier ausnutzt: Dasselbe Geheimnis lässt sich auch aus der anderen Richtung berechnen, nämlich aus dem Private Key der Angreifer und dem ephemeren Public Key. Den ersten Teil besitzt nur die Gruppe, den zweiten legt der Encryptor in jeder Datei ab.
Schritt 3: Schlüsselableitung
Aus dem gemeinsamen Geheimnis wird per SHA-512 ein 64-Byte-Wert abgeleitet. Die ersten 32 Byte bilden den eigentlichen Dateischlüssel, die nächsten 16 bzw. 24 Byte dienen als IV bzw. Nonce. Danach werden ephemerer Private Key, Geheimnis und Hash im Speicher überschrieben.
Das Ergebnis: Der Dateischlüssel wird nirgends gespeichert, weder in der Datei noch im Speicher noch irgendwo sonst. Er kann nur mit dem Private Key der Angreifer rekonstruiert werden. Eine Abkürzung über schwachen Zufall oder zurückgebliebene Schlüssel haben wir in diesem Sample nicht gefunden.
Schritt 4: Zwei Cipher, je nach Hardware
Bemerkenswert ist, dass SafePay den Cipher von der CPU abhängig macht:
| CPU des Opfersystems | Cipher | Schlüsselmaterial aus SHA-512 |
|---|---|---|
| mit AES-NI | AES-256-CBC | Schlüssel = Bytes 0–31, IV = Bytes 32–47 |
| ohne AES-NI | XChaCha20 | Schlüssel = Bytes 0–31, Nonce = Bytes 32–55 |
Der Hintergrund ist schlicht Geschwindigkeit. Mit Hardwarebeschleunigung ist AES extrem schnell, ohne sie ist ChaCha20 in Software deutlich performanter. Für Ransomware zählt jede Minute, bevor jemand den Stecker zieht.
Beide Varianten haben eine Besonderheit, die für einen Nachbau eines Decryptors entscheidend ist. Verarbeitet wird in 1-MB-Blöcken.
- AES-CBC verkettet über alle verschlüsselten Blöcke einer Datei hinweg. Der IV eines Blocks ist der letzte Chiffratblock des vorherigen verschlüsselten Blocks, auch wenn dazwischen unverschlüsselte Bereiche liegen. Ein klassisches Padding nach PKCS#7 gibt es nicht. Der letzte Block wird einfach auf 16 Byte aufgefüllt, die Originalgröße steht im Footer.
- XChaCha20 setzt pro 1-MB-Block den Blockzähler zurück und erhöht stattdessen die 192-Bit-Nonce um eins. Block n nutzt also Nonce N + n.
Teilverschlüsselung: Tempo vor Gründlichkeit
Über den Parameter -enc=N (N = 1 bis 9) lässt sich die Verschlüsselung drosseln. In jedem 10-MB-Abschnitt einer Datei werden dann nur die ersten N Megabyte verschlüsselt, der Rest bleibt unangetastet. Ohne den Parameter gilt der Standard N = 10, also vollständige Verschlüsselung.
Teilverschlüsselung ist inzwischen Standard bei professioneller Ransomware. Bei großen Dateien wie virtuellen Festplatten, Datenbanken oder Backups genügt es, Teile zu zerstören, um sie unbrauchbar zu machen. Für Betroffene ist das ein zweischneidiges Schwert: Teilverschlüsselte Dateien lassen sich mitunter teilweise retten, etwa einzelne Dateien aus einem VM-Image. Der Aufwand ist allerdings erheblich.
Der Footer: 80 Byte am Dateiende
Alles, was zur Entschlüsselung nötig ist, hängt SafePay als 80-Byte-Footer an jede Datei an. Danach erhält die Datei die Endung .safepay.
| Offset | Länge | Inhalt |
|---|---|---|
0x00 | 8 | Originalgröße der Datei (uint64, Little Endian) |
0x08 | 32 | X25519 Public Key der Angreifer |
0x28 | 32 | Ephemerer X25519 Public Key dieser Datei |
0x48 | 1 | Verschlüsselungsgrad N (10 = vollständig) |
0x49 | 1 | Cipher: 0x00 = AES-256-CBC, 0x01 = XChaCha20 |
0x4A | 6 | Nullbytes |
Für die Praxis ist besonders das Feld bei Offset 0x08 nützlich. Weil der Public Key der Angreifer in jedem Footer steht, lässt sich für jede einzelne Datei prüfen, zu welchem Build sie gehört. Das hilft bei der Triage, wenn mehrere Encryptor-Instanzen im Einsatz waren. Bei einer Verhandlungslösung lässt sich so außerdem prüfen, ob ein erhaltener Decryptor wirklich zu den eigenen Dateien passt. Im analysierten Fall konnten wir mathematisch nachweisen, dass der im Decryptor eingebettete Private Key exakt zum Public Key in der Encryptor-Konfiguration gehört.
Der Rest des Werkzeugkastens
Die Verschlüsselung ist nur ein Teil dessen, was der Encryptor mitbringt. Der Vollständigkeit halber ein Überblick:
- UAC-Bypass über den COM-Elevation-Moniker der Klasse CMSTPLUA, ein seit Jahren bekannter und von vielen Familien genutzter Trick.
- Persistenz über einen
Run-Schlüssel in HKCU, derregsvr32mit der DLL und den ursprünglichen Parametern startet. Nach Abschluss der Verschlüsselung wird der Eintrag wieder gelöscht. - Sabotage der Wiederherstellung: Schattenkopien löschen (
vssadmin,wmic), Windows-Recovery perbcdeditdeaktivieren, Papierkorb leeren. - Netzwerk: Freigaben und Netzlaufwerke werden über WNet-Funktionen und mit dupliziertem Token angesprochen. Außerdem hängt der Encryptor Volumes ohne Laufwerksbuchstaben ein, um auch diese zu verschlüsseln.
- Selbstschutz: Anti-Debugging über den Debug-Port, eine Deny-ACE auf den eigenen Prozess und am Ende eine Selbstlöschung, bei der die DLL zuvor per
fsutilmit Nullen überschrieben wird.
Bemerkenswert ist, was fehlt: Der Encryptor enthält keinerlei Internetkommunikation. Wenn Daten abgeflossen sind, und SafePay droht in seinen Erpresserschreiben ausdrücklich mit Veröffentlichung, dann geschah das vorher mit separaten Werkzeugen.
Wo SafePay patzt
So solide die Kryptografie umgesetzt ist, so nachlässig wirken andere Teile des Codes.
Kill-Listen, die nicht treffen
Wie fast jede Ransomware beendet SafePay vor der Verschlüsselung Prozesse und Dienste, damit Datenbanken und Office-Dokumente nicht mehr gesperrt sind. Die Listen enthalten Einträge wie sql, oracle, veeam, backup, sophos oder msexchange.
Der Haken: SafePay vergleicht exakt. Prozessnamen werden ohne .exe mit dem Listeneintrag verglichen, Dienste über den exakten Dienstnamen geöffnet. Einen Prozess namens sql.exe oder einen Dienst namens veeam gibt es aber nicht. Der SQL Server heißt sqlservr.exe bzw. MSSQLSERVER. Die Listen stammen offensichtlich aus älteren Familien, die mit Teilstrings gearbeitet haben, und wurden ohne Anpassung übernommen. Wirksam sind praktisch nur die Einträge mit exakten Namen, etwa die Office-Programme, vss oder einige Backup-Dienste.
Ein Restart Manager, der nichts neu startet
Für gesperrte Dateien nutzt SafePay zusätzlich den Windows Restart Manager. Er findet heraus, welcher Prozess eine Datei blockiert, und soll ihn dann über RmShutdown beenden. Durch einen Fehler in der Funktionstabelle ruft der Code an dieser Stelle jedoch eine falsche Funktion auf. RmShutdown wird nie ausgeführt.
Bemerkenswert: Derselbe Fehler steckt auch im Decryptor. Das ist ein starkes Indiz dafür, dass beide aus demselben Builder bzw. derselben Codebasis stammen.
Was das für Betroffene bedeutet
Zusammengenommen heißt das: Dateien, die zum Zeitpunkt des Angriffs von laufenden Diensten gesperrt waren, wurden möglicherweise gar nicht verschlüsselt. Dazu gehören etwa aktive SQL-Server-Datenbanken, Exchange-Datenbanken oder offene Backup-Repositories. Bevor man solche Daten abschreibt, lohnt sich ein genauer Blick, ob sie die Endung .safepay tragen und einen gültigen Footer besitzen.
Empfehlungen für Verteidiger
Prävention und Erkennung
regsvr32mit/i:-Parametern, die nicht zu legitimer Software gehören, ist ein starkes Signal. Gleiches gilt für neueRun-Einträge, dieregsvr32aufrufen.vssadmin delete shadows,wmic shadowcopy deleteundbcdedit … recoveryenabled Nosollten in jeder EDR-Umgebung einen Alarm auslösen.- COM-Elevation über CMSTPLUA aus ungewöhnlichen Elternprozessen lässt sich mit gängigen Detection-Regeln erkennen.
- Offline- bzw. unveränderliche Backups bleiben die wirksamste Gegenmaßnahme. Die Kryptografie von SafePay bietet keine Abkürzung.
Im Ernstfall
- Kommandozeilen sichern. Das
-pass=-Passwort steht in derregsvr32-Kommandozeile und ermöglicht die Analyse der Konfiguration. - Verschlüsselte Dateien vor jedem Entschlüsselungsversuch sichern. Decryptoren arbeiten in der Regel direkt auf der Originaldatei.
- Footer prüfen, um Zugehörigkeit, Cipher und Verschlüsselungsgrad je Datei festzustellen.
- Gesperrte Datenbanken gezielt prüfen, denn sie könnten unverschlüsselt geblieben sein.
- Den Decryptor selbst analysieren, bevor er im Netz läuft. Im hier untersuchten Fall war er sauber. Darauf verlassen sollte man sich nie.
Fazit
SafePay zeigt exemplarisch den Stand professioneller Ransomware: Die Kryptografie ist modern und korrekt implementiert, mit X25519, SHA-512, AES-256 und XChaCha20 sowie Schlüsseln pro Datei. Ohne den Private Key der Angreifer gibt es keinen Weg zurück. Gleichzeitig verraten übernommene Kill-Listen und ein Fehler in der Funktionstabelle, dass auch hier mit Copy-and-paste gearbeitet wird. Für Betroffene können genau diese Nachlässigkeiten den Unterschied machen.
Wenn Sie von einem Ransomware-Angriff betroffen sind oder Ihre Erkennungs- und Wiederherstellungsfähigkeiten prüfen möchten, sprechen Sie uns an.
CERTAINITY Incident Response Team
