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-python-ds-static — Apache Spark 4.2.0 - Élevé - À distance - Résidu de privilèges - table de sources de données Python globale au processus | Kitploit
Outils/GitHubGitHub/abraxas/spark-python-ds-static
Escalade de PrivilègesAnalyse des VulnérabilitésExploitationPost-ExploitationArticles et RechercheRed TeamingDéveloppement de Charges UtilesLabs et Pratique
GitHubabraxas/spark-python-ds-static

spark-python-ds-static

Apache Spark 4.2.0 - Élevé - À distance - Résidu de privilèges - table de sources de données Python globale au processus

Voir le dépôt
17il y a 8 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-python-ds-static

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  spark-python-ds-static

Write-up : https://abraxaslabs.tech/research/spark-python-ds-static

spark-python-ds-static

Classe : Résidu de privilège Portée : Distante

Apache Spark 4.2.0 (32f72996) - Apache Software Foundation

DataSourceManager.dataSourceBuilders est une map JVM-globale où le premier arrivé l'emporte. SPARK-45917 enregistre automatiquement les sources de données Python pyspark_* depuis le sys.path du worker de lookup. L'isolation des sessions Connect maintient les artefacts sous SparkFiles/<sessionUUID>/, et le registerPython par session reste sur runtimeDataSourceBuilders. Le premier lookup place néanmoins le répertoire SparkFiles de la session déclencheuse sur sys.path, sérialise (pickle) chaque DefaultSource et met en cache ces classes dans l'objet compagnon. Un read.format(name) / USING name ultérieur en Connect SQL (ou Hive Thrift SQL) exécute cette classe en tant qu'UID Spark sans envoyer de proto Python.

Le planteur est un locataire Python Connect qui est déjà autorisé à utiliser Python. La victime est un locataire SQL uniquement sur le même driver Connect. Les alias Java (parquet, csv, json, orc, jdbc) restent sur le chemin Java ServiceLoader. Les plantations ultérieures, une fois la map remplie, ne rafraîchissent pas. AC:H correspond au premier lookup plus un nom qui n'est pas un alias Java.

IDpas encore de CVE
ClasseRésidu de privilège (source de données Python inter-sessions en tant qu'UID Spark ; pas une soumission de job non authentifiée)
PortéeDistante (driver Spark Connect partagé)
CWECWE-269, CWE-502
CVSSÉlevé : 8.8 CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H
ProduitApache Spark
Affecté4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8) registre statique des sources de données Python
AuthLocataire Python Connect (planteur) plus un utilisateur ultérieur SQL uniquement Connect / Hive Thrift SQL (victime)
LicenceGNU Affero GPL v3.0
Lab127.0.0.1:18970 uniquement. Fichier témoin. Gadget de la map compagnon.

Ce qu'un attaquant peut faire

Maintenir une session Python Spark Connect sur un driver partagé. Planter pyfiles/pyspark_<name>.py dont DefaultSource.name() est un nom court de connecteur absent (delta, iceberg, hudi, ...). Déclencher le premier lookup de source de données Python sur cette session. Toute session ultérieure dans la même JVM qui fait read.format(name) ou SQL USING name instancie la classe sérialisée en tant qu'UID Spark sur le worker du planificateur du driver et sur les exécuteurs.

C'est l'ensemble complet des privilèges. Le planteur exécute déjà Python. Le résidu est qu'un locataire SQL uniquement, qui n'a jamais envoyé de proto REGISTER_DATA_SOURCE / Python UDF, exécute tout de même cette classe.

Intégrité (prouvé en lab)

MéthodePoint de chutePrivilège
Planteur : AddArtifacts nom pyfiles/pyspark_<name>.py puis premier format(name) / lookupDataSourceManager.dataSourceBuilders compagnon (objet DataSourceManager.scala) plus lookup_data_sources.py iter_modules de pyspark_*Met en cache le DefaultSource sérialisé de la session déclencheuse à l'échelle de la JVM. Lab : layer='static' trigger='attacker' first-wins=yes.
Victime : SQL USING <name> / spark.read.format(name) sur une session qui n'a jamais plantéPythonDataSourceV2 createDataSourceInPythonExécute cette classe en tant qu'UID Spark. Lab : planted_by='attacker' witness_written=True static-cross-session=yes. Le fichier oracle contient SPARK-PYTHON-DS-STATIC-WITNESS.

Fermé sur ce parcours (prouvé en lab)

MéthodeSinkRésultat
Plantage ultérieur d'un second nom après que la map a été rempliemême map statiqueFermé. Premier arrivé, premier servi. Lab : later-lookup found=False, le companion ne contient toujours que delta.
registerPython("alpha") par sessionruntimeDataSourceBuildersIsolé. Le clone ne copie que le runtime. Lab : runtime-isolated=yes. La lecture de alpha par la victime donne found=False.
Alias Java parquetServiceLoader de DataSourceRegister JavaFermé. Lab : java-alias-closed=yes layer='java'. Idem pour csv/json/orc/jdbc.

Déduit (mêmes sinks, pas l'oracle)

MéthodeSinkPrivilège
USING de la victime après le plantageworkers Python du driver + de l'executorCode à l'échelle du cluster en tant qu'UID Spark. Le lab écrit un fichier témoin au lieu d'une charge utile.
Même chemincrash / spin du workerDisponibilité en tant qu'UID Spark. Ce n'est pas le High. Le High, c'est l'exécution de code.
USING SQL Hive Thrift sur une SparkSession partagéemême map statiqueMême résidu si Thrift et Connect partagent la JVM du driver. Non exercé.

Ce que ce résidu n'accorde pas

  • Soumission de job non authentifiée sur un cluster ouvert. FAQ de SECURITY.md. Par conception.
  • Détournement Java parquet / csv / json / orc / jdbc. ServiceLoader l'emporte.
  • Évasion de chemin d'artefact (concatenatePaths rejette .. et les noms absolus).
  • pythonExec fourni par le client. Le planner Connect utilise PYSPARK_PYTHON / python3 du serveur.
  • Fuite inter-sessions de registerPython. La map runtime est propre à chaque instance de DataSourceManager.
  • pyspark local mono-utilisateur avec une seule session. Il n'y a pas d'autre locataire.
  • Une recherche miss-first qui remplit une map vide. Les plantages ultérieurs ne rafraîchissent pas (AC:H).

Comment je l'ai trouvé

J'ai épinglé apache/spark v4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8). Vingt-huit recherches dans le code source. La soumission de job exécutant du code utilisateur est par conception. L'historique Jackson, le shell de l'UI, l'usurpation locale PySpark et le chemin de réception RPC standalone sont fermés sur cette analyse. Les artefacts Connect isolent les pyfiles sous un UUID de session. Le registerPython runtime est par session. L'objet companion ne l'est pas.

SPARK-45917 enregistre automatiquement les paquets pyspark_* depuis PYTHONPATH. C'est prévu pour les connecteurs installés par l'opérateur. Le résidu, c'est que le worker de recherche fait aussi un sys.path.insert du répertoire SparkFiles de la session déclencheuse (worker_util.setup_spark_files), puis picklise tout DefaultSource pyspark_* qu'il trouve dans une map globale au processus qui ne se rafraîchit jamais.

Fausse piste : considérer l'isolation de registerPython comme l'unique barrière entre locataires. Le runtime est isolé. Le statique ne l'est pas.

Lab

cd lab
./run.sh
Télécharger l’outil