ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于Django的可审计漏洞扫描后端系统设计

基于Django的可审计漏洞扫描后端系统设计 简介本资源是一套基于Python与Django框架实现的漏洞扫描系统完整源码面向网络安全初学者、毕业设计学生及Web安全开发实践者旨在解决常见Web应用安全检测的工程化落地问题。压缩包共376个文件涵盖26个核心Python模块含扫描引擎与分析逻辑、53个JavaScript前端交互脚本、75个GIF动图多为UI操作示意、26个CSS样式文件及大量模板tmpl与数据库配置文件如db_headers、db_subdomains等支撑起扫描任务管理、结果可视化与漏洞库维护等关键功能整体包体达82.58MB。已有403人学习下载资源结构清晰包含可直接运行的Django项目骨架、预置漏洞规则库、响应式前端界面及配套静态资源读者可快速部署调试、理解MVT架构下安全工具的前后端协同机制并基于现有模块扩展端口扫描、弱口令检测或ZAP集成等能力。1. 这不是另一个“扫描器界面”而是一个可嵌入、可审计、可二次开发的漏洞扫描后端服务当你在安全团队内部讨论“要不要自建扫描能力”时真正卡住落地的往往不是扫描逻辑本身而是扫描任务如何持久化历史结果怎么比对报告怎么生成 PDF 并自动归档权限怎么和现有 LDAP/AD 对接——这些都不是nmap -sV加个print()就能解决的问题。本项目标题中的“基于 Python Django 的漏洞扫描系统源码数据库.zip”核心价值恰恰落在“Django”这个关键词上它提供了一套开箱即用的 ORM、Admin 后台、用户认证、API 路由、任务调度集成点和数据库迁移机制。这不是一个跑完就丢的脚本集合而是一个带完整数据模型、状态机、审计日志和扩展钩子的扫描生命周期管理平台。适合安全研发工程师、DevSecOps 工程师或需要将扫描能力深度集成进 CI/CD 或 SOC 平台的技术负责人。你不需要重写 Burp 的插件引擎但你需要一个能承载扫描结果、驱动策略执行、并被其他系统调用的“数据中枢”。2. 为什么选 Django 而非 Flask/FastAPI 构建扫描后端从模型设计到状态流转的底层逻辑2.1 扫描系统的核心数据契约必须定义清楚“谁扫了什么、在何时、得到什么、状态如何”一个健壮的漏洞扫描后端其数据库结构绝不能是“一张表存所有 JSON”。Django 的 ORM 强制你显式建模实体关系这直接决定了后续查询效率、权限控制粒度和审计追溯能力。本项目源码中典型的模型设计包含ScanTarget目标资产IP、域名、URL、CIDR带标签tags、所属业务线business_unit、是否启用is_active字段ScanTask一次扫描任务实例关联ScanTarget、ScanProfile预设参数模板、触发人created_by、计划时间scheduled_at、超时阈值timeout_secondsVulnerability标准化漏洞条目CVE/CWE 编号、CVSS 分数、严重等级、描述、POC 链接独立于具体扫描结果ScanResult单次任务的输出快照一对多关联ScanFinding存储原始响应头、HTTP 状态码、响应体截断response_body_truncated、耗时elapsed_secondsScanFinding具体发现项外键指向Vulnerability含路径path、参数parameter、风险证据evidence_snippet、置信度confidence_level。提示ScanFinding.confidence_level是关键设计。它不是布尔值而是LOW/MEDIUM/HIGH/CONFIRMED四级枚举。很多开源扫描器只返回“疑似”而 Django 模型强制你在入库前做一次可信度分级——这对后续告警降噪和人工复核路径至关重要。2.2 Django Admin 不是摆设它是安全运营人员的第一操作界面很多团队误以为 Django Admin 只适合开发调试。但在漏洞扫描场景中它天然适配三类高频操作快速验证与调试安全工程师可直接在 Admin 中新建ScanTask选择目标、指定ScanProfile如“Web 应用基础检查”点击“运行”实时查看ScanResult状态流转PENDING → RUNNING → COMPLETED人工复核与标记在ScanFinding列表页通过actions下拉菜单批量执行“标记为误报”、“转交开发”、“加入白名单”这些操作会自动更新status字段并记录updated_by和updated_at临时数据探查利用 Admin 内置的搜索search_fields [target__ip, vulnerability__cve_id]和过滤list_filter [status, vulnerability__severity]无需写 SQL 即可定位某 IP 的全部高危发现。# models.py 片段ScanFinding 的关键字段定义 class ScanFinding(models.Model): STATUS_CHOICES [ (NEW, 新发现), (FALSE_POSITIVE, 误报), (IN_PROGRESS, 处理中), (RESOLVED, 已修复), (IGNORED, 已忽略), ] status models.CharField(max_length20, choicesSTATUS_CHOICES, defaultNEW) confidence_level models.CharField( max_length15, choices[(LOW, 低), (MEDIUM, 中), (HIGH, 高), (CONFIRMED, 确认)], defaultMEDIUM ) # 外键关联确保数据一致性 scan_result models.ForeignKey(ScanResult, on_deletemodels.CASCADE, related_namefindings) vulnerability models.ForeignKey(Vulnerability, on_deletemodels.PROTECT)2.2.1 为什么on_deletemodels.PROTECT而非CASCADE当Vulnerability记录被删除时PROTECT会抛出ProtectedError异常阻止误删。这是安全数据治理的底线你不能因为删除一个 CVE 条目就让历史上所有关联的扫描发现消失。真实场景中Vulnerability表应由 CVE 官方源定期同步更新而非人工增删。2.3 任务调度不是“加个 APScheduler 就完事”Django-Q 的队列化设计保障扫描稳定性扫描任务具有强 IO 密集性网络请求、文件读写和不确定性目标响应超时、SSL 握手失败。若在 Django 视图中直接调用扫描函数会导致 HTTP 请求长时间挂起拖垮整个 Web 服务。本项目采用django-q实现异步任务队列ScanTask创建后视图层仅调用q_cluster.enqueue(scan_target, profile_id)立即返回任务 IDdjango-qWorker 进程从 Redis 队列中取出任务执行实际扫描逻辑如调用nucleiCLI 或sqlmapapi扫描完成后Worker 更新ScanResult.status并触发post_save信号通知 Admin 页面刷新状态。# 启动 django-q worker生产环境需用 supervisor/systemd 管理 python manage.py qcluster注意django-q依赖 Redis。若你的环境无 Redis必须先部署 Redis 服务并修改settings.py中的Q_CLUSTER配置。切勿用 Django 默认的locmem缓存后端替代——它不支持跨进程通信会导致任务丢失。3. 从源码 ZIP 解压到本地可运行4 步完成最小闭环验证3.1 环境准备Python 3.9、PostgreSQL 12、Redis 6 是硬性依赖本项目未使用 SQLite因 SQLite 无法支撑并发扫描任务写入也未使用 MySQL因其 JSON 字段索引能力弱于 PostgreSQL 的jsonb_path_ops。安装命令如下以 Ubuntu 22.04 为例# 安装系统依赖 sudo apt update sudo apt install -y python3.10-venv postgresql-14 redis-server # 初始化 PostgreSQL 数据库假设用户名为 scanner密码为 securepass sudo -u postgres psql -c CREATE DATABASE vulnscanner; sudo -u postgres psql -c CREATE USER scanner WITH PASSWORD securepass; sudo -u postgres psql -c GRANT ALL PRIVILEGES ON DATABASE vulnscanner TO scanner; # 启动 Redis默认端口 6379 sudo systemctl enable redis-server sudo systemctl start redis-server3.2 解压与依赖安装关键在于requirements.txt的分层管理解压漏洞扫描系统源码数据库.zip后进入项目根目录。注意requirements.txt通常包含三层依赖类型文件名说明核心框架requirements/base.txtDjango、psycopg2、django-q、redis、requests扫描引擎requirements/scanners.txtnuclei、sqlmap、nmap需系统级安装开发辅助requirements/dev.txtblack、pytest-django、django-extensions执行安装# 创建虚拟环境推荐 Python 3.10 python3.10 -m venv venv source venv/bin/activate # 安装核心依赖 pip install -r requirements/base.txt # 安装扫描工具nuclei 需单独下载二进制 curl -sSfL https://raw.githubusercontent.com/projectdiscovery/nuclei/v3/scripts/install.sh | sh -s sudo mv nuclei /usr/local/bin/ # 验证 nuclei 是否可用 nuclei -version # 应输出 v3.x.x3.3 数据库迁移与超级用户创建绕过manage.py migrate常见陷阱Django 迁移脚本可能因数据库权限或表名冲突失败。务必按顺序执行# 1. 设置环境变量避免硬编码密码 export DB_NAMEvulnscanner export DB_USERscanner export DB_PASSWORDsecurepass export DB_HOSTlocalhost export DB_PORT5432 # 2. 执行迁移首次运行会创建所有表 python manage.py migrate # 3. 创建超级用户用于登录 Admin python manage.py createsuperuser --username admin --email adminexample.com # 4. 加载初始数据如有 fixtures python manage.py loaddata initial_vulnerabilities.json提示若migrate报错relation auth_user does not exist说明django.contrib.auth未正确加载。检查settings.py中INSTALLED_APPS是否包含django.contrib.auth和django.contrib.contenttypes且顺序正确auth必须在contenttypes之后。3.4 启动服务并验证最小扫描流用localhost:8000/admin触发一次真实扫描启动 Django 开发服务器python manage.py runserver 0.0.0.0:8000访问http://localhost:8000/admin用刚创建的超级用户登录。按以下路径操作添加目标ScanTargets→Add scan target→ 输入127.0.0.1标签填local-test保存配置扫描模板ScanProfiles→Add scan profile→ 名称填Quick HTTP Check参数填-t httpx -silent调用 httpx 工具发起扫描回到ScanTargets列表勾选刚添加的目标下拉选择Run scan with profile选中Quick HTTP Check点击Go查看结果几秒后刷新页面在ScanResults列表中找到新记录点击进入详情页确认status为COMPLETEDfindings_count 0。此时你已跑通从 UI 创建任务、异步执行、结果入库、Admin 展示的全链路。下一步即可接入真实资产或扩展扫描插件。4. 扫描引擎集成实战如何将nuclei、httpx、sqlmapapi作为 Django 的“可插拔模块”4.1nuclei集成用subprocess.run调用 CLI解析 JSONL 输出并映射到 Django 模型nuclei的优势在于模板生态丰富但其输出是 JSONL每行一个 JSON 对象需逐行解析。Django 任务函数示例# tasks.py import json import subprocess from django.conf import settings from .models import ScanResult, ScanFinding, Vulnerability def run_nuclei_scan(target_url, template_path): 执行 nuclei 扫描并入库 cmd [ nuclei, -u, target_url, -t, template_path, -jsonl, # 关键输出 JSONL 格式 -silent, # 减少日志干扰 -timeout, 30 ] try: result subprocess.run( cmd, capture_outputTrue, textTrue, timeout120 # 总超时 ) # 解析 JSONL 输出 findings [] for line in result.stdout.strip().split(\n): if not line.strip(): continue try: data json.loads(line) # 映射到 Django 模型字段 vuln, _ Vulnerability.objects.get_or_create( cve_iddata.get(cve_id, ), defaults{ name: data.get(info, {}).get(name, Unknown), severity: data.get(info, {}).get(severity, medium).upper(), description: data.get(info, {}).get(description, ) } ) findings.append(ScanFinding( scan_resultscan_result, # 外键需传入 vulnerabilityvuln, pathdata.get(matched-at, ), evidence_snippetdata.get(matcher-name, ), confidence_levelCONFIRMED if data.get(type) http else HIGH )) except json.JSONDecodeError: continue # 跳过解析失败的行 # 批量创建提升性能 ScanFinding.objects.bulk_create(findings) return True except subprocess.TimeoutExpired: return False4.1.1 为什么不用nuclei的-o output.json而用-jsonl-jsonl流式输出可在扫描过程中实时解析并入库避免等待整个扫描结束才处理而-o是阻塞式写入大目标扫描可能耗时数分钟导致任务状态长时间卡在RUNNING。4.2sqlmapapi集成用 REST API 封装规避命令行参数注入风险直接拼接sqlmap -u xxx?id1存在命令注入风险。更安全的做法是启动sqlmapapi服务通过 HTTP 调用# 启动 sqlmapapi后台运行 sqlmapapi -s -H 0.0.0.0 -p 8775 Django 任务中调用import requests def run_sqlmap_scan(target_url): # 1. 创建任务 resp requests.post(http://127.0.0.1:8775/task/new) task_id resp.json()[taskid] # 2. 设置目标 requests.post(fhttp://127.0.0.1:8775/scan/{task_id}/start, json{ url: target_url, level: 3, risk: 2 }) # 3. 轮询状态直到完成 while True: status requests.get(fhttp://127.0.0.1:8775/scan/{task_id}/status).json() if status[status] terminated: break time.sleep(5) # 4. 获取结果并解析 results requests.get(fhttp://127.0.0.1:8775/scan/{task_id}/data).json() # ... 解析 results[data] 并创建 ScanFinding ...提示sqlmapapi默认无认证生产环境必须通过 Nginx 添加 Basic Auth 或 IP 白名单否则暴露sqlmapapi端口等于开放数据库渗透入口。4.3 扫描参数安全校验防止用户输入破坏系统ScanProfile.parameters字段若允许任意字符串攻击者可注入; rm -rf /。必须在保存前校验# models.py 中 ScanProfile 的 clean 方法 def clean(self): super().clean() # 白名单校验只允许 nuclei/httpx/sqlmap 的合法参数 allowed_flags {-u, -t, -jsonl, -silent, -timeout, --level, --risk} params self.parameters.split() for param in params: if param.startswith(-) and param not in allowed_flags: raise ValidationError(f不支持的参数: {param})5. 生产部署关键配置宝塔面板下的 Nginx Gunicorn Supervisor 组合方案5.1 Gunicorn 配置进程数、超时、用户隔离的黄金参数Django 开发服务器不可用于生产。Gunicorn 是事实标准 WSGI 服务器。创建gunicorn.conf.py# gunicorn.conf.py import multiprocessing bind 127.0.0.1:8001 # Gunicorn 监听内网端口 bind_address 127.0.0.1:8001 workers multiprocessing.cpu_count() * 2 1 # 例如 4 核 → 9 进程 worker_class sync worker_connections 1000 timeout 30 keepalive 5 max_requests 1000 max_requests_jitter 100 # 安全加固 user www-data # 降权运行非 root group www-data umask 0o007 pidfile /var/run/gunicorn.pid启动命令gunicorn --config gunicorn.conf.py vulnscanner.wsgi:application5.2 Nginx 反向代理配置静态文件托管与负载均衡前置宝塔面板中为站点添加反向代理目标 URL 填http://127.0.0.1:8001。同时配置静态文件# 在站点配置中添加 location /static/ { alias /www/wwwroot/vulnscanner/staticfiles/; expires 30d; } location /media/ { alias /www/wwwroot/vulnscanner/media/; expires 7d; }注意Django 的collectstatic必须提前执行将所有静态文件Admin CSS/JS、自定义前端收集到STATIC_ROOT目录python manage.py collectstatic --noinput5.3 Supervisor 进程守护确保 Gunicorn 和 django-q Worker 永不退出在宝塔的“软件管理”中安装 Supervisor然后添加两个进程Gunicorn 进程配置 (/etc/supervisor/conf.d/gunicorn.conf)[program:gunicorn] command/www/wwwroot/vulnscanner/venv/bin/gunicorn --config /www/wwwroot/vulnscanner/gunicorn.conf.py vulnscanner.wsgi:application directory/www/wwwroot/vulnscanner userwww-data autostarttrue autorestarttrue redirect_stderrtrue stdout_logfile/www/wwwroot/vulnscanner/logs/gunicorn.logdjango-q Worker 进程配置 (/etc/supervisor/conf.d/djangoq.conf)[program:djangoq] command/www/wwwroot/vulnscanner/venv/bin/python /www/wwwroot/vulnscanner/manage.py qcluster directory/www/wwwroot/vulnscanner userwww-data autostarttrue autorestarttrue redirect_stderrtrue stdout_logfile/www/wwwroot/vulnscanner/logs/djangoq.log重载 Supervisor 并启动supervisorctl reread supervisorctl update supervisorctl start all此时访问你的域名Django Admin 和扫描功能已全量上线。所有进程由 Supervisor 管理崩溃后自动重启日志统一归集符合企业级运维规范。6. 数据库优化与扫描结果深度分析用 PostgreSQL 的jsonb和窗口函数挖掘高价值线索6.1ScanFinding.evidence_snippet字段升级为JSONB支持高效模糊匹配与结构化查询原设计中evidence_snippet是TextField无法对 JSON 片段做索引查询。修改迁移# migrations/0005_alter_scanfinding_evidence_snippet.py from django.db import migrations, models import django.contrib.postgres.fields class Migration(migrations.Migration): dependencies [ (scanner, 0004_scanfinding_confidence_level), ] operations [ migrations.AlterField( model_namescanfinding, nameevidence_snippet, fielddjango.contrib.postgres.fields.JSONField(defaultdict), ), ]执行python manage.py migrate后可执行以下高价值查询-- 查询所有返回 admin 字符串且状态为 NEW 的发现快速定位后台路径 SELECT target.ip, finding.path, finding.evidence_snippet-response_status FROM scanner_scantarget target JOIN scanner_scanresult result ON target.id result.target_id JOIN scanner_scanfinding finding ON result.id finding.scan_result_id WHERE finding.evidence_snippet {response_body: admin} AND finding.status NEW; -- 使用 jsonb_path_ops 索引加速在生产环境执行一次 CREATE INDEX CONCURRENTLY idx_finding_evidence_gin ON scanner_scanfinding USING GIN (evidence_snippet);6.2 用窗口函数识别“反复出现的顽固漏洞”驱动修复优先级排序安全团队最头疼的是同一漏洞在不同时间、不同目标反复出现。用 PostgreSQL 窗口函数计算每个Vulnerability.cve_id的出现频次和最近出现时间-- 按 CVE 分组统计近 30 天出现次数、最早/最晚时间、涉及目标数 SELECT v.cve_id, COUNT(*) as occurrence_count, MIN(sr.created_at) as first_seen, MAX(sr.created_at) as last_seen, COUNT(DISTINCT st.ip) as affected_targets FROM scanner_vulnerability v JOIN scanner_scanfinding f ON v.id f.vulnerability_id JOIN scanner_scanresult sr ON f.scan_result_id sr.id JOIN scanner_scantarget st ON sr.target_id st.id WHERE sr.created_at NOW() - INTERVAL 30 days GROUP BY v.cve_id HAVING COUNT(*) 3 -- 出现超过 3 次 ORDER BY occurrence_count DESC, last_seen DESC;此查询结果可直接导出为 Excel成为每月安全运营会议的核心议题哪些 CVE 是“高频复发”应推动架构层统一修复而非单点打补丁。6.3 Django Admin 中嵌入自定义统计看板用django-admin-interface替换默认主题并添加仪表盘django-admin-interface支持自定义首页仪表盘。安装后在settings.py中INSTALLED_APPS [admin_interface, colorfield] X_FRAME_OPTIONS SAMEORIGIN # 允许 iframe 嵌入创建admin.py中的自定义视图# admin.py from django.contrib import admin from django.urls import path from django.template.response import TemplateResponse from .models import ScanFinding, Vulnerability admin.site.admin_view def dashboard_view(request): context admin.site.each_context(request) # 查询高频 CVE 数据 top_cves Vulnerability.objects.filter( scanfinding__scan_result__created_at__gtetimezone.now() - timedelta(days7) ).annotate( countCount(scanfinding) ).order_by(-count)[:5] context[top_cves] top_cves return TemplateResponse(request, admin/dashboard.html, context) # 在 urls.py 中注册 urlpatterns [ path(admin/dashboard/, dashboard_view, nameadmin-dashboard), ]templates/admin/dashboard.html中渲染表格安全运营人员登录 Admin 后首页即显示本周 Top 5 高频漏洞无需手动执行 SQL。这才是“数据库.zip”真正释放的价值让数据主动说话而非被动查询。本文还有配套的精品资源点击获取
返回列表