Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Einreichen
ToolsExploitsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

FeedsKontaktDatenschutz© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
spark-history-store-path — Apache Spark 4.2.0 - Hoch - Remote - Dateischreiben - History appStorePath nicht bereinigte App-ID | Kitploit
Tools/GitHubGitHub/abraxas/spark-history-store-path
Statische AnalyseSchwachstellenanalyseCode-AnalyseExploitationWebanwendungs-ExploitationPenetrationstestsLabs & Praxis
GitHubabraxas/spark-history-store-path

spark-history-store-path

Apache Spark 4.2.0 - Hoch - Remote - Dateischreiben - History appStorePath nicht bereinigte App-ID

Repository anzeigen
vor 2 TagenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

Abraxas Labs - spark-history-store-path

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  spark-history-store-path

spark-history-store-path

Klasse: Dateischreiben (konfigurationsgesteuert) Reichweite: Remote

Apache Spark 4.2.0 (32f72996) - Apache Software Foundation

HistoryServerDiskManager.appStorePath führt new File(appStoreDir, appId + extension) ohne Bereinigung aus. Utils.sanitizeDirName ist nur für Event-Log-Dateinamen gedacht. Die JSON-App ID ist asText(). Das Listing speichert event.appId.orNull. Lease.commit verwendet diesen String. Eine App-ID ../ schreibt eine .rdb außerhalb von spark.history.store.path. Der standardmäßig nicht gesetzte store.path ist In-Memory (kein Schreiben). Der Inhalt ist eine Store-Datei, kein RCE.

IDnoch keine CVE
KlasseDateischreiben (konfigurationsgesteuerter History-Disk-Store)
ReichweiteRemote (Event-Log-Schreiber plus History mit gesetztem spark.history.store.path; UI-ACLs standardmäßig aus)
CWECWE-22
CVSSHoch: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N, wenn spark.history.store.path gesetzt ist
ProduktApache Spark History Server
Betroffen4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8)
AuthSchreiber von spark.history.fs.logDirectory (Standard file:/tmp/spark-events); History muss spark.history.store.path gesetzt haben
LizenzGNU Affero GPL v3.0
Labnur 127.0.0.1:18990. Gadget des zitierten Joins. Witness-.rdb außerhalb von store.path.

Was ein Angreifer tun kann

Dasselbe Opfermodell wie bei CVE-2025-54920: Der History Server zeigt auf ein Log-Verzeichnis, in das der Angreifer schreiben kann. Jackson konstruiert keine Gadgets der Klasse HiveConnection mehr. Der Disk-Store-Pfad vertraut weiterhin der App-ID aus dem Event-JSON.

MethodeSinkBerechtigungLab vs. abgeleitet
Ein Event-Log platzieren, dessen JSON-App ID ../<name> (oder ../../oracle/...) ist. Auf den Scan warten. GET, das die App-UI lädt / getAppUI / loadDiskStore / createDiskStoreHistoryServerDiskManager.appStorePath, dann Lease.commit renameToIntegrität: einen .rdb-Pfad (Standard RocksDB) oder .ldb-Pfad (LevelDB) außerhalb von {store.path}/apps als History-UID anlegen. Im Lab am Gadget bewiesen: escaped=yes, Datei /work/oracle/SPARK-HISTORY-STORE-PATH-WITNESS.rdb enthält den Witness. Der Inhalt ist eine Store-Datei, kein vom Angreifer gewählter Host-Bytecode, keine Shell.Im Lab bewiesen (Gadget-Schreiben von Witness-Bytes am ausgelaufenen Pfad). Das vollständige History-renameTo eines RocksDB-Verzeichnisses ist derselbe Join.
Dieselbe App-ID, wenn das ausgelaufene Ziel bereits ein Verzeichnis istLease.commit if (dst.isDirectory()) deleteStore(dst), dann Utils.deleteRecursivelyVerfügbarkeit: ein bestehendes Verzeichnis löschen, dessen Name bereits mit dem Backend-Suffix endet, und es dann durch den geleasten Store ersetzen.Abgeleitet (Pin HistoryServerDiskManager.scala commit). Das Gadget schrieb eine Datei, rief kein deleteRecursively auf.
Standardmäßig nicht gesetztes spark.history.store.pathLOCAL_STORE_DIR createOptional; diskManager = storePath.mapGeschlossen. In-Memory-Listing. Kein HistoryServerDiskManager. Im Lab bewiesen gated=yes written=no.Im Lab bewiesen
Zuerst Utils.sanitizeDirName auf die App-ID anwendenEvent-Log-Dateinamen-HelferBleibt innerhalb von apps/. / und : werden zu -. Im Lab bewiesenes Negativ.Im Lab bewiesen
App-ID local-control mit gesetztem store.path kontrollierenderselbe JoinSchreibt {store.path}/apps/local-control.rdb. Bleibt innerhalb von apps/.Im Lab bewiesen

Angrenzend geschlossen: Standardmäßig nicht gesetzter Store (In-Memory). Jackson sparkEventFromJson erfordert weiterhin SparkListenerEvent (CVE-2025-54920). URL-getAppUI-Fallback eventlog_v2_ + nameForAppAndAttempt ist bereinigt. Der Listing-KV-Key ist kein Dateisystempfad. HybridStore / kvstore-Mapper hat kein Id.CLASS. History-HTTP akzeptiert keinen Upload-Pfad. Compaction standardmäßig aus. Cleaner standardmäßig aus. Job-Submit auf einem offenen Cluster (SECURITY.md FAQ). ML-Modell-Laden (docs/ml-security.md). Dieser Rest ist kein Host-RCE.

Wie ich es gefunden habe

Ich habe Spark 4.2.0 gepinnt, nicht master, nicht ein 4.3 RC. Achtundzwanzig Jagden. Das öffentliche History-Jackson-RCE ist auf diesem Peel geschlossen. Event-Log-Schreiber rufen bereits Utils.sanitizeDirName auf, sodass die Log-Datei kein / enthalten kann. Der Dateiname des Disk-Cache verwendet die rohe App-ID.

private[history] def appStorePath(appId: String, attemptId: Option[String]): File = {
  val fileName = appId + attemptId.map("_" + _).getOrElse("") + extension
  new File(appStoreDir, fileName)
}

appStoreDir ist {spark.history.store.path}/apps. Unix new File(parent, "../../oracle/name.rdb") löst außerhalb des Parents auf. JsonProtocol.applicationStartFromJson nimmt json.get("App ID").asText(). AppListingListener.onApplicationStart speichert event.appId.orNull. lease.commit(appId, attempt.info.attemptId) speist diesen String in appStorePath ein.

Bereits festgehaltene Irrwege: den standardmäßig nicht gesetzten store.path als Schreiben zu behandeln (er ist In-Memory); zu erwarten, dass Unix new File(dir, "/abs") den Parent ignoriert (tut es nicht; der Rest ist ..); RCE zu behaupten, weil das Suffix .rdb ist; einen vollständigen History Server zu booten, obwohl der Join das Orakel ist; sanitizeDirName als diesen Pfad abdeckend zu behandeln.

Lab

python3 spark-history-store-path-Abraxas-Labs.py

oder

cd lab
./run.sh

Gadget von HistoryServerDiskManager.appStorePath auf 127.0.0.1:18990. Pin-Auszüge unter lab/pin/. Der vollständige History Server wird nicht gebootet. Binde ihn an Loopback.

SUCCESS SPARK-HISTORY-STORE-PATH how=gadget escaped=yes gated=yes outside=/work/oracle/SPARK-HISTORY-STORE-PATH-WITNESS.rdb SPARK-HISTORY-STORE-PATH-WITNESS

Der Fix

Führe Utils.sanitizeDirName (oder lehne .. / / / NUL ab) auf appId und attemptId innerhalb von appStorePath vor new File aus. Verlange nach dem Join, dass dst.getCanonicalFile() unter appStoreDir.getCanonicalFile() bleibt. Ein nicht gesetztes spark.history.store.path bleibt der sichere Standard.

Referenzen

Tool herunterladen