Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
spark-python-ds-static — Apache Spark 4.2.0 - Alta - Remota - Privilegio residual - mapa global de procesos de Python Data Source | Kitploit
Herramientas/GitHubGitHub/abraxas/spark-python-ds-static
Escalada de PrivilegiosAnálisis de VulnerabilidadesExplotaciónPost-ExplotaciónPapers e InvestigaciónRed TeamingDesarrollo de PayloadsLabs y Práctica
GitHubabraxas/spark-python-ds-static

spark-python-ds-static

Apache Spark 4.2.0 - Alta - Remota - Privilegio residual - mapa global de procesos de Python Data Source

Ver Repositorio
hace 2 díasAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

Abraxas Labs - spark-python-ds-static

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

spark-python-ds-static

Clase: Privilegio residual Alcance: Remoto

Apache Spark 4.2.0 (32f72996) - Apache Software Foundation

DataSourceManager.dataSourceBuilders es un mapa global de la JVM en el que gana el primero. SPARK-45917 autorregistra los orígenes de datos de Python pyspark_* desde el sys.path del worker de búsqueda. El aislamiento de sesión de Connect mantiene los artefactos bajo SparkFiles/<sessionUUID>/, y el registerPython por sesión permanece en runtimeDataSourceBuilders. La primera búsqueda aún coloca el directorio SparkFiles de la sesión que la desencadena en sys.path, serializa cada DefaultSource y almacena en caché esas clases en el objeto compañero. Las posteriores consultas SQL de Connect (o SQL de Hive Thrift) read.format(name) / USING name ejecutan esa clase como el UID de Spark sin enviar el proto de Python.

El plantador es un inquilino de Connect Python al que ya se le permite Python. La víctima es un inquilino solo de SQL en el mismo driver de Connect. Los alias de Java (parquet, csv, json, orc, jdbc) permanecen en la ruta del ServiceLoader de Java. Las plantaciones posteriores una vez llenado el mapa no se refrescan. AC:H es la primera búsqueda más un nombre que no es un alias de Java.

IDaún sin CVE
ClasePrivilegio residual (origen de datos de Python entre sesiones como UID de Spark; no es envío de trabajos sin autenticación)
AlcanceRemoto (driver de Spark Connect compartido)
CWECWE-269, CWE-502
CVSSAlto: 8.8 CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H
ProductoApache Spark
Afectado4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8) registro estático de orígenes de datos de Python
AutenticaciónInquilino de Connect Python (plantador) más un usuario posterior solo de SQL de Connect / SQL de Hive Thrift (víctima)
LicenciaGNU Affero GPL v3.0
Laboratoriosolo 127.0.0.1:18970. Archivo testigo. Gadget del mapa compañero.

Qué puede hacer un atacante

Mantener una sesión de Spark Connect Python en un driver compartido. Plantar pyfiles/pyspark_<name>.py cuyo DefaultSource.name() sea un nombre corto de conector ausente (delta, iceberg, hudi, ...). Desencadenar la primera búsqueda de origen de datos de Python en esa sesión. Cualquier sesión posterior en la misma JVM que haga read.format(name) o SQL USING name instancia la clase serializada como el UID de Spark en el worker planificador del driver y en los ejecutores.

Ese es el conjunto completo de privilegios. El plantador ya ejecuta Python. Lo residual es que un inquilino solo de SQL, que nunca envió REGISTER_DATA_SOURCE / proto de UDF de Python, aún ejecuta esa clase.

Integridad (probado en laboratorio)

MétodoSumideroPrivilegio
Plantador: AddArtifacts con nombre pyfiles/pyspark_<name>.py y luego el primer format(name) / búsquedacompañero DataSourceManager.dataSourceBuilders (objeto DataSourceManager.scala) más lookup_data_sources.py iter_modules de pyspark_*Almacenar en caché el DefaultSource serializado de la sesión que lo desencadena en toda la JVM. Laboratorio: layer='static' trigger='attacker' first-wins=yes.
Víctima: SQL USING <name> / spark.read.format(name) en una sesión que nunca plantóPythonDataSourceV2 createDataSourceInPythonEjecutar esa clase como UID de Spark. Laboratorio: planted_by='attacker' witness_written=True static-cross-session=yes. El archivo oráculo contiene SPARK-PYTHON-DS-STATIC-WITNESS.

Cerrado en este recorrido (probado en laboratorio)

MétodoSumideroResultado
Plantación posterior de un segundo nombre una vez llenado el mapael mismo mapa estáticoCerrado. Gana el primero. Laboratorio: later-lookup found=False, el compañero sigue siendo solo delta.
registerPython("alpha") por sesiónruntimeDataSourceBuildersAislado. El clon copia solo el runtime. Laboratorio: runtime-isolated=yes. La lectura de alpha por la víctima es found=False.
Alias de Java parquetDataSourceRegister ServiceLoader de JavaCerrado. Laboratorio: java-alias-closed=yes layer='java'. Igual para csv/json/orc/jdbc.

Inferido (mismos sumideros, no el oráculo)

MétodoSumideroPrivilegio
USING de la víctima tras la plantaciónworkers de Python del driver + ejecutorCódigo en todo el clúster como UID de Spark. El laboratorio escribe un archivo testigo en lugar de un payload.
La misma rutacaída / giro del workerDisponibilidad como UID de Spark. No es el Alto. El Alto es la ejecución de código.
SQL de Hive Thrift USING en un SparkSession compartidoel mismo mapa estáticoEl mismo residual si Thrift y Connect comparten la JVM del driver. No ejercitado.

Lo que este residual no otorga

  • Envío de trabajos sin autenticación en un clúster abierto. FAQ de SECURITY.md. Por diseño.
  • Secuestro de parquet / csv / json / orc / jdbc de Java. Gana ServiceLoader.
  • Escape de la ruta de artefactos (concatenatePaths rechaza .. y nombres absolutos).
  • pythonExec proporcionado por el cliente. El planificador de Connect usa PYSPARK_PYTHON / python3 del servidor.
  • Fuga entre sesiones de registerPython. El mapa de runtime es por instancia de DataSourceManager.
  • pyspark local monousuario con una sola sesión. No hay otro inquilino.
  • Una búsqueda fallida inicial que llena un mapa vacío. Las plantaciones posteriores no se refrescan (AC:H).

Cómo lo encontré

Fijé apache/spark v4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8). Veintiocho búsquedas en el código fuente. El envío de trabajos que ejecuta código de usuario es por diseño. History Jackson, el shell de la UI, la suplantación local de PySpark y la ruta de recepción RPC independiente están cerrados en este análisis. Los artefactos de Connect aíslan los pyfiles bajo un UUID de sesión. El registerPython de runtime es por sesión. El objeto compañero no lo es.

SPARK-45917 autorregistra paquetes pyspark_* desde PYTHONPATH. Eso está pensado para conectores instalados por el operador. Lo residual es que el worker de búsqueda también hace sys.path.insert del directorio SparkFiles de la sesión que lo desencadena (worker_util.setup_spark_files), y luego serializa cualquier DefaultSource de pyspark_* que encuentre en un mapa global del proceso que nunca se refresca.

Mal camino: tratar el aislamiento de registerPython como toda la barrera entre inquilinos. El runtime está aislado. El estático no.

Laboratorio

cd lab
./run.sh
Descargar herramienta