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

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

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

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
spark-python-ds-static — Apache Spark 4.2.0 - 高危 - 远程 - 权限残留 - 进程级全局 Python 数据源映射 | Kitploit
工具/GitHubGitHub/abraxas/spark-python-ds-static
权限提升漏洞分析漏洞利用后渗透利用论文与研究红队Payload 开发实验室与实践
GitHubabraxas/spark-python-ds-static

spark-python-ds-static

Apache Spark 4.2.0 - 高危 - 远程 - 权限残留 - 进程级全局 Python 数据源映射

查看仓库
2天前尚未审核

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

Abraxas Labs - spark-python-ds-static

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  spark-python-ds-static

spark-python-ds-static

类别: 权限残留 可达性: 远程

Apache Spark 4.2.0 (32f72996) - Apache Software Foundation

DataSourceManager.dataSourceBuilders 是一个 JVM 全局的先到先得映射。SPARK-45917 会从查找 worker 的 sys.path 自动注册 pyspark_* Python 数据源。Connect 会话隔离将工件保留在 SparkFiles/<sessionUUID>/ 下,而每会话的 registerPython 仍留在 runtimeDataSourceBuilders 上。首次查找仍会将触发会话的 SparkFiles 目录放入 sys.path,pickle 每个 DefaultSource,并将这些类缓存到伴生对象中。之后的 Connect SQL(或 Hive Thrift SQL)read.format(name) / USING name 会将该类作为 Spark UID 运行,而无需发送 Python proto。

植入者是已获准使用 Python 的 Connect Python 租户。受害者是同一 Connect driver 上仅使用 SQL 的租户。Java 别名(parquet、csv、json、orc、jdbc)仍走 Java ServiceLoader 路径。映射填满后的后续植入不会刷新。AC:H 是首次查找加上一个非 Java 别名的名称。

ID暂无 CVE
类别权限残留(跨会话 Python 数据源以 Spark UID 身份运行;并非未认证作业提交)
可达性远程(共享 Spark Connect driver)
CWECWE-269、CWE-502
CVSS高:8.8 CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H
产品Apache Spark
受影响4.2.0(32f7299601108917fb01920a54e084595b7b3bf8)Python 数据源静态注册表
认证Connect Python 租户(植入者)加上之后的仅 SQL Connect / Hive Thrift SQL 用户(受害者)
许可证GNU Affero GPL v3.0
实验环境仅 127.0.0.1:18970。见证文件。伴生映射的 gadget。

攻击者能做什么

在共享 driver 上持有一个 Spark Connect Python 会话。植入 pyfiles/pyspark_<name>.py,其 DefaultSource.name() 是一个不存在的连接器短名称(delta、iceberg、hudi……)。在该会话上触发首次 Python 数据源查找。同一 JVM 中之后每个执行 read.format(name) 或 SQL USING name 的会话,都会在 driver planner worker 和 executor 上将该 pickle 类作为 Spark UID 实例化。

这就是完整的权限集合。植入者本就在运行 Python。残留之处在于:一个从未发送 REGISTER_DATA_SOURCE / Python UDF proto 的仅 SQL 租户,仍会执行该类。

完整性(实验环境已证实)

方法汇聚点权限
植入者:AddArtifacts 名称 pyfiles/pyspark_<name>.py,然后首次 format(name) / 查找伴生 DataSourceManager.dataSourceBuilders(DataSourceManager.scala object)加上 lookup_data_sources.py 对 pyspark_* 的 iter_modules将触发会话的 pickle DefaultSource 缓存到 JVM 全局。实验环境:layer='static' trigger='attacker' first-wins=yes。
受害者:在从未植入的会话上执行 SQL USING <name> / spark.read.format(name)PythonDataSourceV2 createDataSourceInPython将该类作为 Spark UID 运行。实验环境:planted_by='attacker' witness_written=True static-cross-session=yes。Oracle 文件包含 SPARK-PYTHON-DS-STATIC-WITNESS。

本次走查中已关闭(实验环境已证实)

方法汇聚点结果
映射填满后植入第二个名称同一静态映射已关闭。先到先得。实验环境:later-lookup found=False,伴生仍只有 delta。
每会话 registerPython("alpha")runtimeDataSourceBuilders已隔离。克隆仅复制 runtime。实验环境:runtime-isolated=yes。受害者读取 alpha 为 found=False。
Java 别名 parquetJava DataSourceRegister ServiceLoader已关闭。实验环境:java-alias-closed=yes layer='java'。csv/json/orc/jdbc 同理。

推断(相同汇聚点,非 oracle)

方法汇聚点权限
植入后受害者 USINGdriver + executor Python worker以 Spark UID 身份在集群范围执行代码。实验环境写入见证文件而非 payload。
同一路径worker 崩溃 / 空转以 Spark UID 身份影响可用性。并非 High。High 是代码执行。
共享 SparkSession 上的 Hive Thrift SQL USING同一静态映射若 Thrift 与 Connect 共享 driver JVM,则存在相同残留。未实际验证。

此残留不授予的权限

  • 在开放集群上未认证提交作业。SECURITY.md FAQ。设计如此。
  • Java parquet / csv / json / orc / jdbc 劫持。ServiceLoader 胜出。
  • 工件路径逃逸(concatenatePaths 拒绝 .. 和绝对名称)。
  • 客户端提供的 pythonExec。Connect planner 使用服务端 PYSPARK_PYTHON / python3。
  • registerPython 的跨会话泄漏。Runtime 映射按 DataSourceManager 实例隔离。
  • 单用户本地 pyspark 单会话。不存在其他租户。
  • 填充空映射的未命中首次查找。后续植入不会刷新(AC:H)。

我是如何发现的

我固定了 apache/spark v4.2.0(32f7299601108917fb01920a54e084595b7b3bf8)。二十八次源码搜寻。作业提交执行用户代码是设计使然。History Jackson、UI shell、PySpark 本地模拟以及 standalone RPC 接收路径在此次剥离中均已关闭。Connect 工件将 pyfiles 隔离在会话 UUID 下。Runtime registerPython 按会话隔离。伴生对象则不然。

SPARK-45917 从 PYTHONPATH 自动注册 pyspark_* 包。这是为运维人员安装的连接器而设计的。残留之处在于:查找 worker 还会 sys.path.insert 触发会话的 SparkFiles 目录(worker_util.setup_spark_files),然后将找到的任何 pyspark_* DefaultSource pickle 到一个永不刷新的进程全局映射中。

错误方向:将 registerPython 隔离视为整个租户屏障。Runtime 是隔离的。Static 则不然。

实验环境

cd lab
./run.sh

回环 127.0.0.1:18970。Compose 项目 spark-python-ds-static。见证 SPARK-PYTHON-DS-STATIC-WITNESS。object DataSourceManager 的 Python gadget 加上每会话 runtime 映射。仅在攻击者 SparkFiles 中植入 pyspark_delta.py。攻击者查找填充伴生。之后植入 iceberg 不会刷新。受害者 read delta 写入 oracle。registerPython("alpha") 不会泄漏。Java parquet 保持 Java。

最后一行:

SUCCESS SPARK-PYTHON-DS-STATIC static-cross-session=yes runtime-isolated=yes first-wins=yes java-alias-closed=yes SPARK-PYTHON-DS-STATIC-WITNESS

修复方案

在填充静态映射时,不要将会话 SparkFiles 放入查找 worker 的 sys.path。仅加载运维人员 PYTHONPATH 包(SPARK-45917 的设计意图)。或者像工件已经做的那样,按会话 / JobArtifactSet UUID 为静态映射设置键。先到先得的空填充不应在 driver 的整个生命周期内固定另一个租户的类。

在此之前,不要在 Python 租户与仅 SQL 租户之间共享 Connect driver——除非你本就信任后者拥有 driver Python 权限。

参考资料

  • github.com/apache/spark 标签 v4.2.0(32f7299601108917fb01920a54e084595b7b3bf8)
  • DataSourceManager.scala 伴生 dataSourceBuilders / initialStaticDataSourceBuilders
  • lookup_data_sources.py pyspark_* DefaultSource
  • worker_util.py setup_spark_files
  • PythonDataSourceV2.scala
  • SPARK-45917 自动注册(为运维人员 PYTHONPATH 设计)

联系方式

Abraxas Labs - abraxaslabs.tech - github.com/abraxas - @abraxas_null - [email protected]

下载工具