
Detaillierte Analyse und PoC-Exploit für CVE-2025-2825, einen Authentifizierungs-Bypass in CrushFTP. Enthält Nuclei-Vorlagen, Multithread-Scanner und Benutzererstellungsskript für Penetrationstests.
Dieses Dokument präsentiert die Untersuchung der Schwachstelle CVE-2025-2825, die den Serverteil von CrushFTP betrifft – eine kommerzielle Lösung für Dateiübertragung und -speicherung (FTP, SFTP, HTTP/S, S3-ähnliche Schnittstellen usw.).
Der Fehler wird als Authentication Bypass eingestuft, der es einem entfernten, nicht authentifizierten Angreifer ermöglicht, Administratorrechte zu erlangen. Eine erfolgreiche Ausnutzung gewährt Zugriff mit crushadmin-Privilegien, ermöglicht das Anzeigen und Ändern von Dateien, die Verwaltung von Benutzerkonten und die Durchführung administrativer Operationen über die Weboberfläche und die API von CrushFTP.
Gemeldete betroffene Versionen (laut öffentlichen Advisories und Forscherberichten):
⚠️ Hinweis: In einigen Veröffentlichungen gibt es Duplikate und Überschneidungen von CVE-IDs (z. B. CVE-2025-31161).
Schrittweise Analyse der Schwachstelle und Demonstration des vollständigen Untersuchungszyklus, einschließlich:
Nach öffentlichen Berichten hat die Schwachstelle ein kritisches Risiko:
Kritisch sind Instanzen mit folgenden Merkmalen:
CrushFTP (jede Edition mit Webschnittstelle).CrushFTP implementiert die Unterstützung einer S3-ähnlichen API. Für die Authentifizierung wird der Header Authorization in folgender Form verwendet:
Authorization: AWS4-HMAC-SHA256 Credential=<AccessKey>/<Date>/<Region>/s3/aws4_request, SignedHeaders=<Headers>, Signature=<Signature>
Der Server extrahiert den AccessKey aus dem Credential-Feld und sollte die Signatur überprüfen. Im Code gab es jedoch einen Fehler bei der Handhabung des Flags lookup_user_pass.
// ServerSessionHTTP.java, Methode loginCheckHeaderAuth()
if (this.headerLookup.containsKey("AUTHORIZATION") &&
this.headerLookup.getProperty("AUTHORIZATION").trim().startsWith("AWS4-HMAC")) {
boolean lookup_user_pass = true; // ← kritischer Fehler
if (s3_username3.indexOf("~") >= 0) {
user_pass = user_name.substring(user_name.indexOf("~") + 1);
user_name = user_name.substring(0, user_name.indexOf("~"));
lookup_user_pass = false;
}
if (this.thisSession.login_user_pass(
lookup_user_pass,
false,
user_name,
lookup_user_pass ? "" : user_pass)) {
// Erfolgreiche Authentifizierung
}
}
Das Flag lookup_user_pass wird direkt als anyPass übergeben:
if (anyPass && user.getProperty("username").equalsIgnoreCase(the_user)) {
return user; // Authentifizierung ohne Passwortprüfung
}
Somit:
Wenn der Benutzername ohne das Zeichen ~ angegeben wird, bleibt das Flag true.
Die Passwortüberprüfung wird nicht durchgeführt.
Ein Angreifer kann sich authentifizieren, indem er nur einen vorhandenen Benutzernamen (z. B. crushadmin) angibt.
Zusammen mit einem formal gültigen CrushAuth-Cookie und dem Parameter c2f kann so die Authentifizierung umgangen und administrativer Zugriff erlangt werden.
In Version 11.3.1 und neuer haben die Entwickler:
s3_auth_lookup_password_supported (standardmäßig false) hinzugefügt, der das verwundbare Szenario blockiert.~ eingeführt.lookup_user_pass → anyPass zu beseitigen.s3_auth_lookup_password_supported anwenden.Die Ausnutzung von CVE-2025-2825 ist relativ einfach und erfordert keine aufwändige Vorbereitung. Der Angreifer muss lediglich eine speziell gestaltete HTTP-Anfrage senden, die zwei Schlüsselelemente enthält:
Authorization-Header im AWS-S3-Format, der einen korrekten, existierenden Benutzernamen enthält (Feld Credential mit AccessKey/Benutzername).CrushAuth im erwarteten Format und den Parameter c2f in URL/Anfragekörper, deren Werte logisch zueinander passen (das Cookie-Format muss der vom Server erwarteten Struktur entsprechen).Wenn der Server verwundbar ist (Version aus dem Bereich 10.0.0–10.8.3 oder 11.0.0–11.3.0 und kein korrigierender Patch angewendet), führt diese Kombination dazu, dass der Authentifizierungs-Handler den verwundbaren Pfad einschlägt, bei dem das Flag zur Passwortsuche (lookup_user_pass) als „jedes Passwort ist gültig“ interpretiert wird und der Benutzer allein anhand des Namens ohne Passwortprüfung authentifiziert wird.
Wichtiger Hinweis:
Die Ausnutzung dieser Schwachstelle erfordert in der Regel das Senden von zwei aufeinanderfolgenden Anfragen. Die erste, sogenannte „Warm-up“-Anfrage, startet den verwundbaren Authentifizierungsprozess auf dem Server. Charakteristisch dafür ist, dass man als Antwort einen Fehler
502 Bad Gatewayoder einfach ein Timeout erhält. Unmittelbar danach wird die zweite, eigentliche Anfrage gesendet, die die nützliche Aktion ausführt (z. B. Benutzererstellung), während der Server sich noch im verwundbaren Zustand befindet.
GET /WebInterface/function/?command=getUserList&serverGroup=MainUsers&c2f=1111 HTTP/1.1
Host: target-server:8080
Cookie: CrushAuth=1743113839553_vD96EZ70ONL6xAd1DAJhXMZYMn1111
Authorization: AWS4-HMAC-SHA256 Credential=crushadmin/
Für den Test habe ich die kürzlich veröffentlichte HTB-Lab-Umgebung Soulmate verwendet, bei der genau die Ausnutzung von CrushFTP erforderlich ist.

Dank dieser Schwachstelle kann mit dem Befehl setUserItem ein neuer Benutzer mit Administratorrechten hinzugefügt werden. Führen Sie dazu new_user.py aus.
python3 new_user.py --target_host http://ftp.soulmate.htb/ --port 80 --target_user crushadmin --new_user literide --password literide
Parsing des Authorization-Headers: Wenn der Server einen Autorisierungsheader im S3-ähnlichen Format (AWS4-HMAC…) sieht, extrahiert er aus dem Credential-Feld die Client-ID (AccessKey / Benutzername). In diesem Schritt erhält der Server eine Zeichenkette, die er als Benutzernamen betrachtet – diesen Identifikationswert verwendet er dann in der Authentifizierungslogik.
Das Flag lookup_user_pass und seine Rolle:
Im Code gibt es ein boolesches Flag lookup_user_pass, das angeben soll, woher das Passwort bei der Prüfung stammt:
Im normalen Szenario hilft das Flag zu entscheiden: ob das in der Anfrage übermittelte Passwort verwendet oder das Passwort aus dem Benutzerspeicher abgerufen werden soll.
Aufgrund eines Implementierungsfehlers wird dasselbe Flag jedoch weitergegeben und in der Prüffunktion anders interpretiert – als Signal, das die Passwortprüfung zu überspringen erlaubt (im Wesentlichen: „anyPass“).
Weitergabe des Flags entlang der Aufrufkette:
Ungefährer Pfad: ServerSessionHTTP.loginCheckHeaderAuth() → Session.login_user_pass(...) → UserTools.ut.verify_user(...). Am Eingang bestimmt das Flag das Verhalten, und in verify_user führt es zu einer frühen Rückgabe des gefundenen Benutzerobjekts ohne Passwortvergleich, wenn der Name übereinstimmt. Dies ermöglicht die Umgehung der Authentifizierungsprüfung – der Server „erkennt“ den Benutzer am Namen und betrachtet ihn als authentifiziert.
Begleitende Elemente (Cookie / c2f):
Öffentliche Analysen wiesen darauf hin, dass der Handler ein korrektes Format von Cookie/Parametern erwartet, um die Anfrage einer Sitzung/einem Kontext zuzuordnen. Der eigentliche Fehler liegt jedoch im logischen Fehler bei der Verarbeitung von lookup_user_pass; die anderen Elemente helfen der Anfrage lediglich, die Standardverarbeitungszweige zu durchlaufen.
Hauptursache
Credential führte dazu, dass das Vorhandensein eines korrekten Benutzernamens ausreichte, um die Benutzerdaten ohne Passwortprüfung zu erhalten.Passive Vorlage:
Da die genaue Version von CrushFTP in den meisten Webservices nicht bestimmbar ist, prüft diese Vorlage lediglich, ob der Dienst CrushFTP verwendet.
Am besten in Kombination mit der aktiven Vorlage verwenden.
Aktive Vorlage:
Die aktive Vorlage prüft, ob der Befehl getUserList möglich ist.

Multithread-Skript
Das Skript funktioniert ähnlich wie die aktive Vorlage, ist jedoch viel schneller und unterstützt die gleichzeitige Überprüfung mehrerer Hosts.
python3 scan.py -t http://ftp.soulmate.htb/ -p 80 -u crushadmin

Um die mit CVE-2025-31161 verbundenen Risiken zu mindern, werden folgende Schritte empfohlen:
Sofortige Aktualisierung:
Anwendung eines Workaround (falls ein Update nicht möglich ist):
s3_auth_lookup_password_supported auf false. Dies deaktiviert die verwundbare Authentifizierungslogik, ohne das gesamte Produkt zu aktualisieren.Risikokompensierende Maßnahmen:
AWS4-HMAC-SHA256 im Authorization-Header enthalten, insbesondere wenn Sie keine S3-Integration nutzen.Authorization-Header an Endpunkte enthalten, die nicht für die S3-API vorgesehen sind.