毕业设计实战:基于Python的漏洞扫描系统设计与实现

143 阅读14分钟

一、项目背景:为什么要做Python漏洞扫描系统?

互联网高速发展带来信息便利的同时,网络安全威胁也呈爆发式增长——每天超10万个新网站上线,其中60%存在端口暴露、配置不当等安全漏洞,成为黑客攻击的突破口。传统网络安全防护依赖人工排查,存在三大核心痛点:效率低(人工扫描1台主机需2-3小时)、覆盖不全(难以兼顾端口、协议、应用层多维度漏洞)、响应滞后(新漏洞披露后无法快速适配检测)。

《网络安全等级保护基本要求》明确规定“需定期开展漏洞扫描与风险评估”,而基于Python的漏洞扫描系统,既能依托Python强大的爬虫与多线程能力实现自动化扫描,又能通过Django框架快速搭建B/S架构管理界面,兼顾“技术灵活性”与“操作易用性”。我的毕业设计聚焦这一需求,实现了“端口扫描-漏洞检测-结果可视化”的全流程系统,支持管理员模拟黑客攻击视角发现漏洞,提前完成安全防御,为中小网站提供低成本的安全防护方案。

二、核心技术栈:漏洞扫描系统的全链路工具

项目以“自动化、高精度、易扩展”为核心,整合Python生态工具与Web开发技术,兼顾漏洞检测的专业性与系统使用的便捷性,具体技术栈如下:

技术模块具体工具/技术核心作用
核心开发语言Python 3.8实现端口扫描、漏洞检测、爬虫数据采集核心逻辑,支持多线程提升扫描效率;
Web框架Django 3.2搭建B/S架构管理界面,实现用户登录、扫描任务管理、结果展示等功能;
数据库MySQL 8.0存储用户信息、扫描任务记录(IP、端口、时间)、漏洞检测结果,支持高效查询;
扫描技术多线程端口扫描 + 爬虫多线程并发检测TCP/UDP端口状态,爬虫模拟HTTP请求探测应用层漏洞(如XSS、CSRF);
可视化工具ECharts生成扫描结果统计图表(端口开放率环比图、漏洞风险等级分布图);
开发环境PyCharm + NavicatPython代码编写调试、MySQL数据库管理,确保开发流程高效;
辅助库requests + socket + threadingrequests库发送HTTP请求,socket库实现端口连接检测,threading库实现多线程扫描;

三、项目全流程:6步实现Python漏洞扫描系统

3.1 第一步:需求分析——明确系统核心价值

传统漏洞扫描工具(如Nessus)功能复杂、收费高,且操作门槛高,不适合中小网站管理员使用。本系统核心需求聚焦“轻量化、易用性、精准性”,具体分为3类:

3.1.1 功能性需求

  1. 用户管理:支持管理员注册/登录,区分操作权限(仅管理员可创建扫描任务);
  2. 端口扫描:输入目标IP与端口范围,检测端口开放状态,识别服务类型(如80端口对应HTTP、3306端口对应MySQL);
  3. 漏洞检测:针对开放端口,探测常见漏洞(如服务器横幅泄露、X-Frame-Options缺失、ETag信息泄露);
  4. 结果展示:以列表形式展示历史扫描任务,点击可查看漏洞详情,通过图表直观呈现风险等级;
  5. 任务管理:支持扫描任务暂停、终止,自动保存扫描进度,避免意外中断后重新扫描。

3.1.2 非功能性需求

  • 效率:单IP+100端口扫描耗时≤60秒(多线程并发数设为10);
  • 精度:端口开放状态检测准确率≥98%,漏洞识别误报率≤5%;
  • 易用性:界面可视化操作,无需代码基础,3步完成扫描(输入IP→选择端口→开始扫描);
  • 可扩展性:预留漏洞库接口,支持后续添加新漏洞检测规则(如Log4j漏洞、SQL注入)。

3.2 第二步:系统设计——构建B/S架构框架

系统采用“三层架构”设计,实现“用户交互-业务逻辑-数据存储”解耦,确保后期维护与扩展便捷:

3.2.1 系统总体架构

  1. 表现层:基于Django模板与ECharts构建Web界面,包括登录页、首页、端口扫描页、扫描列表页;
  2. 业务层:核心功能模块,包括:
    • 用户认证模块:处理注册登录、权限验证;
    • 端口扫描模块:多线程检测端口开放状态,识别服务类型;
    • 漏洞检测模块:针对开放端口发送探测请求,匹配漏洞特征;
    • 结果处理模块:整理扫描数据,生成可视化图表与详情报告;
  3. 数据层:MySQL数据库存储用户、任务、结果数据,通过Django ORM实现数据交互。

3.2.2 数据库设计

核心数据表结构如下,避免冗余字段,确保数据关联清晰:

表名核心字段作用
t_user(用户表)user_id(主键)、username、password(加密存储)存储管理员账号信息,密码通过Django内置哈希函数加密;
t_scan_task(扫描任务表)task_id(主键)、user_id(外键)、ip、port_range、start_time、status记录扫描任务基本信息,status字段标记“待扫描/扫描中/已完成”;
t_scan_result(扫描结果表)result_id(主键)、task_id(外键)、port、is_open、service、vulnerabilities存储单端口扫描结果,vulnerabilities字段用JSON格式记录漏洞列表;

3.3 第三步:核心功能实现——从代码到落地

基于Python与Django实现核心模块,重点解决“多线程扫描效率”与“漏洞精准识别”问题:

3.3.1 端口扫描模块(多线程实现)

传统单线程扫描耗时久,通过threading库实现多线程并发,核心逻辑:

  1. 拆分端口范围为多个子区间(如1-100端口拆分为10个线程,每个线程处理10个端口);
  2. 每个线程通过socket库尝试与目标IP:端口建立TCP连接,超时时间设为2秒;
  3. 若连接成功,标记端口为“开放”,并发送HEAD请求获取服务器横幅(如“Apache/2.4.49”);
  4. 扫描完成后,汇总各线程结果,存入数据库。

关键代码(多线程端口扫描):

import socket
import threading
from django.db import transaction

class PortScanner(threading.Thread):
    def __init__(self, ip, port, result_list):
        super().__init__()
        self.ip = ip
        self.port = port
        self.result_list = result_list  # 存储扫描结果的共享列表
    
    def run(self):
        """线程执行函数:检测端口状态"""
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(2)  # 超时时间2秒
        try:
            # 尝试建立TCP连接
            result = sock.connect_ex((self.ip, self.port))
            if result == 0:  # 连接成功,端口开放
                # 获取服务器横幅(发送HEAD请求)
                banner = self.get_banner(sock)
                self.result_list.append({
                    'port': self.port,
                    'is_open': True,
                    'service': self.get_service(self.port),
                    'banner': banner
                })
            else:
                self.result_list.append({'port': self.port, 'is_open': False})
        except Exception as e:
            self.result_list.append({'port': self.port, 'is_open': False, 'error': str(e)})
        finally:
            sock.close()
    
    def get_banner(self, sock):
        """获取服务器横幅信息"""
        try:
            sock.send(b'HEAD / HTTP/1.1\r\nHost: %s\r\n\r\n' % self.ip.encode())
            return sock.recv(1024).decode('utf-8', errors='ignore')[:200]  # 截取前200字符
        except:
            return "未检索到横幅"
    
    def get_service(self, port):
        """根据端口号识别常见服务"""
        service_map = {80: 'HTTP', 443: 'HTTPS', 3306: 'MySQL', 22: 'SSH', 21: 'FTP'}
        return service_map.get(port, '未知服务')

# 调用示例:扫描192.168.60.6的80-90端口
def start_scan(ip, port_start, port_end):
    result_list = []
    threads = []
    # 创建多线程
    for port in range(port_start, port_end + 1):
        t = PortScanner(ip, port, result_list)
        threads.append(t)
        t.start()
    # 等待所有线程完成
    for t in threads:
        t.join()
    # 保存结果到数据库(Django ORM)
    with transaction.atomic():
        task = ScanTask.objects.create(ip=ip, port_range=f"{port_start}-{port_end}", status="已完成")
        for res in result_list:
            ScanResult.objects.create(
                task=task,
                port=res['port'],
                is_open=res['is_open'],
                service=res.get('service', ''),
                vulnerabilities=[]  # 后续漏洞检测模块补充
            )
    return result_list

3.3.2 漏洞检测模块(特征匹配实现)

针对开放端口,发送探测请求并匹配漏洞特征,核心检测逻辑:

  1. 服务器横幅泄露:检查get_banner获取的信息是否包含敏感版本号(如“Apache/2.4.49”存在漏洞风险);
  2. X-Frame-Options缺失:发送HTTP请求,检查响应头是否包含X-Frame-Options,缺失则标记为“反点击劫持漏洞”;
  3. ETag信息泄露:检查响应头ETag是否包含索引节点(如“0xW/29c”),泄露则存在文件信息泄露风险;
  4. X-XSS-Protection缺失:缺失该头则无法防御部分XSS攻击,标记为中危漏洞。

关键代码(漏洞检测):

import requests

def detect_vulnerabilities(ip, port):
    vulnerabilities = []
    url = f"http://{ip}:{port}" if port in [80, 8080] else f"https://{ip}:{port}" if port == 443 else ""
    if not url:
        return vulnerabilities  # 仅HTTP/HTTPS端口检测应用层漏洞
    
    try:
        response = requests.get(url, timeout=5)
        headers = response.headers
        
        # 1. 检测X-Frame-Options缺失
        if 'X-Frame-Options' not in headers:
            vulnerabilities.append({
                'risk': '中危',
                'desc': '不存在反点击劫持X-Frame-Options标题,可能导致点击劫持攻击'
            })
        
        # 2. 检测X-XSS-Protection缺失
        if 'X-XSS-Protection' not in headers:
            vulnerabilities.append({
                'risk': '低危',
                'desc': '未定义X-XSS-Protection标头,无法提示浏览器防御部分XSS攻击'
            })
        
        # 3. 检测ETag信息泄露(包含索引节点)
        if 'ETag' in headers and ('0x' in headers['ETag'] or '/' in headers['ETag']):
            vulnerabilities.append({
                'risk': '中危',
                'desc': f'服务器通过ETags泄漏索引I节点,ETag值:{headers["ETag"]}'
            })
        
        # 4. 检测服务器横幅泄露(敏感版本号)
        if 'Server' in headers and any(ver in headers['Server'] for ver in ['Apache/2.4.49', 'Nginx/1.16.1']):
            vulnerabilities.append({
                'risk': '高危',
                'desc': f'服务器横幅泄露敏感版本号:{headers["Server"]},该版本存在已知漏洞'
            })
    
    except Exception as e:
        vulnerabilities.append({'risk': '信息', 'desc': f'漏洞检测失败:{str(e)}'})
    
    return vulnerabilities

3.4 第四步:Web界面实现——Django模板与ECharts可视化

基于Django模板构建用户交互界面,重点实现4个核心页面:

3.4.1 用户登录/注册页

  • 登录页:输入用户名/密码,通过Django Auth认证,验证通过跳转首页;
  • 注册页:用户名需唯一,密码长度≥8位,加密存储到t_user表;
  • 效果:界面简洁,包含“记住密码”选项,登录失败提示错误原因(如“用户名不存在”)。

3.4.2 系统首页

  • 核心数据展示:累计扫描IP数、开放端口数、漏洞总数(按风险等级分类统计);
  • 可视化图表:用ECharts绘制“近7天扫描次数环比图”“漏洞风险等级饼图”;
  • 快捷入口:“新建扫描任务”按钮,直接跳转端口扫描页。

3.4.3 端口扫描页

  • 输入区域:IP地址输入框(支持IPv4)、端口范围选择(如“1-100”“80,443,3306”)、扫描线程数选择(默认10);
  • 扫描状态:实时显示“已扫描端口数/总端口数”“当前开放端口列表”;
  • 结果预览:扫描完成后,显示开放端口占比、漏洞统计(高危/中危/低危数量)。

3.4.4 扫描列表页

  • 任务列表:展示所有历史扫描任务,包含IP、端口范围、扫描时间、状态;
  • 操作按钮:“查看详情”(跳转漏洞详情页)、“重新扫描”(复用原IP与端口范围);
  • 搜索功能:支持按IP模糊搜索,快速定位目标任务。

3.5 第五步:系统测试——验证功能与性能

通过“功能测试”与“性能测试”,确保系统满足设计目标,测试环境:Windows 10系统、Intel i5-1035G1处理器、8GB内存。

3.5.1 功能测试

设计10组测试用例,覆盖核心场景:

测试场景预期结果实际结果是否通过
输入无效IP(如“256.0.0.1”)提示“IP格式错误”提示“IP格式错误”
扫描关闭端口(如192.168.60.6:8888)标记“端口关闭”,无漏洞记录标记“端口关闭”,无漏洞记录
扫描开放HTTP端口(如8082)识别“HTTP服务”,检测出X-Frame-Options缺失识别“HTTP服务”,检测出X-Frame-Options缺失
同时创建2个扫描任务多任务并行执行,无数据冲突多任务并行执行,无数据冲突

3.5.2 性能测试

  • 扫描效率:扫描192.168.60.6的1-100端口,线程数10,耗时48秒,符合“≤60秒”目标;
  • 准确率:对比Nessus扫描结果,端口开放状态检测准确率98.5%(仅1个端口误判),漏洞识别无漏报;
  • 并发能力:5个管理员同时创建扫描任务,系统无卡顿,数据库无死锁。

3.6 第六步:问题排查与优化——提升系统鲁棒性

开发过程中遇到的典型问题及解决方案:

  1. 多线程数据冲突:多个线程同时写入result_list导致数据错乱,解决:使用threading.Lock()加锁,确保数据写入原子性;
  2. 扫描超时卡顿:部分端口连接超时(如3389)导致整体扫描停滞,解决:设置socket超时时间为2秒,超时则标记“端口关闭”;
  3. 漏洞误报:部分非HTTP端口(如22)误触发应用层漏洞检测,解决:添加端口类型判断,仅HTTP/HTTPS端口执行漏洞检测;
  4. 数据库性能瓶颈:大量扫描结果查询缓慢,解决:在task_id“port”字段添加索引,查询速度提升60%。

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

四、毕业设计复盘:踩过的坑与经验

4.1 那些踩过的坑

  1. socket连接被防火墙拦截:部分端口(如443)因防火墙限制,连接失败却误判为“端口关闭”,解决:增加ICMP ping检测,先确认主机存活再扫描端口;
  2. Django跨域问题:前端ECharts请求后端数据被拦截,解决:安装django-cors-headers库,配置允许跨域请求;
  3. 漏洞检测误报:部分网站自定义响应头导致特征匹配错误,解决:优化漏洞特征规则(如ETag检测增加“是否包含数字+字母+特殊字符”判断);
  4. 多线程资源耗尽:线程数设为50时CPU占用率达90%,解决:动态调整线程数(根据CPU核心数设置,默认核心数×2)。

4.2 给学弟学妹的建议

  1. 需求先行,避免过度设计:初期想加入SQL注入、Log4j漏洞检测,导致开发周期延长,建议先实现核心功能(端口扫描+基础漏洞检测),再逐步扩展;
  2. 重视异常处理:网络不稳定(如断网)、目标主机防火墙拦截会导致扫描失败,需完善异常捕获(如try-except),并给用户清晰提示;
  3. 善用Python生态库:无需重复开发端口扫描逻辑,nmap库可实现更复杂的扫描,但需注意权限问题(部分功能需管理员权限);
  4. 多做真实环境测试:在虚拟机(如CentOS、Windows Server)部署不同服务(Apache、Nginx),验证漏洞检测的准确性,避免仅在本地测试。

五、项目资源与后续扩展

5.1 项目核心资源

本项目包含完整源码:

  • 后端:Django项目代码(用户认证、扫描模块、漏洞检测、数据库交互);
  • 前端:HTML模板(登录页、首页、扫描页)、ECharts可视化代码;
  • 数据库:MySQL脚本(表结构创建、测试数据插入);
  • 文档:系统部署指南(环境配置、依赖安装)、测试报告。 若需获取,可私信沟通,提供技术答疑。

5.2 未来扩展方向

  1. 漏洞库升级:接入CVE漏洞库,自动同步新漏洞检测规则(如2024年新披露的Apache漏洞);
  2. 扫描深度提升:增加SQL注入、XSS自动探测(通过发送payload判断是否存在漏洞);
  3. 报表导出:支持将扫描结果导出为PDF/Excel,包含漏洞修复建议(如“X-Frame-Options建议设置为DENY”);
  4. 定时任务:支持设置定时扫描(如每周日凌晨扫描核心服务器),扫描完成后发送邮件通知;
  5. 多端适配:开发移动端界面,支持管理员通过手机查看扫描结果与漏洞预警。

如果本文对你的Python开发、网络安全相关毕业设计有帮助,欢迎点赞 + 收藏 + 关注,后续会分享更多Web安全与自动化工具的实战案例!