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-store-path — Apache Spark 4.2.0 - Alta - Remoto - Gravação de arquivo - History appStorePath App ID não sanitizado | Kitploit
Ferramentas/GitHubGitHub/abraxas/spark-history-store-path
Análise EstáticaAnálise de VulnerabilidadesAnálise de CódigoExploraçãoExploração de Aplicações WebTestes de PenetraçãoLabs e Prática
GitHub
abraxas/spark-history-store-path

spark-history-store-path

Apache Spark 4.2.0 - Alta - Remoto - Gravação de arquivo - History appStorePath App ID não sanitizado

Ver Repositório
há 2 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-store-path

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

spark-history-store-path

Classe: Escrita de arquivo (controlada por configuração) Alcance: Remoto

Apache Spark 4.2.0 (32f72996) - Apache Software Foundation

HistoryServerDiskManager.appStorePath faz new File(appStoreDir, appId + extension) sem sanitização. Utils.sanitizeDirName serve apenas para nomes de arquivo de event-log. O App ID do JSON é asText(). A listagem armazena event.appId.orNull. Lease.commit usa essa string. App ID ../ grava um .rdb fora de spark.history.store.path. O padrão não definido de store.path é em memória (sem escrita). O conteúdo é um arquivo de store, não RCE.

IDsem CVE ainda
ClasseEscrita de arquivo (store em disco do History controlado por configuração)
AlcanceRemoto (escritor de event-log mais History com spark.history.store.path definido; ACLs da UI desativadas por padrão)
CWECWE-22
CVSSAlto: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N quando spark.history.store.path está definido
ProdutoApache Spark History Server
Afetado4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8)
Autenticaçãoescritor de spark.history.fs.logDirectory (padrão file:/tmp/spark-events); o History deve ter spark.history.store.path definido
LicençaGNU Affero GPL v3.0
Labapenas 127.0.0.1:18990. Gadget do join citado. Witness .rdb fora de store.path.

O que um atacante pode fazer

Mesmo modelo de vítima que CVE-2025-54920: History Server apontado para um diretório de log no qual o atacante pode escrever. O Jackson não constrói mais gadgets da classe HiveConnection. O caminho do disk-store ainda confia no App ID do event-JSON.

MétodoSinkPrivilégioLab vs inferido
Plantar um event log cujo App ID no JSON seja ../<name> (ou ../../oracle/...). Aguardar o scan. GET que carrega a UI do app / getAppUI / loadDiskStore / createDiskStoreHistoryServerDiskManager.appStorePath e então Lease.commit renameToIntegridade: criar um caminho .rdb (RocksDB por padrão) ou .ldb (LevelDB) fora de {store.path}/apps como o UID do History. Comprovado em lab no gadget: escaped=yes, o arquivo /work/oracle/SPARK-HISTORY-STORE-PATH-WITNESS.rdb contém o witness. O conteúdo é um arquivo de store, não bytecode de host escolhido pelo atacante, não um shell.Comprovado em lab (gravação do gadget dos bytes do witness no caminho escapado). O renameTo completo do History de um diretório RocksDB é o mesmo join.
Mesmo App ID quando o destino escapado já é um diretórioLease.commit if (dst.isDirectory()) deleteStore(dst) e então Utils.deleteRecursivelyDisponibilidade: excluir um diretório existente cujo nome já termina com o sufixo do backend, e então substituí-lo pelo store arrendado.Inferido (fixar HistoryServerDiskManager.scala commit). O gadget gravou um arquivo, não chamou deleteRecursively.
Padrão não definido de spark.history.store.pathLOCAL_STORE_DIR createOptional; diskManager = storePath.mapFechado. Listagem em memória. Sem HistoryServerDiskManager. Comprovado em lab gated=yes written=no.Comprovado em lab
Aplicar Utils.sanitizeDirName ao App ID primeirohelper de nome de arquivo de event-logPermanece dentro de apps/. / e : tornam-se -. Comprovado em lab negativo.Comprovado em lab
Controlar App ID local-control com store.path definidomesmo joinGrava {store.path}/apps/local-control.rdb. Permanece dentro de apps/.Comprovado em lab

Adjacentes fechados: store padrão não definido (em memória). Jackson sparkEventFromJson ainda exige SparkListenerEvent (CVE-2025-54920). O fallback de URL getAppUI eventlog_v2_ + nameForAppAndAttempt é sanitizado. A chave KV da listagem não é um caminho de filesystem. O mapper HybridStore / kvstore não tem Id.CLASS. O HTTP do History não aceita um caminho de upload. Compactação desativada por padrão. Cleaner desativado por padrão. Submissão de job em um cluster aberto (SECURITY.md FAQ). Carregamento de modelo ML (docs/ml-security.md). Este resíduo não é RCE de host.

Como eu encontrei

Fiz pin do Spark 4.2.0, não do master, não de um RC 4.3. Vinte e oito caçadas. O RCE público do Jackson no History está fechado nesta peel. Escritores de event-log já chamam Utils.sanitizeDirName, então o arquivo de log não pode conter /. O nome do arquivo do disk-cache usa o App ID bruto.

private[history] def appStorePath(appId: String, attemptId: Option[String]): File = {
  val fileName = appId + attemptId.map("_" + _).getOrElse("") + extension
  new File(appStoreDir, fileName)
}

appStoreDir é {spark.history.store.path}/apps. No Unix, new File(parent, "../../oracle/name.rdb") resolve fora do parent. JsonProtocol.applicationStartFromJson pega json.get("App ID").asText(). AppListingListener.onApplicationStart armazena event.appId.orNull. lease.commit(appId, attempt.info.attemptId) alimenta essa string para appStorePath.

Caminhos errados já registrados: tratar o padrão não definido de store.path como uma escrita (é em memória); esperar que new File(dir, "/abs") no Unix ignore o parent (não ignora; o resíduo é ..); afirmar RCE porque o sufixo é .rdb; inicializar um History Server completo quando o join é o oráculo; tratar sanitizeDirName como cobrindo este caminho.

Lab

python3 spark-history-store-path-Abraxas-Labs.py

ou

cd lab
./run.sh

Gadget de HistoryServerDiskManager.appStorePath em 127.0.0.1:18990. Trechos do pin em lab/pin/. O History Server completo não é inicializado. Vincule-o ao loopback.

SUCCESS SPARK-HISTORY-STORE-PATH how=gadget escaped=yes gated=yes outside=/work/oracle/SPARK-HISTORY-STORE-PATH-WITNESS.rdb SPARK-HISTORY-STORE-PATH-WITNESS

A correção

Execute Utils.sanitizeDirName (ou rejeite .. / / / NUL) em appId e attemptId dentro de appStorePath antes de new File. Após o join, exija que dst.getCanonicalFile() permaneça sob appStoreDir.getCanonicalFile(). O spark.history.store.path não definido permanece o padrão seguro.

Referências

Baixar ferramenta