Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
spark-history-zip-symlink — Apache Spark 4.2.0 - Alta - Remoto - Leitura de arquivo - History zip segue symlink plantado | Kitploit
Ferramentas/GitHubGitHub/abraxas/spark-history-zip-symlink
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebColeta de InformaçõesTestes de PenetraçãoPapers e Pesquisa
GitHubabraxas/spark-history-zip-symlink

spark-history-zip-symlink

Apache Spark 4.2.0 - Alta - Remoto - Leitura de arquivo - History zip segue symlink plantado

Ver Repositório
4há 4 diasAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Abraxas Labs - spark-history-zip-symlink

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

spark-history-zip-symlink

Classe: Leitura de arquivo Alcance: Remoto

Apache Spark 4.2.0 (32f72996) - Apache Software Foundation

O CVE-2025-54920 travou o Jackson do History Server para que sparkEventFromJson apenas construísse subclasses de SparkListenerEvent. O rolling zipEventLogFiles ainda despeja todo filho de listStatus via FileSystem.open. O LocalFileSystem segue um symlink POSIX. Um filho plantado em eventlog_v2_* é empacotado no GET /api/v1/applications/{id}/logs sem autenticação. O corpo do membro do zip é o alvo do SHS-UID. O nome da entrada é o basename do symlink.

Isto não é um re-registro do RCE do Jackson. O Jackson permanece fechado. Isto não é RCE no host. Integridade e disponibilidade são nulas.

IDainda sem CVE
ClasseLeitura de arquivo (resíduo do zip rolling do modelo de vítima do CVE-2025-54920)
AlcanceRemoto (escritor do diretório de log do History mais GET não autenticado do 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
ProdutoApache Spark
Afetado4.2.0 tag v4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8)
AutenticaçãoPR:L = escrita em spark.history.fs.logDirectory (mesma vítima do 54920). ACLs da UI do History desativadas por padrão.
LicençaGNU Affero GPL v3.0
Labapenas 127.0.0.1:18980

O que um atacante pode fazer

Alguém que consiga escrever em spark.history.fs.logDirectory (padrão file:/tmp/spark-events) pode plantar um diretório rolling que o History Server irá zipar. Os escritores rolling estão ativados por padrão. As ACLs da UI do History estão desativadas por padrão. O UID do processo SHS é o deputy confundido.

PrivilégioMétodo / sinkComprovado em lab ou inferido
Confidencialidade: ler um arquivo do host que o UID do SHS consegue abrirPlantar eventlog_v2_<id>/ com appstatus_* válido mais JSON events_* (SparkListenerLogStart / SparkListenerApplicationStart) mais um filho symlink cujo alvo fica fora do diretório de log. Aguardar o scan. GET /api/v1/applications/{id}/logs sem autenticação (OneApplicationResource.getEventLogs -> FsHistoryProvider.writeEventLogs -> RollingEventLogFilesFileReader.zipEventLogFiles -> FileSystem.open)Comprovado em lab. O corpo do membro do zip eventlog_v2_app-2026-0001/planted-secret é SPARK-HISTORY-ZIP-SYMLINK-WITNESS. O membro de events não tem witness. O nome da entrada permanece o basename do symlink, não o caminho do alvo.
Confidencialidade: log de eventos de tenant irmão que o atacante não consegue open (660)Mesmo zip, alvo do symlink é o log de outro appInferido. Mesmo FileSystem.open. Não exercitado.
Confidencialidade: keytab, spark-env.sh, /etc/passwd se o SHS conseguir lê-losMesmo zipInferido. O oráculo é um /secret/host-secret dedicado, não esses arquivos.
Integridade de arquivos do SHS ou do hosto zip é lido para o corpo HTTPFechado. Comprovado em lab como nulo.
Disponibilidade de arquivos do SHS ou do hosto zip não apaga nem trunca o alvoFechado. Comprovado em lab como nulo.
RCE no host / construção de gadget JacksonJsonProtocol.sparkEventFromJsonFechado. SparkListenerEvent obrigatório. Este lab planta apenas JSON de Event benigno.
Zip slip de ../ no nome da entradaPath.getName()Fechado. Nome de arquivo POSIX não pode conter /. A entrada é eventlog_v2_<id>/<basename>.
Escape de string de caminho de resolveLogPathnew Path(logDir, attempt.logPath)Fechado. O objeto Path permanece sob o diretório de log configurado. O escape é o inode.
Reescrita de compactação / exclusão do alvo pelo cleanerspark.history.fs.eventLog.rolling.maxFilesToRetain padrão Integer.MAX_VALUE; cleaner desativado por padrãoFechado. O fs.delete local de um symlink desvincula o link, não o alvo.
Submissão de job sem autenticação / carregamento de modelo MLFAQ do SECURITY.md / docs/ml-security.mdFechado. Por design, não este resíduo.

Como eu encontrei

Fixe em apache/spark v4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8) em vez de master ou um RC 4.3. Vinte e oito caçadas. O RCE do Jackson no History está fechado nesta revisão (JsonProtocol.scala:965-972). O History Server ainda apontava para um diretório de log gravável pelo atacante, que é o mesmo modelo de vítima do CVE-2025-54920.

zipEventLogFiles zipa todos os files, não apenas arquivos de evento:

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 é fileSystem.open e depois transferTo. O LocalFileSystem segue symlinks POSIX. getLogDirInfo comenta "handles symbolic links properly" e então percorre pais de Path não resolvidos para um nome de exibição.

Caminhos errados já registrados: tratar SPARK-52381 como toda a história do History; plantar o witness em events_* (o lab falha nisso); esperar que a entrada do zip carregue o caminho do alvo; tratar o prefix-join de resolveLogPath como o escape; tentar uma classe Event de HiveConnection nesta revisão.

Lab

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

ou

cd lab
./run.sh

Gadget do dump do zip rolling de EventLogFileReaders.scala, não um History Server completo e não a imagem oficial spark:4.2.0. Ele não faz parsing de Event JSON através do Jackson. Loopback 127.0.0.1:18980. Projeto Compose spark-history-zip-symlink. O diretório rolling contém appstatus_* + events_* válidos (sem witness) mais planted-secret -> /secret/host-secret.

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

A correção

Empacotar apenas filhos events_* / appstatus_*, não todo nome de listStatus. Abrir com no-follow (O_NOFOLLOW / opções no-symlink do Hadoop) e rejeitar um filho cujo realpath esteja fora de spark.history.fs.logDirectory. Um helper de nome de exibição não é uma verificação de realpath.

Referências

Baixar ferramenta