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-history-zip-symlink — Apache Spark 4.2.0 - Alta - Remoto - Lectura de archivos - El zip de historial sigue un enlace simbólico plantado | Kitploit
Herramientas/GitHubGitHub/abraxas/spark-history-zip-symlink
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebRecopilación de InformaciónPruebas de PenetraciónPapers e Investigación
GitHubabraxas/spark-history-zip-symlink

spark-history-zip-symlink

Apache Spark 4.2.0 - Alta - Remoto - Lectura de archivos - El zip de historial sigue un enlace simbólico plantado

Ver Repositorio
4hace 5 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-history-zip-symlink

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  spark-history-zip-symlink

spark-history-zip-symlink

Clase: Lectura de archivos Alcance: Remoto

Apache Spark 4.2.0 (32f72996) - Apache Software Foundation

CVE-2025-54920 bloqueó Jackson en el History Server para que sparkEventFromJson solo construya subclases de SparkListenerEvent. El rolling zipEventLogFiles sigue volcando cada hijo de listStatus mediante FileSystem.open. LocalFileSystem sigue un enlace simbólico POSIX. Un hijo plantado en eventlog_v2_* se empaqueta en el GET /api/v1/applications/{id}/logs sin autenticación. El cuerpo del miembro del zip es el objetivo del UID del SHS. El nombre de la entrada es el basename del enlace simbólico.

Esto no es una re-presentación del RCE de Jackson. Jackson permanece cerrado. Esto no es RCE del host. La integridad y la disponibilidad no se ven afectadas.

IDsin CVE todavía
ClaseLectura de archivos (residuo del zip rolling del modelo de víctima de CVE-2025-54920)
AlcanceRemoto (escritor del directorio de logs del History más GET sin autenticación del zip)
CWECWE-59, CWE-22
CVSSAlto: 7.5 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
ProductoApache Spark
Afectado4.2.0 tag v4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8)
AuthPR:L = escritura en spark.history.fs.logDirectory (misma víctima que 54920). Las ACLs de la UI del History están desactivadas por defecto.
LicenciaGNU Affero GPL v3.0
Labsolo 127.0.0.1:18980

Qué puede hacer un atacante

Alguien que pueda escribir en spark.history.fs.logDirectory (por defecto file:/tmp/spark-events) puede plantar un directorio rolling que el History Server comprimirá en zip. Los escritores rolling están activados por defecto. Las ACLs de la UI del History están desactivadas por defecto. El UID del proceso SHS es el deputy confundido.

PrivilegioMétodo / sinkProbado en lab o inferido
Confidencialidad: leer un archivo del host que el UID del SHS pueda abrirPlantar eventlog_v2_<id>/ con appstatus_* válido más JSON events_* (SparkListenerLogStart / SparkListenerApplicationStart) más un hijo de enlace simbólico cuyo objetivo esté fuera del directorio de logs. Esperar al escaneo. GET /api/v1/applications/{id}/logs sin autenticación (OneApplicationResource.getEventLogs -> FsHistoryProvider.writeEventLogs -> RollingEventLogFilesFileReader.zipEventLogFiles -> FileSystem.open)Probado en lab. El cuerpo del miembro del zip eventlog_v2_app-2026-0001/planted-secret es SPARK-HISTORY-ZIP-SYMLINK-WITNESS. El miembro de events no tiene witness. El nombre de la entrada permanece como el basename del enlace simbólico, no la ruta objetivo.
Confidencialidad: log de eventos de un inquilino hermano que el atacante no puede open (660)Mismo zip, el objetivo del enlace simbólico es el log de otra appInferido. Mismo FileSystem.open. No ejercitado.
Confidencialidad: keytab, spark-env.sh, /etc/passwd si el SHS puede leerlosMismo zipInferido. El oráculo es un /secret/host-secret dedicado, no esos archivos.
Integridad de archivos del SHS o del hostel zip se lee en el cuerpo HTTPCerrado. Probado en lab: ninguno.
Disponibilidad de archivos del SHS o del hostel zip no elimina ni trunca el objetivoCerrado. Probado en lab: ninguno.
RCE del host / construcción de gadget de JacksonJsonProtocol.sparkEventFromJsonCerrado. Se requiere SparkListenerEvent. Este lab solo planta JSON de Event benigno.
Zip slip de ../ en el nombre de la entradaPath.getName()Cerrado. Un nombre de archivo POSIX no puede contener /. La entrada es eventlog_v2_<id>/<basename>.
Escape de la cadena de ruta de resolveLogPathnew Path(logDir, attempt.logPath)Cerrado. El objeto Path permanece bajo el directorio de logs configurado. El escape es el inodo.
Reescritura por compactación / borrado por cleaner del objetivospark.history.fs.eventLog.rolling.maxFilesToRetain por defecto Integer.MAX_VALUE; cleaner desactivado por defectoCerrado. El fs.delete local de un enlace simbólico desvincula el enlace, no el objetivo.
Envío de jobs sin autenticación / carga de modelos MLFAQ de SECURITY.md / docs/ml-security.mdCerrado. Por diseño, no este residuo.

Cómo lo encontré

Fijé apache/spark v4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8) en lugar de master o un RC de 4.3. Veintiocho cacerías. El RCE de Jackson en el History está cerrado en este peel (JsonProtocol.scala:965-972). El History Server seguía apuntando a un directorio de logs escribible por el atacante, que es el mismo modelo de víctima que CVE-2025-54920.

zipEventLogFiles comprime en zip todos los files, no solo los archivos de eventos:

override def zipEventLogFiles(zipStream: ZipOutputStream): Unit = {
  val dirEntryName = rootPath.getName + "/"
  zipStream.putNextEntry(new ZipEntry(dirEntryName))
  files.foreach { file =>
    addFileAsZipEntry(zipStream, file.getPath, dirEntryName + file.getPath.getName)
  }
}

addFileAsZipEntry es fileSystem.open y luego transferTo. LocalFileSystem sigue enlaces simbólicos POSIX. getLogDirInfo comenta "handles symbolic links properly" y luego recorre los padres del Path sin resolver para obtener un nombre para mostrar.

Caminos equivocados ya registrados: tratar SPARK-52381 como toda la historia del History; plantar el witness en events_* (el lab falla eso); esperar que la entrada del zip lleve la ruta objetivo; tratar el prefix-join de resolveLogPath como el escape; probar una clase Event de HiveConnection en este pin.

Lab

python3 spark-history-zip-symlink-Abraxas-Labs.py

o

cd lab
./run.sh

Gadget del volcado del zip rolling de EventLogFileReaders.scala, no un History Server completo ni la imagen oficial spark:4.2.0. No parsea JSON de Event a través de Jackson. Loopback 127.0.0.1:18980. Proyecto de Compose spark-history-zip-symlink. El directorio rolling contiene appstatus_* + events_* válidos (sin witness) más planted-secret -> /secret/host-secret.

SUCCESS SPARK-HISTORY-ZIP-SYMLINK SPARK-HISTORY-ZIP-SYMLINK-WITNESS

La solución

Empaquetar solo los hijos events_* / appstatus_*, no cada nombre de listStatus. Abrir sin seguir enlaces (O_NOFOLLOW / opciones no-symlink de Hadoop) y rechazar un hijo cuyo realpath esté fuera de spark.history.fs.logDirectory. Un helper de nombre para mostrar no es una comprobación de realpath.

Referencias

Descargar herramienta