SSH Vulnerability Scanner

一款专业的SSH服务漏洞批量检测工具,通过Nmap引擎对多个域名进行并发扫描,精准识别存在已知安全漏洞的OpenSSH版本,帮助安全团队快速定位风险资产。

功能特性

  • 批量域名扫描:支持从文件中读取多个域名,一行一个,实现批量检测
  • 多线程并发:采用线程池技术,大幅提升大规模扫描效率
  • 精准版本识别:自动检测SSH服务版本,对比13个已知漏洞版本(OpenSSH 8.5p1至9.7p1)
  • 智能端口扫描:预设22和2222端口,可自定义扩展SSH服务端口范围
  • 彩色输出报告:使用termcolor库对漏洞版本进行红色高亮,非漏洞版本黄色标记
  • Nmap脚本增强:集成ssh2-enum-algos、ssh-auth-methods、ssh-hostkey等专用脚本
  • 错误处理机制:自动处理DNS解析失败、Nmap执行错误等异常情况

安装指南

系统要求

  • Python 3.x
  • Nmap安全扫描工具
  • 网络连接(用于域名解析和端口扫描)

依赖安装

  1. 安装Nmap(如果未安装):

    # Ubuntu/Debian
    sudo apt-get install nmap
    
    # CentOS/RHEL
    sudo yum install nmap
    
    # macOS
    brew install nmap
    
  2. 安装Python依赖

    pip install termcolor
    
  3. 获取脚本

    git clone https://github.com/thegenetic/CVE-2024-6387-exploit.git
    cd CVE-2024-6387-exploit
    

使用说明

基础用法

  1. 准备域名列表文件(例如 domains.txt):

    example.com
    github.com
    stackoverflow.com
    
  2. 运行扫描器

    python CVE-2024-6387.py domains.txt
    

扫描示例

$ python ssh_vuln_scanner.py domains.txt

Scanning example.com (93.184.216.34)...
Scanning github.com (140.82.112.3)...
Scanning stackoverflow.com (151.101.1.69)...

Scan Results:

example.com:
22/tcp: SSH-2.0-OpenSSH_8.8p1  # 红色显示(漏洞版本)
2222/tcp: SSH-2.0-OpenSSH_8.6p1  # 红色显示(漏洞版本)

github.com:
22/tcp: SSH-2.0-OpenSSH_9.5p1  # 红色显示(漏洞版本)

stackoverflow.com:
No SSH service detected on open ports

工作流程

  1. 域名解析:将每个域名转换为IP地址
  2. Nmap扫描:对指定端口(22,2222)执行服务和版本探测
  3. 版本匹配:将检测到的SSH版本与漏洞版本库对比
  4. 结果输出:分类显示漏洞版本(红色)和非漏洞版本(黄色)

核心代码

主扫描函数

def scan_domain(domain, queue):
    """扫描单个域名的SSH服务"""
    try:
        ip_address = socket.gethostbyname(domain)
        print(f"Scanning {domain} ({ip_address})...")

        # 使用Nmap扫描SSH服务端口
        ports = "22,2222"
        nmap_command = f"nmap -Pn -sV -p {ports} --script ssh2-enum-algos,ssh-auth-methods,ssh-hostkey,ssh-run,sshv1 {ip_address}"

        try:
            output = subprocess.check_output(nmap_command, shell=True, stderr=subprocess.STDOUT)
            process_nmap_output(domain, output.decode())
        except subprocess.CalledProcessError as e:
            print(f"Error scanning {domain}: {e.output.decode()}")
            results[domain] = f"Nmap Error: {e.output.decode()}"

    except socket.gaierror as e:
        print(f"Error: Could not resolve domain {domain}: {str(e)}")
        results[domain] = f"DNS resolution error: {str(e)}"

    queue.task_done()

Nmap输出处理

def process_nmap_output(domain, output):
    """解析Nmap输出并识别漏洞版本"""
    vulnerable_versions = [
        'SSH-2.0-OpenSSH_8.5p1',
        'SSH-2.0-OpenSSH_8.6p1',
        'SSH-2.0-OpenSSH_8.7p1',
        'SSH-2.0-OpenSSH_8.8p1',
        'SSH-2.0-OpenSSH_8.9p1',
        'SSH-2.0-OpenSSH_9.0p1',
        'SSH-2.0-OpenSSH_9.1p1',
        'SSH-2.0-OpenSSH_9.2p1',
        'SSH-2.0-OpenSSH_9.3p1',
        'SSH-2.0-OpenSSH_9.4p1',
        'SSH-2.0-OpenSSH_9.5p1',
        'SSH-2.0-OpenSSH_9.6p1',
        'SSH-2.0-OpenSSH_9.7p1'
    ]

    if "Nmap scan report" in output:
        lines = output.splitlines()
        for line in lines:
            if "SSH" in line and "open" in line:
                parts = line.split()
                port = parts[0]
                version = parts[-1]
                if any(vuln_version in version for vuln_version in vulnerable_versions):
                    result = colored(version, 'red')
                else:
                    result = colored(version, 'yellow')
                lock.acquire()
                if domain not in results:
                    results[domain] = {}
                results[domain][port] = result
                lock.release()

多线程调度器

def scan_domains(input_file):
    """使用线程池批量扫描域名"""
    queue = Queue()

    with open(input_file, 'r') as f:
        domains = f.read().strip().splitlines()

    # 为每个域名创建独立线程
    for domain in domains:
        queue.put(domain)
        t = Thread(target=scan_domain, args=(domain, queue))
        t.daemon = True
        t.start()

    queue.join()

    # 打印扫描结果
    print("\nScan Results:\n")
    for domain, data in results.items():
        print(f"{domain}:")
        if isinstance(data, str):
            print(data)
        else:
            for port, version in data.items():
                print(f"{port}: {version}")
            if not data:
                print("No SSH service detected on open ports")
        print()

技术参数

配置项说明
扫描端口22, 2222(可修改)
Nmap参数-Pn -sV
检测脚本ssh2-enum-algos, ssh-auth-methods, ssh-hostkey, ssh-run, sshv1
漏洞版本库OpenSSH 8.5p1 ~ 9.7p1(13个版本)
并发模型多线程(Thread)
输出格式彩色终端文本
6HFtX5dABrKlqXeO5PUv/zyPZu04lXes2ESCCpxrfi8CzuyKvlZDOwG0JTZL6pF8