Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
spark-history-store-path — Apache Spark 4.2.0 - 高危 - 远程 - 文件写入 - History appStorePath 未过滤的 App ID | Kitploit
工具/GitHubGitHub/abraxas/spark-history-store-path
静态分析漏洞分析代码分析漏洞利用Web应用程序漏洞利用渗透测试实验室与实践
GitHubabraxas/spark-history-store-path

spark-history-store-path

Apache Spark 4.2.0 - 高危 - 远程 - 文件写入 - History appStorePath 未过滤的 App ID

查看仓库
2天前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

Abraxas Labs - spark-history-store-path

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

spark-history-store-path

类别: 文件写入(受配置门控) 可达性: 远程

Apache Spark 4.2.0(32f72996)- Apache Software Foundation

HistoryServerDiskManager.appStorePath 执行 new File(appStoreDir, appId + extension),未做任何清理。Utils.sanitizeDirName 仅用于事件日志文件名。JSON 中的 App ID 通过 asText() 获取。列表存储 event.appId.orNull。Lease.commit 使用该字符串。App ID 为 ../ 时会在 spark.history.store.path 之外写入一个 .rdb 文件。默认未设置的 store.path 为内存模式(不写入)。内容为存储文件,并非 RCE。

ID暂无 CVE
类别文件写入(受配置门控的 History 磁盘存储)
可达性远程(事件日志写入者加上设置了 spark.history.store.path 的 History;UI ACL 默认关闭)
CWECWE-22
CVSS高危:7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N(当设置了 spark.history.store.path 时)
产品Apache Spark History Server
受影响版本4.2.0(32f7299601108917fb01920a54e084595b7b3bf8)
认证spark.history.fs.logDirectory 的写入者(默认 file:/tmp/spark-events);History 必须设置 spark.history.store.path
许可证GNU Affero GPL v3.0
实验环境仅限 127.0.0.1:18990。所引用拼接的利用组件。在 store.path 之外生成见证文件 .rdb。

攻击者能做什么

与 CVE-2025-54920 相同的受害者模型:History Server 指向攻击者可写入的日志目录。Jackson 不再构造 HiveConnection 类利用组件。磁盘存储路径仍然信任事件 JSON 中的 App ID。

方法汇聚点权限实验环境 vs 推断
植入一个事件日志,其 JSON App ID 为 ../<name>(或 ../../oracle/...)。等待扫描。GET 加载应用 UI / getAppUI / loadDiskStore / createDiskStoreHistoryServerDiskManager.appStorePath 然后 Lease.commit renameTo完整性: 以 History UID 身份在 {store.path}/apps 之外创建 .rdb(默认 RocksDB)或 .ldb(LevelDB)路径。在利用组件上实验证明:escaped=yes,文件 /work/oracle/SPARK-HISTORY-STORE-PATH-WITNESS.rdb 包含见证内容。内容为存储文件,并非攻击者选择的主机字节码,也不是 shell。实验证明(在逃逸路径写入见证字节的利用组件)。完整 History 对 RocksDB 目录的 renameTo 是同一拼接。
当逃逸目标已是目录时使用相同 App IDLease.commit 的 if (dst.isDirectory()) deleteStore(dst) 然后 Utils.deleteRecursively可用性: 删除名称已以后端后缀结尾的现有目录,然后用租用的存储替换它。推断(依据 HistoryServerDiskManager.scala 提交逻辑)。利用组件写入的是文件,未调用 deleteRecursively。
默认未设置 spark.history.store.pathLOCAL_STORE_DIR createOptional;diskManager = storePath.map已关闭。内存列表。无 HistoryServerDiskManager。实验证明 gated=yes written=no。实验证明
先对 App ID 应用 Utils.sanitizeDirName事件日志文件名辅助函数保持在 apps/ 内。/ 和 : 变为 -。实验证明为否定结果。实验证明
控制 App ID 为 local-control 且设置了 store.path同一拼接写入 {store.path}/apps/local-control.rdb。保持在 apps/ 内。实验证明

相邻已关闭项: 默认未设置的存储(内存模式)。Jackson 的 sparkEventFromJson 仍要求 SparkListenerEvent(CVE-2025-54920)。URL getAppUI 回退 eventlog_v2_ + nameForAppAndAttempt 已清理。列表 KV 键不是文件系统路径。HybridStore / kvstore 映射器没有 Id.CLASS。压缩默认关闭。清理器默认关闭。开放集群上的作业提交(SECURITY.md FAQ)。ML 模型加载(docs/ml-security.md)。此遗留问题并非主机 RCE。

我是如何发现的

我固定使用 Spark 4.2.0,不是 master,也不是 4.3 RC。二十八次搜寻。公开的 History Jackson RCE 在此版本上已关闭。事件日志写入者已调用 Utils.sanitizeDirName,因此日志文件不能包含 /。磁盘缓存文件名使用原始 App ID。

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。Unix 的 new File(parent, "../../oracle/name.rdb") 会解析到 parent 之外。JsonProtocol.applicationStartFromJson 取 json.get("App ID").asText()。AppListingListener.onApplicationStart 存储 event.appId.orNull。lease.commit(appId, attempt.info.attemptId) 将该字符串送入 appStorePath。

已记录的弯路:将默认未设置的 store.path 视为写入(实际为内存模式);期望 Unix 的 new File(dir, "/abs") 忽略 parent(实际不会;遗留为 ..);因后缀为 .rdb 而声称 RCE;在拼接即为 oracle 时启动完整 History Server;将 sanitizeDirName 视为覆盖此路径。

实验环境

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

或

cd lab
./run.sh

HistoryServerDiskManager.appStorePath 在 127.0.0.1:18990 上的利用组件。固定版本摘录位于 lab/pin/ 下。未启动完整 History Server。将其绑定到回环地址。

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

修复方案

在 appStorePath 内、new File 之前,对 appId 和 attemptId 运行 Utils.sanitizeDirName(或拒绝 .. / / / NUL)。拼接后,要求 dst.getCanonicalFile() 保持在 appStoreDir.getCanonicalFile() 之下。未设置 spark.history.store.path 仍为安全默认值。

参考资料

  • github.com/apache/spark 标签 v4.2.0(32f7299601108917fb01920a54e084595b7b3bf8)
  • HistoryServerDiskManager.scala appStorePath / Lease.commit
  • FsHistoryProvider.scala diskManager / loadDiskStore / onApplicationStart
  • JsonProtocol.scala applicationStartFromJson
  • Utils.scala sanitizeDirName
  • History.scala LOCAL_STORE_DIR(可选)
  • 已关闭的 Jackson 遍历:CVE-2025-54920 / SPARK-52381
  • CWE-22

许可证

GNU Affero GPL v3.0。参见 LICENSE。仅限回环实验环境。无担保。

下载工具