ARTICLE DETAIL

资讯详情

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

Django漏洞扫描系统源码实战:从环境搭建到二次开发

Django漏洞扫描系统源码实战:从环境搭建到二次开发 简介这是一套基于Django框架与Python实现的漏洞扫描系统完整源码面向计算机、信息安全、数据科学等专业的在校学生、教师及企业员工可用于课程设计、期末大作业、毕业设计或初期项目立项演示。资源包共441个文件以146个py源码、68个html模板、42个js脚本及scss、css、less等前端样式文件为主另含sql数据库脚本、json配置、bat启动脚本与项目说明文档压缩包约8.46MB目录结构清晰。系统覆盖主机漏洞扫描、WEB网页漏洞扫描、数据库管理、用户交互、漏洞报告、用户管理、日志记录与修复评估等模块支持端口扫描、服务识别、XSS与SQL注入检测、报告生成下载及数据增删改查。已有319人学习下载适合小白入门进阶也便于在现有基础上二次开发DIY其他安全检测功能。1. 从一份 Django 漏洞扫描系统源码说起它到底能扫什么、不能扫什么如果你正在做课程设计或毕业设计选题是「漏洞扫描系统」大概率会遇到一个尴尬网上能搜到的要么是纯理论综述要么是调用现成扫描器的壳子真正能跑起来、代码结构完整、还带数据库的 Django 项目并不多。这份基于 Django 框架 Python 实现的漏洞扫描系统源码配了 SQL 数据库和详细项目说明解决的正是「有界面、有任务调度、有结果入库、能演示完整流程」这件事。它适合三类人一是需要交课程设计、期末大作业的学生要的是能跑通、能讲清架构二是刚接触 Django 项目实战的新手想找一个有真实业务逻辑而不是博客、商城的项目练手三是需要二次开发的人想在这个骨架上加自己的扫描插件。需要先明确边界它是一套 Web 化的扫描任务管理与结果展示系统扫描能力取决于内置的检测逻辑不是 Nessus、AWVS 那种商业级引擎别指望它扫出 0day。把它当成「Django 全栈 安全扫描流程」的学习载体预期就对了。2. 环境搭建与项目跑通从 Python 安装到 Django 创建 app2.1 依赖版本与虚拟环境的选择理由拿到源码包第一件事不是急着pip install而是先看项目说明里的依赖清单。Django 项目最容易翻车的地方就是版本不匹配——Django 2.x 和 3.x、4.x 在路由写法、url()与re_path()、中间件配置上都有差异Python 3.8 和 3.11 对某些库的兼容性也不同。常见做法是先确认项目用的 Django 大版本再用对应的 Python 版本建虚拟环境避免污染全局环境。我一般会这样建环境Windows 和 Linux 都适用# 创建虚拟环境python 版本按项目说明选这里以 3.9 为例 python -m venv venv # Windows 激活 venv\Scripts\activate # Linux / macOS 激活 source venv/bin/activate # 升级 pip避免装包时各种玄学报错 python -m pip install --upgrade pip # 安装项目依赖requirements.txt 在源码根目录 pip install -r requirements.txt逻辑说明虚拟环境的核心价值是隔离。漏洞扫描系统往往会用到requests、beautifulsoup4、lxml这类库它们对底层编译环境敏感全局安装很容易和系统里其他项目打架。参数上python -m venv venv里的venv是环境目录名可以改但改了后面激活路径要跟着改。如果requirements.txt里没锁版本建议手动在文件里给 Django 加上版本号比如Django3.2.18这是长期支持版稳定性好新手踩坑少。2.2 数据库配置SQL 数据库连接与迁移这份源码带 SQL 数据库通常有两种情况一种是直接给了.sql备份文件需要你导入另一种是 Django 用 ORM 管理通过migrate生成表。先看项目说明里数据库是 MySQL 还是 SQLite。如果是 MySQL配置在settings.py的DATABASES里# settings.py 数据库配置片段 DATABASES { default: { ENGINE: django.db.backends.mysql, # 使用 MySQL 引擎 NAME: vulnscan, # 数据库名需提前创建 USER: root, # 数据库用户名 PASSWORD: your_password, # 改成你自己的密码 HOST: 127.0.0.1, # 本机数据库 PORT: 3306, # MySQL 默认端口 OPTIONS: { charset: utf8mb4, # 支持中文和特殊字符 }, } }逻辑说明ENGINE决定用哪种数据库后端MySQL 需要额外装mysqlclient或pymysql如果报No module named MySQLdb就在__init__.py里加pymysql.install_as_MySQLdb()。NAME对应的库要先在 MySQL 里CREATE DATABASE vulnscan DEFAULT CHARSET utf8mb4;建好Django 不会帮你建库只会建表。参数HOST和PORT按实际改本地就是127.0.0.1:3306。配置完执行迁移# 生成迁移文件模型有改动时才需要 python manage.py makemigrations # 应用迁移真正在数据库里建表 python manage.py migrate # 创建后台管理员账号用于登录 admin python manage.py createsuperuser如果源码附带了.sql文件就先用mysql -u root -p vulnscan backup.sql导入再执行migrate补齐 Django 自带的表。顺序反了会报主键冲突这是血泪经验。2.3 创建 app 与路由挂载Django 项目实战新手最容易迷糊的是「项目」和「app」的关系。项目是容器app 是功能模块。漏洞扫描系统一般会把扫描逻辑拆成独立 app比如scanner、vuln、task。如果你要自己加一个模块流程是# 在项目根目录创建 app python manage.py startapp myscanner然后在settings.py的INSTALLED_APPS里注册INSTALLED_APPS [ django.contrib.admin, django.contrib.auth, django.contrib.contenttypes, django.contrib.sessions, django.contrib.messages, django.contrib.staticfiles, scanner, # 已有的扫描模块 vuln, # 漏洞展示模块 myscanner, # 你新加的 ]逻辑说明不注册 appDjango 不会加载它的模型和模板migrate也不会为它建表。路由分两级项目级urls.py用include挂载 app 级路由# 项目 urls.py from django.contrib import admin from django.urls import path, include urlpatterns [ path(admin/, admin.site.urls), path(scanner/, include(scanner.urls)), # 扫描模块路由 ]参数说明include(scanner.urls)表示把scanner/urls.py里的路由挂到/scanner/前缀下。这样拆分的好处是模块解耦删掉一个 app 不影响其他部分。启动前记得python manage.py runserver默认 8000 端口浏览器访问http://127.0.0.1:8000/看首页是否正常。3. 扫描核心逻辑拆解任务下发、检测执行与结果入库3.1 扫描任务的模型设计一套能演示的漏洞扫描系统核心数据模型通常围绕「任务—目标—结果」三层。任务表记录一次扫描的元信息目标表存 URL 或 IP结果表存漏洞详情。用 Django ORM 表达大致是这样# scanner/models.py 核心模型 from django.db import models class ScanTask(models.Model): name models.CharField(max_length100) # 任务名称 target_url models.URLField() # 扫描目标 status models.CharField(max_length20, defaultpending) # 状态 created_at models.DateTimeField(auto_now_addTrue) def __str__(self): return self.name class VulnResult(models.Model): task models.ForeignKey(ScanTask, on_deletemodels.CASCADE) # 外键关联任务 vuln_type models.CharField(max_length50) # 漏洞类型 risk_level models.CharField(max_length10) # 风险等级 detail models.TextField() # 详情 found_at models.DateTimeField(auto_now_addTrue)逻辑说明ForeignKey加on_deletemodels.CASCADE表示删任务时级联删结果避免脏数据。status字段用字符串存pending/running/done/failed比布尔字段灵活。参数上URLField自带格式校验但如果你要扫 IP 段得换成CharField。这里有个常见误用把扫描结果直接塞进任务表的一个大文本字段后期查询和统计会非常痛苦拆表是正解。3.2 检测逻辑请求发送与特征匹配扫描器的本质是「发请求 看响应 匹配特征」。以检测 SQL 注入和 XSS 为例常见做法是构造带 payload 的请求观察响应里是否出现数据库报错或脚本原样回显# scanner/engine.py 简化检测逻辑 import requests from urllib.parse import urljoin # 常见 SQL 注入探测 payload SQL_PAYLOADS [, \, 1 OR 11] def check_sql_injection(url): findings [] for payload in SQL_PAYLOADS: test_url f{url}?id{payload} # 拼接测试参数 try: resp requests.get(test_url, timeout5) # 匹配数据库报错特征 if any(err in resp.text for err in [SQL syntax, mysql_fetch, ORA-]): findings.append({ type: SQL Injection, level: high, detail: fpayload: {payload}, }) except requests.RequestException: continue # 单次请求失败不影响整体 return findings逻辑说明timeout5是必须的扫描目标如果不响应没超时设置会一直挂着。requests.RequestException捕获连接错误、超时等保证一个 payload 失败不中断整个任务。参数上payload 列表可以按需扩展但别一上来就堆几百个先跑通流程再加。特征匹配用的是响应文本关键字这种方式误报率不低所以结果里要保留detail方便人工复核。3.3 结果入库与前端展示检测函数返回的findings列表要写进VulnResult表再通过视图渲染到页面# scanner/views.py 任务执行与入库 from django.shortcuts import render from .models import ScanTask, VulnResult from .engine import check_sql_injection def run_scan(request, task_id): task ScanTask.objects.get(idtask_id) task.status running task.save() findings check_sql_injection(task.target_url) for item in findings: VulnResult.objects.create( tasktask, vuln_typeitem[type], risk_levelitem[level], detailitem[detail], ) task.status done task.save() results VulnResult.objects.filter(tasktask) return render(request, result.html, {results: results})逻辑说明先改状态为running扫完改done这样前端能显示进度。objects.create()逐条入库如果结果量大可以改用bulk_create提升性能。filter(tasktask)按任务过滤保证页面只显示当前任务的结果。前端模板里用{% for r in results %}循环渲染表格即可。这套流程跑通整个系统的骨架就立住了。4. 避坑与排查跑不起来时先看这几处4.1 报错 No module named MySQLdb现象执行migrate时抛ImportError: No module named MySQLdb。原因Django 默认用MySQLdb驱动但 Python 3 下它安装麻烦。解决装pymysql然后在项目__init__.py里加两行import pymysql pymysql.install_as_MySQLdb()这样 Django 会把pymysql当成MySQLdb用不用改settings.py。4.2 静态文件 404页面样式全丢现象首页能打开但没样式控制台一堆 404。原因DEBUGTrue时 Django 才自动服务静态文件或者STATIC_URL配置不对。解决确认settings.py里DEBUG TrueSTATIC_URL /static/并在urls.py末尾加from django.conf import settings from django.conf.urls.static import static urlpatterns static(settings.STATIC_URL, document_rootsettings.STATIC_ROOT)生产环境则要用 Nginx 托管静态文件别用这种方式。4.3 扫描任务卡在 running 不动现象任务状态一直是running页面不刷新。原因扫描是同步执行的请求超时或目标不可达时线程被阻塞。解决给requests加timeout并在视图里用try/except包住扫描逻辑异常时把状态改成failed并记录原因。进阶做法是把扫描丢进 Celery 异步队列但这会增加部署复杂度课程设计阶段同步够用。4.4 中文乱码现象漏洞详情里的中文显示成问号。原因数据库字符集不是utf8mb4。解决建库时指定DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_unicode_cisettings.py的OPTIONS里加charset: utf8mb4。已经建好的库可以用ALTER DATABASE vulnscan CHARACTER SET utf8mb4;补救。4.5 端口被占用现象runserver报That port is already in use。原因8000 端口被别的进程占了。解决换端口python manage.py runserver 8080或者找到占用进程杀掉。Windows 用netstat -ano | findstr 8000Linux 用lsof -i:8000。5. 二次开发与验证把扫描器改成你自己的5.1 加一个检测插件系统跑通后最有价值的动作是加自己的检测逻辑。比如加一个检测敏感目录泄露的插件# scanner/engine.py 追加 SENSITIVE_PATHS [/admin/, /.git/, /backup.zip, /phpinfo.php] def check_sensitive_paths(base_url): findings [] for path in SENSITIVE_PATHS: url urljoin(base_url, path) try: resp requests.get(url, timeout5) # 200 且内容不是通用 404 页面视为疑似泄露 if resp.status_code 200 and len(resp.text) 0: findings.append({ type: Sensitive Path, level: medium, detail: f{url} 返回 200, }) except requests.RequestException: continue return findings逻辑说明urljoin保证拼接不出错status_code 200是初筛实际还要看响应内容长度和特征否则误报会很多。参数SENSITIVE_PATHS按目标技术栈调整扫 PHP 站就加.php相关路径。加完在视图里调用结果同样入库。5.2 验证扫描结果是否可信自己写的扫描器验证方法很关键。我一般会搭一个本地靶场比如用 DVWA 或 pikachu这些是专门用来练手的漏洞环境。把扫描目标指向靶场看能不能扫出已知漏洞。如果扫不出先手动用浏览器或curl复现 payload确认靶场确实存在该漏洞再回头查扫描逻辑。这个「先手动、再自动」的习惯能省掉大量瞎猜时间。5.3 用 Django admin 做结果管理Django 自带 admin 是现成的后台把模型注册进去就能管理数据# scanner/admin.py from django.contrib import admin from .models import ScanTask, VulnResult admin.register(ScanTask) class ScanTaskAdmin(admin.ModelAdmin): list_display (name, target_url, status, created_at) list_filter (status,) admin.register(VulnResult) class VulnResultAdmin(admin.ModelAdmin): list_display (task, vuln_type, risk_level, found_at) search_fields (vuln_type,)逻辑说明list_display控制列表页显示哪些字段list_filter加侧边筛选search_fields加搜索框。这样不用写前端就能快速查数据调试阶段特别顺手。参数按需增减字段名必须和模型一致。5.4 一个具体技巧用 Django shell 快速调试改完扫描逻辑不用每次都开浏览器点按钮。用python manage.py shell进交互环境直接调函数看返回# 进入 shell 后 from scanner.engine import check_sql_injection result check_sql_injection(http://localhost/dvwa/vulnerabilities/sqli/) print(result)这样能快速验证逻辑对不对比走完整 Web 流程快得多。我每次改完检测函数都先在 shell 里跑一遍确认返回结构没问题再接到视图上。从那以后我每次动扫描核心代码都强制走一遍「shell 验证 → 靶场实测 → 页面联调」再没出现过改完页面报 500 还找不到原因的情况。希望帮到你。本文还有配套的精品资源点击获取
返回列表