目录
POC:ssh_poc.py
python
import sys
import socket
import argparse
import threading
import queue
import os
from datetime import datetime
from urllib.parse import urlparse
from packaging.version import parse as parse_version, InvalidVersion
# ANSI color codes
light_gray_color = '\033[37;1m'
dimmed_gray_color = '\033[90m'
honey_yellow_color = "\033[38;5;214m"
dim_yellow_color = "\033[33;1m"
cyan_color = '\033[96m'
green_color = '\033[92m'
dimmed_green_color = '\033[2;32m'
red_color = '\033[31m'
light_orange_color = '\033[38;5;214m'
reset_color = '\033[0m'
the_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
# Log directory and file
LOG_DIR = 'logs'
LOG_FILE = os.path.join(LOG_DIR, 'scan.log')
def banner():
print(f"""
{light_orange_color}
▒█▀▀▀█ █▀▀█ █▀▀ █▀▀▄ ▒█▀▀▀█ ▒█▀▀▀█ ▒█░▒█ ▒█▀▀▀█ █▀▀ █▀▀█ █▀▀▄ █▀▀▄ █▀▀ █▀▀█
▒█░░▒█ █░░█ █▀▀ █░░█ ░▀▀▀▄▄ ░▀▀▀▄▄ ▒█▀▀█ ░▀▀▀▄▄ █░░ █▄▄█ █░░█ █░░█ █▀▀ █▄▄▀
▒█▄▄▄█ █▀▀▀ ▀▀▀ ▀░░▀ ▒█▄▄▄█ ▒█▄▄▄█ ▒█░▒█ ▒█▄▄▄█ ▀▀▀ ▀░░▀ ▀░░▀ ▀░░▀ ▀▀▀ ▀░▀▀
{reset_color}{light_gray_color}-> Bulk Scanning Tool for OpenSSH RCE CVE-2024-6387, CVE-2006-5051 and CVE-2008-4109.
{reset_color}
""")
def is_vulnerable(version):
if version.startswith("OpenSSH_"):
version_num = version.split('_')[1].split()[0] # Split out version number
try:
parsed_version = parse_version(version_num.replace("p", "."))
except InvalidVersion:
return False, None
# Check if version is earlier than 4.4p1
if parsed_version < parse_version("4.4"):
return True, "CVE-2006-5051, CVE-2008-4109"
# Check if version is in the range 8.5p1 to 9.7p1
if parse_version("8.5") <= parsed_version < parse_version("9.8"):
return True, "CVE-2024-6387"
return False, None
vulnerable_ips = []
# Function to create log directory
def create_log_dir():
if not os.path.exists(LOG_DIR):
os.makedirs(LOG_DIR)
print_message('info', f"Log directory created: {LOG_DIR}")
# Function to log messages
def log_message(message):
with open(LOG_FILE, 'a') as log_file:
log_file.write(f"{the_time} - {message}\n")
# Function to print messages with ANSI colors
def print_message(level, message):
if level == 'vulnerable':
print(f"[{light_gray_color}{the_time}] {light_orange_color}[VULN] {message}{reset_color}")
if level == 'info':
print(f"[{light_gray_color}{the_time}] {dimmed_gray_color}[INFO] {message}{reset_color}")
elif level == 'ok':
print(f"[{light_gray_color}{the_time}] {dimmed_green_color}[OK] {message}{reset_color}")
elif level == 'warning':
print(f"[{light_gray_color}{the_time}] {light_gray_color}[INFO] {message}{reset_color}")
elif level == 'error':
print(f"[{light_gray_color}{the_time}] {red_color}[ERROR] {message}{reset_color}")
log_message(message)
# Function to get OpenSSH version
def get_ssh_version(ip, port):
try:
sock = socket.create_connection((ip, port), timeout=5)
sock.sendall(b'\x00')
response = sock.recv(1024).decode().strip()
sock.close()
if response.startswith("SSH-2.0-OpenSSH"):
version_info = response.split('-')[2]
if "OpenSSH_" in version_info:
version = version_info.split('_')[1]
return version
else:
return "no version"
return "Invalid SSH identification string."
except socket.error as e:
return None
# Function to test a single host
def test_host(target):
if "://" in target:
target = target.split("://")[1]
target = target.rstrip('/')
if ":" in target:
ip, port = target.split(":")
try:
port = int(port)
except ValueError:
print_message('error', f"Invalid port in target {target}")
return
else:
ip = target
port = 22
version = get_ssh_version(ip, port)
if version:
message = f"OpenSSH version {version} {ip}:{port}"
is_vuln, cve_number = is_vulnerable(f"OpenSSH_{version}")
if is_vuln:
vuln_message = f"{cve_number} OpenSSH version {version} {ip}:{port}"
print_message('vulnerable', vuln_message)
vulnerable_ips.append(target)
elif version == "Invalid SSH identification string.":
message = f"{version} {ip}:{port}"
print_message('info', message)
else:
print_message('ok', message)
else:
print_message('info', f"No OpenSSH {ip}:{port}")
# Worker function for threading
def worker(queue):
while not queue.empty():
target = queue.get()
test_host(target)
queue.task_done()
# Main function
def main():
banner()
parser = argparse.ArgumentParser(description='OpenSSH Bulk Vesrioning Scanning Tool for CVE-2024-6387, CVE-2006-5051 and CVE-2008-4109.')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-u', '--url', help='Target IP:PORT (e.g., 192.168.1.1:22)')
group.add_argument('-f', '--file', help='File containing list of targets/IPs (one per line)')
parser.add_argument('--output', help='File to save vulnerable IPs', required=False)
args = parser.parse_args()
create_log_dir()
if not args.url and not args.file:
parser.error("one of the arguments -u to scan a single IP or -f Bulk IPs file path is required")
if args.url:
test_host(args.url)
elif args.file:
try:
with open(args.file, 'r') as f:
targets = [line.strip() for line in f if line.strip()]
except FileNotFoundError:
print_message('error', f"File not found: {args.file}")
sys.exit(1)
target_queue = queue.Queue()
for target in targets:
target_queue.put(target)
threads = []
for _ in range(10):
t = threading.Thread(target=worker, args=(target_queue,))
t.start()
threads.append(t)
for t in threads:
t.join()
if args.output:
with open(args.output, 'w') as output_file:
for ip in vulnerable_ips:
output_file.write(f"{ip}\n")
print_message('info', "Scanning complete.")
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print_message('error', "Scanning interrupted by user.")
sys.exit(1)
使用方法
python
python3 ssh_poc.py -u 172.16.12.137
python3 ssh_poc.py -f ips.txt
github
https://github.com/bigb0x/CVE-2024-6387https://github.com/bigb0x/CVE-2024-6387
CVE-2024-6387
漏洞信息
2024年7月1日,OpenSSH 官方发布安全通告,披露CVE-2024-6387 OpenSSH Server 远程代码执行漏洞。漏洞成因 为 条件竞争,因此若要成功利用该漏洞,需要经过多次尝试,并需要绕过相关系统保护措施(如ASLR),在实际网络环境下利用难度较大。同时安装于0penBsD系统/Windows系统中的OpenssH 也不受该漏洞影响。