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

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

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

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
spark-history-zip-symlink — Apache Spark 4.2.0 - 高危 - 远程 - 文件读取 - History zip 跟随植入的符号链接 | Kitploit
工具/GitHubGitHub/abraxas/spark-history-zip-symlink
漏洞分析漏洞利用Web应用程序漏洞利用信息收集渗透测试论文与研究
GitHubabraxas/spark-history-zip-symlink

spark-history-zip-symlink

Apache Spark 4.2.0 - 高危 - 远程 - 文件读取 - History zip 跟随植入的符号链接

查看仓库
55天前尚未审核

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

Abraxas Labs - spark-history-zip-symlink

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

spark-history-zip-symlink

类别: 文件读取 可达性: 远程

Apache Spark 4.2.0 (32f72996) - Apache Software Foundation

CVE-2025-54920 锁定了 History Server 的 Jackson,使 sparkEventFromJson 只能构造 SparkListenerEvent 的子类。滚动 zipEventLogFiles 仍会通过 FileSystem.open 转储每个 listStatus 子项。LocalFileSystem 会跟随 POSIX 符号链接。在 eventlog_v2_* 中植入的子项会被打包进未认证的 GET /api/v1/applications/{id}/logs。zip 成员正文是 SHS-UID 目标。条目名称是符号链接的基名。

这不是 Jackson RCE 的重复提交。Jackson 仍然关闭。这不是主机 RCE。完整性和可用性均无影响。

ID暂无 CVE
类别文件读取(CVE-2025-54920 受害模型遗留的滚动 zip 问题)
可达性远程(History 日志目录的写入者,加上对 zip 的未认证 GET)
CWECWE-59、CWE-22
CVSS高危:7.5 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
产品Apache Spark
受影响版本4.2.0 标签 v4.2.0 (32f7299601108917fb01920a54e084595b7b3bf8)
认证PR:L = 对 spark.history.fs.logDirectory 的写入权限(与 54920 相同的受害模型)。History UI ACL 默认关闭。
许可证GNU Affero GPL v3.0
实验环境仅 127.0.0.1:18980

攻击者能做什么

能够写入 spark.history.fs.logDirectory(默认 file:/tmp/spark-events)的人可以植入一个滚动目录,History Server 会将其打包为 zip。滚动写入器默认开启。History UI ACL 默认关闭。SHS 进程 UID 就是被混淆的代理。

权限方法 / 汇聚点实验验证或推断
机密性:读取 SHS UID 可打开的主机文件植入 eventlog_v2_<id>/,包含有效的 appstatus_* 和 events_* JSON(SparkListenerLogStart / SparkListenerApplicationStart),以及一个目标位于日志目录之外的符号链接子项。等待扫描。未认证 GET /api/v1/applications/{id}/logs(OneApplicationResource.getEventLogs -> FsHistoryProvider.writeEventLogs -> RollingEventLogFilesFileReader.zipEventLogFiles -> FileSystem.open)实验验证。zip 成员 eventlog_v2_app-2026-0001/planted-secret 正文为 SPARK-HISTORY-ZIP-SYMLINK-WITNESS。Events 成员没有见证内容。条目名称保持为符号链接的基名,而非目标路径。
机密性:攻击者无法 open(660)的兄弟租户事件日志同一个 zip,符号链接目标是另一个应用的日志推断。相同的 FileSystem.open。未实际验证。
机密性:keytab、spark-env.sh、/etc/passwd(如果 SHS 可读取)同一个 zip推断。验证目标是专用的 /secret/host-secret,而非这些文件。
SHS 或主机文件的完整性zip 被读入 HTTP 正文关闭。实验验证无影响。
SHS 或主机文件的可用性zip 不会删除或截断目标关闭。实验验证无影响。
主机 RCE / Jackson gadget 构造JsonProtocol.sparkEventFromJson关闭。需要 SparkListenerEvent。本实验仅植入无害的 Event JSON。
条目名称中 ../ 的 zip slipPath.getName()关闭。POSIX 文件名不能包含 /。条目为 eventlog_v2_<id>/<basename>。
resolveLogPath 的路径字符串逃逸new Path(logDir, attempt.logPath)关闭。Path 对象保持在配置的日志目录下。逃逸的是 inode。
目标的压缩重写 / 清理器删除spark.history.fs.eventLog.rolling.maxFilesToRetain 默认 Integer.MAX_VALUE;清理器默认关闭关闭。对符号链接执行本地 fs.delete 只会解除链接,而非删除目标。
未认证作业提交 / ML 模型加载SECURITY.md FAQ / docs/ml-security.md关闭。设计如此,非本遗留问题。

我是如何发现的

我固定了 apache/spark v4.2.0(32f7299601108917fb01920a54e084595b7b3bf8),而非 master 或 4.3 RC。二十八次搜寻。Jackson History RCE 在此版本上已关闭(JsonProtocol.scala:965-972)。History Server 仍指向攻击者可写的日志目录,这与 CVE-2025-54920 是相同的受害模型。

zipEventLogFiles 会打包所有 files,而不仅是事件文件:

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,然后 transferTo。LocalFileSystem 会跟随 POSIX 符号链接。getLogDirInfo 注释说“正确处理符号链接”,然后遍历未解析的 Path 父级以获取显示名称。

已记录的弯路:将 SPARK-52381 视为整个 History 问题;将见证内容植入 events_*(实验会失败);期望 zip 条目携带目标路径;将 resolveLogPath 的前缀拼接视为逃逸点;在此版本上尝试 HiveConnection Event 类。

实验环境

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

或

cd lab
./run.sh

EventLogFileReaders.scala 滚动 zip 转储的 gadget,不是完整的 History Server,也不是官方 spark:4.2.0 镜像。它不通过 Jackson 解析 Event JSON。回环地址 127.0.0.1:18980。Compose 项目 spark-history-zip-symlink。滚动目录包含有效的 appstatus_* + events_*(无见证内容)以及 planted-secret -> /secret/host-secret。

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

修复方案

仅打包 events_* / appstatus_* 子项,而非每个 listStatus 名称。使用 no-follow 打开(O_NOFOLLOW / Hadoop no-symlink 选项),并拒绝 realpath 位于 spark.history.fs.logDirectory 之外的子项。显示名称辅助函数不是 realpath 检查。

参考资料

  • github.com/apache/spark 标签 v4.2.0(32f7299601108917fb01920a54e084595b7b3bf8)
  • EventLogFileReaders.scala(addFileAsZipEntry 约 48-56 行,zipEventLogFiles 约 267-272 行)
  • FsHistoryProvider.scala(writeEventLogs 约 831-856 行,resolveLogPath 约 866-896 行)
  • OneApplicationResource.scala(GET .../logs 约 128-165 行)
  • JsonProtocol.scala(sparkEventFromJson 约 965-972 行,Jackson 锁定)
  • 附近已修补(Jackson 构造,非此 inode 遍历):CVE-2025-54920 / SPARK-52381
  • CWE-59 · CWE-22

许可证

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

下载工具