Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
spark-connect-archive-fragment — Apache Spark 4.2.0 - Alto - Remoto - Scrittura di file - Connect archivia hash-fragment dest | Kitploit
Strumenti/GitHubGitHub/abraxas/spark-connect-archive-fragment
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebVirtualizzazione per la SicurezzaPenetration TestingRed TeamingLab e Pratica
GitHub
abraxas/spark-connect-archive-fragment

spark-connect-archive-fragment

Apache Spark 4.2.0 - Alto - Remoto - Scrittura di file - Connect archivia hash-fragment dest

Vedi Repository
2 giorni faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

Abraxas Labs - spark-connect-archive-fragment

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  spark-connect-archive-fragment

spark-connect-archive-fragment

Classe: Scrittura di file Portata: Remota

Apache Spark 4.2.0 (32f72996) - Apache Software Foundation

I nomi AddArtifacts di Spark Connect nella forma archives/<file>#<fragment> vengono divisi sul carattere hash / cancelletto. I byte dello zip passano attraverso concatenatePaths. Il frammento no. SparkContext.addFile(..., isArchive=true) esegue poi new File(root, uri.getFragment), deleteRecursively(dest) e unpack sul driver. Gli executor costruiscono la stessa dest. SPARK-33530 documentava #name come nome di directory sotto SparkFiles. Un frammento di ../<outside> è la dest.

Connect archives/<file>#../<path> estrae e deleteRecursively al di fuori della directory SparkFiles della sessione come UID di Spark.

IDnessuna CVE al momento
ClasseScrittura di file
PortataRemota (client Spark Connect; AddArtifacts con archive=True)
CWECWE-22
CVSSAlto: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H
ProdottoApache Spark
Affetto4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8) Connect archives/ dest con frammento hash
AuthClient Connect. Connect predefinito non ha PSK (spark.connect.authenticate.token non impostato). PR:L se PSK / ACL di rete; PR:N su Connect aperto predefinito.
LicenzaGNU Affero GPL v3.0
Labsolo 127.0.0.1

Ho fissato il tag v4.2.0 peel 32f72996 (2026-07-11, v4.2.0-rc6). Il lab è un gadget Java della divisione hash di StagedArtifact fissata, ArtifactUtils.concatenatePaths, new File(root, fragment), deleteRecursively e estrazione zip contenuta nella dest. HTTP su loopback su 127.0.0.1:18930. PySpark ufficiale copia già un frammento URI nel nome dell'archivio.

Questo non è RCE. I membri dello zip che escono dalla dest vengono rifiutati (classe Hadoop FileUtil.unZip / HADOOP-13649). Ciò che rimane è la dest stessa.

Cosa può fare un attaccante

MetodoSinkPrivilegio
Connect AddArtifacts nome archives/<file>#../<outside>SparkContext.addFile dest new File(root, uri.getFragment) poi Utils.unpack (SparkContext.scala:1891-1900)Integrità (provato in lab): scrive i membri dell'archivio come UID di Spark al di fuori di SparkFiles della sessione. Dest del lab canonica /lab/oracle/SPARK-CONNECT-ARCHIVE-FRAGMENT-WITNESS, uid 1000, dest-outside=yes.
Stessa dest, prima dell'estrazioneUtils.deleteRecursively(dest) (SparkContext.scala:1899)Disponibilità (provato in lab): canary della dest sparito. Lab deleteRecursively=yes; canary.txt sotto la dest non è sopravvissuto. Il sibling /lab/oracle/canary-keep.txt conservato.
Stessa primitiva su ogni executor che recupera l'archivioDest dell'Executor new File(root, sourceURI.getFragment) poi deleteRecursively + unpack (Executor.scala:1468-1477)Integrità / disponibilità (inferito): stessa costruzione della dest sugli executor. Il lab è il gadget lato driver.
Nome dell'artefatto files/../../... o archives/../../...ArtifactUtils.concatenatePaths (ArtifactUtils.scala:26-39)Chiuso (provato in lab): INVALID_ARTIFACT_PATH.
Frammento assoluto Unix /absnew File(root, "/abs")Chiuso su Unix (provato in lab): il parent non viene ignorato; la dest si unisce sotto root. Dest del lab /lab/root/lab/oracle/abs-..., outside=false, canary abs conservato.
Aggiunta jars/ / classes/ della propria sessioneURLClassLoader della sessioneChiuso come residuo: il caricamento di JAR della propria sessione è by design. Non è questa la scoperta.
Caricamento di jar cross-sessioneIsolamento Connect spark.sql.artifact.isolation.enabled=trueChiuso: le sessioni isolate leggono addedJars(sessionUUID).

Provato in lab vs inferito: dest con frammento hash al di fuori di SparkFiles, canary della dest cancellato, canary sibling conservato, concatenazione dei nomi files/ e archives/ rifiutata, frammento assoluto Unix che si unisce sotto root, uid 1000, estrazione zip contenuta nella dest: lab. Recupero della stessa dest da parte dell'executor: inferito (stesso costruttore). Sovrascrittura di una classe caricata successivamente sul classpath del driver: catena inferita, non dimostrata, non gonfiata a RCE.

Richiede: un client Connect che possa eseguire AddArtifacts con archive=True. PySpark ufficiale spark.addArtifact(..., archive=True) mette già un frammento URI non vuoto nel nome (python/pyspark/sql/connect/client/artifact.py:223-236). Connect predefinito non ha PSK.

Superficie adiacente che rimane chiusa

SuperficieLab
Nome artefatto .. / assoluto attraverso concatenatePathsfiles-concat=rejected INVALID_ARTIFACT_PATH
Nome archives/ walk archives/../../...stesso INVALID_ARTIFACT_PATH
Unix new File(root, "/abs")dest sotto root; canary oracle abs conservato
Zip-slip di membro zip sotto una dest contenutail gadget rifiuta i membri che sfuggono alla dest (classe HADOOP-13649). Non questo residuo.
Concatenazione di percorso files/ (senza divisione hash)il frammento non viene preso; il nome è comunque concatenatePaths
Isolamento jar cross-sessioneattivo per impostazione predefinita per Connect
SQL / Python non autenticato su Connect apertoinvio job by-design (SECURITY.md FAQ). Non questo residuo.
Invio job / caricamento modello MLby design

Come l'ho trovato

StagedArtifact divide solo i nomi che iniziano con archives più il File.separator del server, e solo su #:

val splits = name.split("#")
if (splits.length == 2) {
  (splits(0), Some(splits(1)))
}

splits(0) viene preparato tramite concatenatePaths. splits(1) viene mantenuto come fragment. ArtifactManager collega quel frammento all'URI del file-server della sessione e chiama SparkContext.addArchive. La dest è new File(root, uri.getFragment). I test SPARK-33530 usano sc.addArchive(s"${jarFile.getAbsolutePath}#foo") come nome di directory sotto SparkFiles.

La prima passata di hunting sosteneva che un frammento assoluto Unix ignora root (ignoramento del parent di java.io.File per figli assoluti). Su Unix, new File(root, "/abs") rimuove la barra iniziale e si unisce sotto root. Il parent viene ignorato solo su Windows. Il walk High su questo pin è #../.

Lab

cd lab
./run.sh

Loopback 127.0.0.1:18930. Progetto Compose spark-connect-archive-fragment. Immagine eclipse-temurin:21-jdk-jammy, uid runtime 1000. Witness SPARK-CONNECT-ARCHIVE-FRAGMENT-WITNESS. Ultima riga:

SUCCESS SPARK-CONNECT-ARCHIVE-FRAGMENT how=gadget dest-outside=yes deleteRecursively=yes files-concat=rejected uid=1000 SPARK-CONNECT-ARCHIVE-FRAGMENT-WITNESS
Scarica lo strumento