Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OSError: [Errno 24] Too many open files #19

Closed
nawabs11 opened this issue Jul 2, 2024 · 2 comments
Closed

OSError: [Errno 24] Too many open files #19

nawabs11 opened this issue Jul 2, 2024 · 2 comments

Comments

@nawabs11
Copy link

nawabs11 commented Jul 2, 2024

Found an issue "OSError: [Errno 24] Too many open files" while executing on a MAC, likely as the script attempts to create a large number of concurrent threads and sockets, leading to this issue.

@nawabs11
Copy link
Author

nawabs11 commented Jul 2, 2024

`import socket
import argparse
import ipaddress
import threading
from queue import Queue
from concurrent.futures import ThreadPoolExecutor, as_completed

def get_ssh_sock(ip, port, timeout):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(timeout)
try:
sock.connect((ip, port))
return sock
except:
return None

def get_ssh_banner(sock):
try:
banner = sock.recv(1024).decode().strip()
sock.close()
return banner
except Exception as e:
return str(e)

def check_vulnerability(ip, port, timeout, result_queue):
sshsock = get_ssh_sock(ip, port, timeout)
if not sshsock:
result_queue.put((ip, port, 'closed', "Port closed"))
return

banner = get_ssh_banner(sshsock)
if "SSH-2.0-OpenSSH" not in banner:
    result_queue.put((ip, port, 'failed', f"Failed to retrieve SSH banner: {banner}"))
    return

vulnerable_versions = [
    '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'
]

excluded_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'
]

if any(version in banner for version in vulnerable_versions) and banner not in excluded_versions:
    result_queue.put((ip, port, 'vulnerable', f"(running {banner})"))
else:
    result_queue.put((ip, port, 'not_vulnerable', f"(running {banner})"))

def process_ip_list(ip_list_file):
ips = []
try:
with open(ip_list_file, 'r') as file:
ips.extend(file.readlines())
except IOError:
print(f"❌ [-] Could not read file: {ip_list_file}")
return [ip.strip() for ip in ips]

def main():
parser = argparse.ArgumentParser(description="Check if servers are running a vulnerable version of OpenSSH.")
parser.add_argument("targets", nargs='*', help="IP addresses, domain names, file paths containing IP addresses, or CIDR network ranges.")
parser.add_argument("--port", type=int, default=22, help="Port number to check (default: 22).")
parser.add_argument("-t", "--timeout", type=float, default=1.0, help="Connection timeout in seconds (default: 1 second).")
parser.add_argument("-l", "--list", help="File containing a list of IP addresses to check.")

args = parser.parse_args()
targets = args.targets
port = args.port
timeout = args.timeout

ips = []

if args.list:
    ips.extend(process_ip_list(args.list))

for target in targets:
    try:
        with open(target, 'r') as file:
            ips.extend(file.readlines())
    except IOError:
        if '/' in target:
            try:
                network = ipaddress.ip_network(target, strict=False)
                ips.extend([str(ip) for ip in network.hosts()])
            except ValueError:
                print(f"❌ [-] Invalid CIDR notation: {target}")
        else:
            ips.append(target)

result_queue = Queue()

# Limit the number of concurrent threads
max_workers = 100
with ThreadPoolExecutor(max_workers=max_workers) as executor:
    futures = []
    for ip in ips:
        ip = ip.strip()
        futures.append(executor.submit(check_vulnerability, ip, port, timeout, result_queue))

    for future in as_completed(futures):
        future.result()

total_scanned = len(ips)
closed_ports = 0
not_vulnerable = []
vulnerable = []

while not result_queue.empty():
    ip, port, status, message = result_queue.get()
    if status == 'closed':
        closed_ports += 1
    elif status == 'vulnerable':
        vulnerable.append((ip, message))
    elif status == 'not_vulnerable':
        not_vulnerable.append((ip, message))
    else:
        print(f"⚠️ [!] Server at {ip}:{port} is {message}")

print(f"\n🛡️ Servers not vulnerable: {len(not_vulnerable)}\n")
for ip, msg in not_vulnerable:
    print(f"   [+] Server at {ip} {msg}")
print(f"\n🚨 Servers likely vulnerable: {len(vulnerable)}\n")
for ip, msg in vulnerable:
    print(f"   [+] Server at {ip} {msg}")
print(f"\n🔒 Servers with port {port} closed: {closed_ports}")
print(f"\n📊 Total scanned targets: {total_scanned}\n")

if name == "main":
main()
`

xaitax added a commit that referenced this issue Jul 2, 2024
@xaitax
Copy link
Owner

xaitax commented Jul 2, 2024

Please test again - should be solved now. If persists, please reopen.

@xaitax xaitax closed this as completed Jul 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants