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 DllMain ist 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 von kernel32.dll. Der Schlüssel steht also nie im Binary selbst.
  • Verschlüsselte Konfiguration. Public Key, Ausschlusslisten, Kill-Listen und Erpressertext liegen in einem als .debug getarnten 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 OpfersystemsCipherSchlüsselmaterial aus SHA-512
mit AES-NIAES-256-CBCSchlüssel = Bytes 0–31, IV = Bytes 32–47
ohne AES-NIXChaCha20Schlü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.


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.

OffsetLängeInhalt
0x008Originalgröße der Datei (uint64, Little Endian)
0x0832X25519 Public Key der Angreifer
0x2832Ephemerer X25519 Public Key dieser Datei
0x481Verschlüsselungsgrad N (10 = vollständig)
0x491Cipher: 0x00 = AES-256-CBC, 0x01 = XChaCha20
0x4A6Nullbytes

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, der regsvr32 mit 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 per bcdedit deaktivieren, 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 fsutil mit 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

  • regsvr32 mit /i:-Parametern, die nicht zu legitimer Software gehören, ist ein starkes Signal. Gleiches gilt für neue Run-Einträge, die regsvr32 aufrufen.
  • vssadmin delete shadows, wmic shadowcopy delete und bcdedit … recoveryenabled No sollten 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

  1. Kommandozeilen sichern. Das -pass=-Passwort steht in der regsvr32-Kommandozeile und ermöglicht die Analyse der Konfiguration.
  2. Verschlüsselte Dateien vor jedem Entschlüsselungsversuch sichern. Decryptoren arbeiten in der Regel direkt auf der Originaldatei.
  3. Footer prüfen, um Zugehörigkeit, Cipher und Verschlüsselungsgrad je Datei festzustellen.
  4. Gesperrte Datenbanken gezielt prüfen, denn sie könnten unverschlüsselt geblieben sein.
  5. 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