-
Notifications
You must be signed in to change notification settings - Fork 1
/
CVE-2024-6387.py
143 lines (120 loc) · 5.47 KB
/
CVE-2024-6387.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
#!/usr/bin/env python3
import socket
import argparse
import ipaddress
# Define color codes
GREEN = "\033[92m"
RED = "\033[91m"
YELLOW = "\033[93m"
ORANGE = "\033[33m"
ENDC = "\033[0m"
# Define known vulnerable and patched versions
vulnerable_versions = {
'SSH-2.0-OpenSSH_1', 'SSH-2.0-OpenSSH_2', 'SSH-2.0-OpenSSH_3', 'SSH-2.0-OpenSSH_4.0',
'SSH-2.0-OpenSSH_4.1', 'SSH-2.0-OpenSSH_4.2', 'SSH-2.0-OpenSSH_4.3', 'SSH-2.0-OpenSSH_4.4',
'SSH-2.0-OpenSSH_8.5', 'SSH-2.0-OpenSSH_8.6', 'SSH-2.0-OpenSSH_8.7', 'SSH-2.0-OpenSSH_8.8',
'SSH-2.0-OpenSSH_8.9', 'SSH-2.0-OpenSSH_9.0', 'SSH-2.0-OpenSSH_9.1', 'SSH-2.0-OpenSSH_9.2',
'SSH-2.0-OpenSSH_9.3', 'SSH-2.0-OpenSSH_9.4', 'SSH-2.0-OpenSSH_9.5', 'SSH-2.0-OpenSSH_9.6',
'SSH-2.0-OpenSSH_9.7'
}
patched_versions = {
'SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.10', 'SSH-2.0-OpenSSH_9.3p1 Ubuntu-3ubuntu3.6',
'SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.3', 'SSH-2.0-OpenSSH_9.3p1 Ubuntu-1ubuntu3.6',
'SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u3', 'SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u3',
'SSH-2.0-OpenSSH_9.7p1 Debian-7'
}
def display_banner():
banner = f"""
{GREEN}
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ CVE-2024-6387 Vulnerability Checker +
+ Created by senhasegura Identity Threat Labs +
+ Filipi Pires - Threat Researcher & Cybersecurity Advocate +
+ @senhasegura / @filipipires +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{ENDC}
"""
print(banner)
def resolve_hostname(hostname):
try:
return socket.gethostbyname(hostname)
except socket.gaierror:
return None
def get_ssh_banner(ip, port, timeout):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(timeout)
sock.connect((ip, port))
banner = sock.recv(1024).decode().strip()
sock.close()
return banner
except socket.error:
return None
def check_vulnerability(address, port, timeout):
ip = resolve_hostname(address) if not address.replace(".", "").isdigit() else address
if not ip:
return ip, port, 'ERROR', " WE COULDN'T CONNECT OR RETRIEVE BANNER"
banner = get_ssh_banner(ip, port, timeout)
if not banner:
return ip, port, 'ERROR', " WE COULDN'T CONNECT OR RETRIEVE BANNER"
if "SSH-2.0-OpenSSH" in banner:
if banner in vulnerable_versions and banner not in patched_versions:
return ip, port, 'VULNERABLE', f"-> Running {banner}"
else:
return ip, port, 'SAFE', f"-> Running {banner}"
else:
return ip, port, 'UNKNOWN', f"-> SSH version {banner}"
def main():
display_banner()
parser = argparse.ArgumentParser(description="Check for CVE-2024-6387 vulnerability on a list of servers.")
parser.add_argument("addresses", nargs='*', help="IP addresses, URLs, or CIDR ranges of the servers to check.")
parser.add_argument("-f", "--file", help="File containing a list of IP addresses or CIDR ranges to check.")
parser.add_argument("-p", "--ports", type=str, default="22", help="Comma-separated list of port numbers for SSH (default: 22).")
parser.add_argument("-t", "--timeout", type=float, default=5.0, help="Connection timeout in seconds (default: 5.0).")
args = parser.parse_args()
results = {'SAFE': [], 'VULNERABLE': [], 'UNKNOWN': [], 'ERROR': []}
ports = [int(p) for p in args.ports.split(',')]
addresses = list(args.addresses)
# Read addresses from file if provided
if args.file:
try:
with open(args.file, 'r') as f:
file_addresses = [line.strip() for line in f if line.strip()]
addresses.extend(file_addresses)
except IOError:
print(f"{YELLOW}Could not read file: {args.file}{ENDC}")
# Resolve CIDR ranges and expand them into IP addresses
expanded_addresses = []
for addr in addresses:
if '/' in addr:
try:
network = ipaddress.ip_network(addr, strict=False)
expanded_addresses.extend([str(ip) for ip in network.hosts()])
except ValueError:
print(f"{YELLOW}Invalid CIDR notation: {addr}{ENDC}")
else:
expanded_addresses.append(addr)
# Check all combinations of addresses and ports
for address in expanded_addresses:
for port in ports:
ip, port, status, message = check_vulnerability(address, port, args.timeout)
results[status].append((ip, port, message))
# Display results
if len(results['SAFE']) > 0:
print(f"\n{GREEN}SERVER NOT VULNERABLE: {len(results['SAFE'])}{ENDC}")
for ip, port, msg in results['SAFE']:
print(f"{GREEN}[SAFE] -> {ip}:{port}{msg}{ENDC}")
if len(results['VULNERABLE']) > 0:
print(f"\n{RED}SERVER VULNERABLE: {len(results['VULNERABLE'])}{ENDC}")
for ip, port, msg in results['VULNERABLE']:
print(f"{RED}[VULNERABLE] -> {ip}:{port} {msg}{ENDC}")
if len(results['UNKNOWN']) > 0:
print(f"\n{ORANGE}SERVER UNKNOWN SSH VERSION: {len(results['UNKNOWN'])}{ENDC}")
for ip, port, msg in results['UNKNOWN']:
print(f"{ORANGE}[UNKNOWN] -> {ip}:{port}{msg}{ENDC}")
if len(results['ERROR']) > 0:
print(f"\n{YELLOW}WE COULDN'T CONNECT OR RETRIEVE BANNER: {len(results['ERROR'])}{ENDC}")
for ip, port, msg in results['ERROR']:
print(f"{YELLOW}[ERROR] -> {ip}:{port}{msg}{ENDC}")
if __name__ == "__main__":
main()