Python脚本实现扫描网站子域名及漏洞

 更新时间:2025年12月03日 08:35:32   作者:宏权实验室  
这篇文章主要为大家详细介绍了如何使用Python编写一个域名漏洞扫描脚本,可以实现子域名枚举,端口扫描,服务识别和常见漏洞检测,感兴趣的小伙伴可以了解下

完整代码如下:

scanner.py

#!/usr/bin/env python3
"""
域名漏洞扫描脚本
功能:子域名枚举、端口扫描、服务识别、常见漏洞检测
"""

import requests
import socket
import threading
import subprocess
import json
import time
from urllib.parse import urljoin
import dns.resolver
import ssl
import argparse
from concurrent.futures import ThreadPoolExecutor


class DomainVulnerabilityScanner:
    def __init__(self, domain, threads=50):
        self.domain = domain
        self.threads = threads
        self.results = {
            'domain': domain,
            'subdomains': [],
            'open_ports': [],
            'vulnerabilities': [],
            'services': [],
            'ssl_info': {}
        }

    def subdomain_enumeration(self):
        """子域名枚举"""
        print(f"[+] 开始子域名枚举: {self.domain}")

        # 常见子域名列表
        common_subdomains = [
            'www', 'mail', 'ftp', 'localhost', 'webmail', 'smtp', 'pop', 'ns1', 'webdisk',
            'ns2', 'cpanel', 'whm', 'autodiscover', 'autoconfig', 'm', 'imap', 'test',
            'blog', 'pop3', 'dev', 'www2', 'admin', 'forum', 'news', 'vpn', 'ns3', 'mail2',
            'new', 'mysql', 'old', 'lists', 'support', 'mobile', 'mx', 'static', 'docs',
            'beta', 'shop', 'sql', 'secure', 'demo', 'cp', 'calendar', 'wiki', 'api',
            'media', 'email', 'images', 'img', 'www1', 'intranet', 'portal', 'video',
            'search', 'cdn', 'remote', 'db', 'forums', 'store', 'relay', 'files',
            'newsletter', 'app', 'apps', 'download', 'uploads', 'dns', 'ns4', 'sftp'
        ]

        found_subdomains = []

        def check_subdomain(subdomain):
            full_domain = f"{subdomain}.{self.domain}"
            try:
                socket.gethostbyname(full_domain)
                found_subdomains.append(full_domain)
                print(f"  [+] 发现子域名: {full_domain}")
            except socket.gaierror:
                pass

        with ThreadPoolExecutor(max_workers=self.threads) as executor:
            executor.map(check_subdomain, common_subdomains)

        self.results['subdomains'] = found_subdomains
        return found_subdomains

    def port_scan(self, host, ports=None):
        """端口扫描"""
        if ports is None:
            ports = [21, 22, 23, 25, 53, 80, 110, 443, 993, 995, 1433, 1521, 3306, 3389, 5432, 5900, 6379, 27017]

        open_ports = []

        def scan_port(port):
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(3)
                result = sock.connect_ex((host, port))
                sock.close()
                if result == 0:
                    service = self.get_service_name(port)
                    open_ports.append({'port': port, 'service': service})
                    print(f"  [+] {host}:{port} 开放 - {service}")
            except Exception:
                pass

        print(f"[+] 开始端口扫描: {host}")
        with ThreadPoolExecutor(max_workers=self.threads) as executor:
            executor.map(scan_port, ports)

        return open_ports

    def get_service_name(self, port):
        """获取服务名称"""
        service_map = {
            21: 'FTP', 22: 'SSH', 23: 'Telnet', 25: 'SMTP', 53: 'DNS',
            80: 'HTTP', 110: 'POP3', 443: 'HTTPS', 993: 'IMAPS',
            995: 'POP3S', 1433: 'MSSQL', 1521: 'Oracle', 3306: 'MySQL',
            3389: 'RDP', 5432: 'PostgreSQL', 5900: 'VNC', 6379: 'Redis',
            27017: 'MongoDB'
        }
        return service_map.get(port, 'Unknown')

    def check_ssl_vulnerabilities(self, host):
        """检查SSL/TLS漏洞"""
        print(f"[+] 检查SSL/TLS配置: {host}")

        try:
            context = ssl.create_default_context()
            with socket.create_connection((host, 443), timeout=5) as sock:
                with context.wrap_socket(sock, server_hostname=host) as ssock:
                    cert = ssock.getpeercert()
                    cipher = ssock.cipher()

                    ssl_info = {
                        'subject': dict(x[0] for x in cert['subject']),
                        'issuer': dict(x[0] for x in cert['issuer']),
                        'not_before': cert['notBefore'],
                        'not_after': cert['notAfter'],
                        'cipher': cipher
                    }

                    self.results['ssl_info'] = ssl_info

                    # 检查证书过期
                    import datetime
                    expire_date = datetime.datetime.strptime(cert['notAfter'], '%b %d %H:%M:%S %Y %Z')
                    if expire_date < datetime.datetime.now():
                        self.results['vulnerabilities'].append({
                            'type': 'SSL',
                            'severity': 'HIGH',
                            'description': 'SSL证书已过期',
                            'host': host
                        })

                    print(f"  [+] SSL信息: {ssl_info}")

        except Exception as e:
            print(f"  [-] SSL检查失败: {e}")

    def web_vulnerability_scan(self, url):
        """Web应用漏洞扫描"""
        print(f"[+] Web漏洞扫描: {url}")

        vulnerabilities = []

        # 检查常见安全头
        try:
            response = requests.get(url, timeout=10, verify=False)
            headers = response.headers

            security_headers = {
                'X-Frame-Options': '点击劫 持保护',
                'X-Content-Type-Options': 'MIME类型嗅探保护',
                'X-XSS-Protection': 'XSS保护',
                'Strict-Transport-Security': 'HSTS',
                'Content-Security-Policy': '内容安全策略'
            }

            for header, description in security_headers.items():
                if header not in headers:
                    vulnerabilities.append({
                        'type': 'WEB',
                        'severity': 'MEDIUM',
                        'description': f'缺少安全头: {header} - {description}',
                        'url': url
                    })

        except Exception as e:
            print(f"  [-] Web扫描失败: {e}")

        return vulnerabilities

    def run_full_scan(self):
        """执行完整扫描"""
        print(f"[*] 开始对 {self.domain} 进行漏洞扫描")
        start_time = time.time()

        # 子域名枚举
        subdomains = self.subdomain_enumeration()

        # 扫描主域名
        targets = [self.domain] + subdomains

        for target in targets:
            # 端口扫描
            open_ports = self.port_scan(target)
            self.results['open_ports'].extend(open_ports)

            # SSL检查
            if any(port['port'] == 443 for port in open_ports):
                self.check_ssl_vulnerabilities(target)

            # Web漏洞扫描
            for port_info in open_ports:
                if port_info['port'] in [80, 443, 8080, 8443]:
                    scheme = 'https' if port_info['port'] in [443, 8443] else 'http'
                    url = f"{scheme}://{target}:{port_info['port']}"
                    web_vulns = self.web_vulnerability_scan(url)
                    self.results['vulnerabilities'].extend(web_vulns)

        # 生成报告
        self.generate_report()

        end_time = time.time()
        print(f"\n[*] 扫描完成! 用时: {end_time - start_time:.2f}秒")

        return self.results

    def generate_report(self):
        """生成扫描报告"""
        report = f"""
域名漏洞扫描报告
================

目标域名: {self.results['domain']}
扫描时间: {time.strftime('%Y-%m-%d %H:%M:%S')}

发现子域名 ({len(self.results['subdomains'])}个):
{chr(10).join(['  - ' + sub for sub in self.results['subdomains']])}

开放端口:
{chr(10).join([f"  - {item['host'] if 'host' in item else self.domain}:{item['port']} ({item['service']})" for item in self.results['open_ports']])}

发现漏洞 ({len(self.results['vulnerabilities'])}个):
"""

        for i, vuln in enumerate(self.results['vulnerabilities'], 1):
            report += f"""
{i}. 类型: {vuln['type']}
   严重性: {vuln['severity']}
   描述: {vuln['description']}
   目标: {vuln.get('host', vuln.get('url', 'N/A'))}
"""

        # 保存报告
        filename = f"scan_report_{self.domain}_{int(time.time())}.txt"
        with open(filename, 'w', encoding='utf-8') as f:
            f.write(report)

        print(f"[+] 报告已保存至: {filename}")

        return report


def main():
    parser = argparse.ArgumentParser(description='域名漏洞扫描器')
    parser.add_argument('domain', help='要扫描的域名')
    parser.add_argument('-t', '--threads', type=int, default=50, help='线程数 (默认: 50)')

    args = parser.parse_args()

    scanner = DomainVulnerabilityScanner(args.domain, args.threads)
    results = scanner.run_full_scan()

    # 输出摘要
    print(f"\n{'=' * 50}")
    print("扫描摘要:")
    print(f"子域名: {len(results['subdomains'])}个")
    print(f"开放端口: {len(results['open_ports'])}个")
    print(f"发现漏洞: {len(results['vulnerabilities'])}个")
    print(f"{'=' * 50}")


if __name__ == "__main__":
    main()

扫描效果:

到此这篇关于Python脚本实现扫描网站子域名及漏洞的文章就介绍到这了,更多相关Python域名漏洞扫描内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python实现PC屏幕截图并自动发送邮箱

    Python实现PC屏幕截图并自动发送邮箱

    这篇文章主要为大家详细介绍了如何使用Python实现一个屏幕截图应用程序,可以定时截取屏幕,并将截图通过电子邮件发送给指定的收件人,需要的可以参考下
    2024-12-12
  • numpy.insert()的具体使用方法

    numpy.insert()的具体使用方法

    本文主要介绍了numpy.insert()的具体使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • 基于DataFrame改变列类型的方法

    基于DataFrame改变列类型的方法

    今天小编就为大家分享一篇基于DataFrame改变列类型的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • Selenium启动Chrome时配置选项详解

    Selenium启动Chrome时配置选项详解

    这篇文章主要介绍了Selenium启动Chrome时配置选项详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • Python比较两个日期的两种方法详解

    Python比较两个日期的两种方法详解

    我们使用Python处理日期/时间的时候,经常会遇到各种各样的问题。本文为大家总结了两个Python比较两个日期的方法,需要的可以参考一下
    2022-07-07
  • 基于Python实现文件分类器的示例代码

    基于Python实现文件分类器的示例代码

    这篇文章主要为大家详细介绍了如何基于Python实现文件分类器,目的主要是为了将办公过程中产生的各种格式的文件完成整理,感兴趣的可以了解一下
    2023-04-04
  • python matplotlib绘图过程中设置线条颜色实战举例

    python matplotlib绘图过程中设置线条颜色实战举例

    Matplotlib是一个用于数据可视化和创建交互式图表的Python库,下面这篇文章主要给大家介绍了关于python matplotlib绘图过程中设置线条颜色的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-05-05
  • Python语言中Tuple的由来分析

    Python语言中Tuple的由来分析

    Tuple在Python中表示一种“大小固定的有序序列”,这篇文章主要介绍了Python语言中Tuple的由来,需要的朋友可以参考下
    2022-09-09
  • 简单谈谈Python中的元祖(Tuple)和字典(Dict)

    简单谈谈Python中的元祖(Tuple)和字典(Dict)

    这篇文章主要介绍了关于Python中元祖(Tuple)和字典(Dict)的相关资料,文中通过示例代码介绍的非常详细,相信对大家具有一定的参考价值,需要的朋友们下面来一起看看吧。
    2017-04-04
  • 基于python实现制作发货单

    基于python实现制作发货单

    这篇文章主要为大家详细介绍了如何基于python实现制作发货单,并将还html转为pdf,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2024-11-11

最新评论