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-connect-archive-fragment — Apache Spark 4.2.0 - Alta - Remota - Escritura de archivos - Connect archives hash-fragment dest | Kitploit
Herramientas/GitHubGitHub/abraxas/spark-connect-archive-fragment
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebVirtualización de SeguridadPruebas de PenetraciónRed TeamingLabs y Práctica
GitHub
abraxas/spark-connect-archive-fragment

spark-connect-archive-fragment

Apache Spark 4.2.0 - Alta - Remota - Escritura de archivos - Connect archives hash-fragment dest

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-connect-archive-fragment

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

spark-connect-archive-fragment

Clase: Escritura de archivos Alcance: Remoto

Apache Spark 4.2.0 (32f72996) - Apache Software Foundation

Los nombres de AddArtifacts de Spark Connect con la forma archives/<file>#<fragment> se dividen por el carácter hash / signo de número. Los bytes del zip pasan por concatenatePaths. El fragmento no. SparkContext.addFile(..., isArchive=true) luego hace new File(root, uri.getFragment), deleteRecursively(dest) y unpack en el driver. Los ejecutores construyen el mismo dest. SPARK-33530 documentó #name como un nombre de directorio bajo SparkFiles. Un fragmento de ../<outside> es el dest.

Connect archives/<file>#../<path> descomprime y hace deleteRecursively fuera del directorio SparkFiles de la sesión como el UID de Spark.

IDsin CVE aún
ClaseEscritura de archivos
AlcanceRemoto (cliente 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
ProductoApache Spark
Afectado4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8) Connect archives/ dest de fragmento hash
AuthCliente Connect. Connect por defecto no tiene PSK (spark.connect.authenticate.token sin establecer). PR:L si hay PSK / ACL de red; PR:N en Connect abierto por defecto.
LicenciaGNU Affero GPL v3.0
Labsolo 127.0.0.1

Fijé el tag v4.2.0 peel 32f72996 (2026-07-11, v4.2.0-rc6). El lab es un gadget Java del split de hash de StagedArtifact fijado, ArtifactUtils.concatenatePaths, new File(root, fragment), deleteRecursively y descompresión de zip contenida en dest. HTTP en loopback sobre 127.0.0.1:18930. El PySpark oficial ya copia un fragmento de URI en el nombre del archivo.

Esto no es RCE. Los miembros del zip que salen de dest son rechazados (clase Hadoop FileUtil.unZip / HADOOP-13649). Lo que queda es el propio dest.

Qué puede hacer un atacante

MétodoSinkPrivilegio
Connect AddArtifacts nombre archives/<file>#../<outside>SparkContext.addFile dest new File(root, uri.getFragment) luego Utils.unpack (SparkContext.scala:1891-1900)Integridad (probado en lab): escribe miembros del archivo como el UID de Spark fuera de SparkFiles de la sesión. Dest del lab canónico /lab/oracle/SPARK-CONNECT-ARCHIVE-FRAGMENT-WITNESS, uid 1000, dest-outside=yes.
Mismo dest, antes de unpackUtils.deleteRecursively(dest) (SparkContext.scala:1899)Disponibilidad (probado en lab): canary de dest eliminado. Lab deleteRecursively=yes; canary.txt bajo dest no sobrevivió. Hermano /lab/oracle/canary-keep.txt conservado.
Misma primitiva en cada ejecutor que obtiene el archivoDest de Executor new File(root, sourceURI.getFragment) luego deleteRecursively + unpack (Executor.scala:1468-1477)Integridad / disponibilidad (inferido): misma construcción de dest en los ejecutores. El lab es el gadget del lado del driver.
Nombre de artefacto files/../../... o archives/../../...ArtifactUtils.concatenatePaths (ArtifactUtils.scala:26-39)Cerrado (probado en lab): INVALID_ARTIFACT_PATH.
Fragmento absoluto Unix /absnew File(root, "/abs")Cerrado en Unix (probado en lab): el padre no se ignora; dest se une bajo root. Dest del lab /lab/root/lab/oracle/abs-..., outside=false, canary abs conservado.
Añadir jars/ / classes/ de la propia sesiónURLClassLoader de la sesiónCerrado como remanente: la carga de JAR de la propia sesión es por diseño. No es este hallazgo.
Carga de jar entre sesionesAislamiento de Connect spark.sql.artifact.isolation.enabled=trueCerrado: las sesiones aisladas leen addedJars(sessionUUID).

Probado en lab vs inferido: dest de fragmento hash fuera de SparkFiles, canary de dest eliminado, canary hermano conservado, concatenación de nombres files/ y archives/ rechazada, fragmento absoluto Unix se une bajo root, uid 1000, descompresión de zip contenida en dest: lab. Obtención por el ejecutor del mismo dest: inferido (mismo constructor). Sobrescritura de una clase cargada posteriormente en el classpath del driver: cadena inferida, no demostrada, no inflada a RCE.

Requiere: un cliente Connect que pueda AddArtifacts con archive=True. El PySpark oficial spark.addArtifact(..., archive=True) ya coloca un fragmento de URI no vacío en el nombre (python/pyspark/sql/connect/client/artifact.py:223-236). Connect por defecto no tiene PSK.

Superficie adyacente que permanece cerrada

SuperficieLab
Nombre de artefacto .. / absoluto a través de concatenatePathsfiles-concat=rejected INVALID_ARTIFACT_PATH
Recorrido del nombre archives/ archives/../../...mismo INVALID_ARTIFACT_PATH
Unix new File(root, "/abs")dest bajo root; canary abs oracle conservado
Zip-slip de miembro de zip bajo un dest contenidoel gadget rechaza miembros que escapan de dest (clase HADOOP-13649). No es este remanente.
Concatenación de ruta files/ (sin split de hash)el fragmento no se toma; el nombre sigue siendo concatenatePaths
Aislamiento de jar entre sesionesactivado por defecto para Connect
SQL / Python sin autenticación en Connect abiertoenvío de trabajos por diseño (SECURITY.md FAQ). No es este remanente.
Envío de trabajos / carga de modelo MLpor diseño

Cómo lo encontré

StagedArtifact divide solo los nombres que comienzan con archives más el File.separator del servidor, y solo por #:

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

splits(0) se prepara vía concatenatePaths. splits(1) se conserva como fragment. ArtifactManager adjunta ese fragmento a la URI del file-server de la sesión y llama a SparkContext.addArchive. Dest es new File(root, uri.getFragment). Las pruebas de SPARK-33530 usan sc.addArchive(s"${jarFile.getAbsolutePath}#foo") como un nombre de directorio bajo SparkFiles.

La primera pasada de búsqueda afirmó que un fragmento absoluto Unix ignora root (ignorar el padre en java.io.File para hijos absolutos). En Unix, new File(root, "/abs") elimina la barra inicial y se une bajo root. El padre solo se ignora en Windows. El recorrido Alto en este pin es #../.

Lab

cd lab
./run.sh

Loopback 127.0.0.1:18930. Proyecto Compose spark-connect-archive-fragment. Imagen eclipse-temurin:21-jdk-jammy, uid de runtime 1000. Witness SPARK-CONNECT-ARCHIVE-FRAGMENT-WITNESS. Última línea:

SUCCESS SPARK-CONNECT-ARCHIVE-FRAGMENT how=gadget dest-outside=yes deleteRecursively=yes files-concat=rejected uid=1000 SPARK-CONNECT-ARCHIVE-FRAGMENT-WITNESS
Descargar herramienta