一、项目背景:为什么要做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 + Navicat | Python代码编写调试、MySQL数据库管理,确保开发流程高效; |
| 辅助库 | requests + socket + threading | requests库发送HTTP请求,socket库实现端口连接检测,threading库实现多线程扫描; |
三、项目全流程:6步实现Python漏洞扫描系统
3.1 第一步:需求分析——明确系统核心价值
传统漏洞扫描工具(如Nessus)功能复杂、收费高,且操作门槛高,不适合中小网站管理员使用。本系统核心需求聚焦“轻量化、易用性、精准性”,具体分为3类:
3.1.1 功能性需求
- 用户管理:支持管理员注册/登录,区分操作权限(仅管理员可创建扫描任务);
- 端口扫描:输入目标IP与端口范围,检测端口开放状态,识别服务类型(如80端口对应HTTP、3306端口对应MySQL);
- 漏洞检测:针对开放端口,探测常见漏洞(如服务器横幅泄露、X-Frame-Options缺失、ETag信息泄露);
- 结果展示:以列表形式展示历史扫描任务,点击可查看漏洞详情,通过图表直观呈现风险等级;
- 任务管理:支持扫描任务暂停、终止,自动保存扫描进度,避免意外中断后重新扫描。
3.1.2 非功能性需求
- 效率:单IP+100端口扫描耗时≤60秒(多线程并发数设为10);
- 精度:端口开放状态检测准确率≥98%,漏洞识别误报率≤5%;
- 易用性:界面可视化操作,无需代码基础,3步完成扫描(输入IP→选择端口→开始扫描);
- 可扩展性:预留漏洞库接口,支持后续添加新漏洞检测规则(如Log4j漏洞、SQL注入)。
3.2 第二步:系统设计——构建B/S架构框架
系统采用“三层架构”设计,实现“用户交互-业务逻辑-数据存储”解耦,确保后期维护与扩展便捷:
3.2.1 系统总体架构
- 表现层:基于Django模板与ECharts构建Web界面,包括登录页、首页、端口扫描页、扫描列表页;
- 业务层:核心功能模块,包括:
- 用户认证模块:处理注册登录、权限验证;
- 端口扫描模块:多线程检测端口开放状态,识别服务类型;
- 漏洞检测模块:针对开放端口发送探测请求,匹配漏洞特征;
- 结果处理模块:整理扫描数据,生成可视化图表与详情报告;
- 数据层: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-100端口拆分为10个线程,每个线程处理10个端口);
- 每个线程通过
socket库尝试与目标IP:端口建立TCP连接,超时时间设为2秒; - 若连接成功,标记端口为“开放”,并发送
HEAD请求获取服务器横幅(如“Apache/2.4.49”); - 扫描完成后,汇总各线程结果,存入数据库。
关键代码(多线程端口扫描):
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 漏洞检测模块(特征匹配实现)
针对开放端口,发送探测请求并匹配漏洞特征,核心检测逻辑:
- 服务器横幅泄露:检查
get_banner获取的信息是否包含敏感版本号(如“Apache/2.4.49”存在漏洞风险); - X-Frame-Options缺失:发送HTTP请求,检查响应头是否包含
X-Frame-Options,缺失则标记为“反点击劫持漏洞”; - ETag信息泄露:检查响应头
ETag是否包含索引节点(如“0xW/29c”),泄露则存在文件信息泄露风险; - 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 第六步:问题排查与优化——提升系统鲁棒性
开发过程中遇到的典型问题及解决方案:
- 多线程数据冲突:多个线程同时写入
result_list导致数据错乱,解决:使用threading.Lock()加锁,确保数据写入原子性; - 扫描超时卡顿:部分端口连接超时(如3389)导致整体扫描停滞,解决:设置
socket超时时间为2秒,超时则标记“端口关闭”; - 漏洞误报:部分非HTTP端口(如22)误触发应用层漏洞检测,解决:添加端口类型判断,仅HTTP/HTTPS端口执行漏洞检测;
- 数据库性能瓶颈:大量扫描结果查询缓慢,解决:在
task_id“port”字段添加索引,查询速度提升60%。
四、毕业设计复盘:踩过的坑与经验
4.1 那些踩过的坑
- socket连接被防火墙拦截:部分端口(如443)因防火墙限制,连接失败却误判为“端口关闭”,解决:增加ICMP ping检测,先确认主机存活再扫描端口;
- Django跨域问题:前端ECharts请求后端数据被拦截,解决:安装
django-cors-headers库,配置允许跨域请求; - 漏洞检测误报:部分网站自定义响应头导致特征匹配错误,解决:优化漏洞特征规则(如ETag检测增加“是否包含数字+字母+特殊字符”判断);
- 多线程资源耗尽:线程数设为50时CPU占用率达90%,解决:动态调整线程数(根据CPU核心数设置,默认核心数×2)。
4.2 给学弟学妹的建议
- 需求先行,避免过度设计:初期想加入SQL注入、Log4j漏洞检测,导致开发周期延长,建议先实现核心功能(端口扫描+基础漏洞检测),再逐步扩展;
- 重视异常处理:网络不稳定(如断网)、目标主机防火墙拦截会导致扫描失败,需完善异常捕获(如
try-except),并给用户清晰提示; - 善用Python生态库:无需重复开发端口扫描逻辑,
nmap库可实现更复杂的扫描,但需注意权限问题(部分功能需管理员权限); - 多做真实环境测试:在虚拟机(如CentOS、Windows Server)部署不同服务(Apache、Nginx),验证漏洞检测的准确性,避免仅在本地测试。
五、项目资源与后续扩展
5.1 项目核心资源
本项目包含完整源码:
- 后端:Django项目代码(用户认证、扫描模块、漏洞检测、数据库交互);
- 前端:HTML模板(登录页、首页、扫描页)、ECharts可视化代码;
- 数据库:MySQL脚本(表结构创建、测试数据插入);
- 文档:系统部署指南(环境配置、依赖安装)、测试报告。 若需获取,可私信沟通,提供技术答疑。
5.2 未来扩展方向
- 漏洞库升级:接入CVE漏洞库,自动同步新漏洞检测规则(如2024年新披露的Apache漏洞);
- 扫描深度提升:增加SQL注入、XSS自动探测(通过发送payload判断是否存在漏洞);
- 报表导出:支持将扫描结果导出为PDF/Excel,包含漏洞修复建议(如“X-Frame-Options建议设置为DENY”);
- 定时任务:支持设置定时扫描(如每周日凌晨扫描核心服务器),扫描完成后发送邮件通知;
- 多端适配:开发移动端界面,支持管理员通过手机查看扫描结果与漏洞预警。
如果本文对你的Python开发、网络安全相关毕业设计有帮助,欢迎点赞 + 收藏 + 关注,后续会分享更多Web安全与自动化工具的实战案例!