Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
spark-connect-archive-fragment — Apache Spark 4.2.0 - Élevé - À distance - Écriture de fichier - Connect archives hash-fragment dest | Kitploit
Outils/GitHubGitHub/abraxas/spark-connect-archive-fragment
Analyse des VulnérabilitésExploitationExploitation d'Applications WebVirtualisation de SécuritéTests d'IntrusionRed TeamingLabs et Pratique
GitHub
abraxas/spark-connect-archive-fragment

spark-connect-archive-fragment

Apache Spark 4.2.0 - Élevé - À distance - Écriture de fichier - Connect archives hash-fragment dest

Voir le dépôt
il y a 2 joursPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Abraxas Labs - spark-connect-archive-fragment

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

spark-connect-archive-fragment

Classe : Écriture de fichier Portée : Distante

Apache Spark 4.2.0 (32f72996) - Apache Software Foundation

Les noms AddArtifacts de Spark Connect de la forme archives/<file>#<fragment> sont découpés sur le caractère dièse / signe numéro. Les octets du zip passent par concatenatePaths. Le fragment, non. SparkContext.addFile(..., isArchive=true) fait ensuite new File(root, uri.getFragment), deleteRecursively(dest), et unpack sur le driver. Les exécuteurs construisent la même dest. SPARK-33530 a documenté #name comme nom de répertoire sous SparkFiles. Un fragment ../<outside> constitue la dest.

Connect archives/<file>#../<path> décompresse et deleteRecursively en dehors du répertoire SparkFiles de la session en tant qu'UID Spark.

IDpas encore de CVE
ClasseÉcriture de fichier
PortéeDistante (client Spark Connect ; AddArtifacts avec archive=True)
CWECWE-22
CVSSÉlevé : 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H
ProduitApache Spark
Affecté4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8) dest du fragment-dièse de Connect archives/
AuthClient Connect. Connect par défaut n'a pas de PSK (spark.connect.authenticate.token non défini). PR:L si PSK / ACL réseau ; PR:N sur Connect ouvert par défaut.
LicenceGNU Affero GPL v3.0
Lab127.0.0.1 uniquement

J'ai épinglé le tag v4.2.0 peel 32f72996 (2026-07-11, v4.2.0-rc6). Le lab est un gadget Java du découpage de hash StagedArtifact épinglé, ArtifactUtils.concatenatePaths, new File(root, fragment), deleteRecursively, et décompression zip contenue dans la dest. HTTP en boucle locale sur 127.0.0.1:18930. Le PySpark officiel copie déjà un fragment d'URI dans le nom de l'archive.

Ce n'est pas une RCE. Les membres de zip qui sortent de la dest sont rejetés (classe Hadoop FileUtil.unZip / HADOOP-13649). Le reliquat est la dest elle-même.

Ce qu'un attaquant peut faire

MéthodeSinkPrivilège
Connect AddArtifacts nom archives/<file>#../<outside>dest SparkContext.addFile new File(root, uri.getFragment) puis Utils.unpack (SparkContext.scala:1891-1900)Intégrité (prouvé en lab) : écrire des membres d'archive en tant qu'UID Spark en dehors des SparkFiles de la session. Dest du lab canonique /lab/oracle/SPARK-CONNECT-ARCHIVE-FRAGMENT-WITNESS, uid 1000, dest-outside=yes.
Même dest, avant décompressionUtils.deleteRecursively(dest) (SparkContext.scala:1899)Disponibilité (prouvé en lab) : canari de dest disparu. Lab deleteRecursively=yes ; canary.txt sous la dest n'a pas survécu. Le voisin /lab/oracle/canary-keep.txt conservé.
Même primitive sur chaque exécuteur qui récupère l'archivedest Executor new File(root, sourceURI.getFragment) puis deleteRecursively + unpack (Executor.scala:1468-1477)Intégrité / disponibilité (inféré) : même construction de dest sur les exécuteurs. Le lab est le gadget côté driver.
Nom d'artefact files/../../... ou archives/../../...ArtifactUtils.concatenatePaths (ArtifactUtils.scala:26-39)Fermé (prouvé en lab) : INVALID_ARTIFACT_PATH.
Fragment absolu Unix /absnew File(root, "/abs")Fermé sur Unix (prouvé en lab) : le parent n'est pas ignoré ; la dest se joint sous root. Dest du lab /lab/root/lab/oracle/abs-..., outside=false, canari abs conservé.
Ajout jars/ / classes/ de sa propre sessionURLClassLoader de sessionFermé en tant que reliquat : le chargement de JAR de sa propre session est by design. Pas cette découverte.
Chargement de jar inter-sessionIsolation Connect spark.sql.artifact.isolation.enabled=trueFermé : les sessions isolées lisent addedJars(sessionUUID).

Prouvé en lab vs inféré : dest du fragment-dièse en dehors des SparkFiles, canari de dest supprimé, canari voisin conservé, concaténation de nom files/ et archives/ rejetée, fragment absolu Unix se joint sous root, uid 1000, décompression zip contenue dans la dest : lab. Récupération par l'exécuteur de la même dest : inféré (même constructeur). Écrasement d'une classe chargée ultérieurement sur le classpath du driver : chaîne inférée, non démontrée, non gonflée en RCE.

Nécessite : un client Connect capable de AddArtifacts avec archive=True. Le PySpark officiel spark.addArtifact(..., archive=True) place déjà un fragment d'URI non vide dans le nom (python/pyspark/sql/connect/client/artifact.py:223-236). Connect par défaut n'a pas de PSK.

Surface adjacente qui reste fermée

SurfaceLab
Nom d'artefact .. / absolu via concatenatePathsfiles-concat=rejected INVALID_ARTIFACT_PATH
Nom archives/ walk archives/../../...même INVALID_ARTIFACT_PATH
Unix new File(root, "/abs")dest sous root ; canari oracle abs conservé
Zip-slip de membre de zip sous une dest contenuele gadget rejette les membres qui s'échappent de la dest (classe HADOOP-13649). Pas ce reliquat.
Concaténation de chemin files/ (pas de découpage sur dièse)le fragment n'est pas pris ; le nom reste concatenatePaths
Isolation de jar inter-sessionactivée par défaut pour Connect
SQL / Python non authentifié sur Connect ouvertsoumission de job by design (FAQ SECURITY.md). Pas ce reliquat.
Soumission de job / chargement de modèle MLby design

Comment je l'ai trouvé

StagedArtifact ne découpe que les noms qui commencent par archives plus le File.separator du serveur, et uniquement sur # :

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

splits(0) est stagé via concatenatePaths. splits(1) est conservé comme fragment. ArtifactManager attache ce fragment à l'URI du file-server de la session et appelle SparkContext.addArchive. La dest est new File(root, uri.getFragment). Les tests SPARK-33530 utilisent sc.addArchive(s"${jarFile.getAbsolutePath}#foo") comme nom de répertoire sous SparkFiles.

La première passe de chasse a prétendu qu'un fragment absolu Unix ignore root (parent-ignore de java.io.File pour les enfants absolus). Sur Unix, new File(root, "/abs") supprime le slash initial et se joint sous root. Le parent n'est ignoré que sur Windows. Le walk Élevé sur ce pin est #../.

Lab

cd lab
./run.sh

Boucle locale 127.0.0.1:18930. Projet Compose spark-connect-archive-fragment. Image eclipse-temurin:21-jdk-jammy, uid d'exécution 1000. Témoin SPARK-CONNECT-ARCHIVE-FRAGMENT-WITNESS. Dernière ligne :

SUCCESS SPARK-CONNECT-ARCHIVE-FRAGMENT how=gadget dest-outside=yes deleteRecursively=yes files-concat=rejected uid=1000 SPARK-CONNECT-ARCHIVE-FRAGMENT-WITNESS
Télécharger l’outil