Krishna-The-Developer/IIT-Jammu-Final-Project

GitHub: Krishna-The-Developer/IIT-Jammu-Final-Project

一款基于 Python 的多线程网络漏洞扫描器,具备端口扫描、服务识别、规则检测和 HTML 报告生成功能,专为教育和学术场景设计。

Stars: 0 | Forks: 0

# VulnScan – 基础网络漏洞扫描器 VulnScan 是我用 Python 编写的一款网络漏洞扫描器。只需给它一个 IP 地址,它就会扫描开放端口,尝试识别每个端口背后运行的服务(banner grabbing),根据一些基础的安全规则进行检查,计算出风险评分,最后生成一份可以直接在浏览器中打开的 HTML 报告。 它还提供了一个使用 Tkinter 制作的简易桌面 GUI,因此你无需接触命令行即可使用它。 ## 目录 1. [项目描述](#project-description) 2. [功能特性](#features) 3. [项目架构](#project-architecture) 4. [项目文件夹结构](#project-folder-structure) 5. [使用的技术](#technologies-used) 6. [环境要求](#requirements) 7. [安装指南](#installation-guide) 8. [如何运行](#how-to-run) 9. [GUI 操作指南](#gui-walkthrough) 10. [扫描模式](#scan-modes) 11. [扫描流程的工作原理](#how-the-scanning-process-works) 12. [风险评分](#risk-scoring) 13. [HTML 报告](#html-report) 14. [示例工作流](#sample-workflow) 15. [预期输出](#expected-output) 16. [截图](#screenshots) 17. [项目演示](#project-demo) 18. [常见问题排查](#troubleshooting) 19. [未来改进](#future-improvements) 20. [教育目的](#educational-purpose) 21. [许可证](#license) ## 项目描述 ### 什么是 VulnScan? VulnScan 是一款入门级漏洞扫描器。你只需输入一个 IP 地址,它就会检查该设备上有哪些开放端口,尝试识别每个开放端口背后运行的服务,并标记出一些广为人知的安全问题——比如启用了 Telnet,或者暴露在外的 FTP 服务器。所有结果最终都会被打包进一份易于阅读的 HTML 报告中。 ### 为什么开发这个工具 作为一个大学小型项目,我开发这个工具主要是为了真正去理解(而不仅仅是纸上谈兵)以下几件事: - 端口和网络服务在实际中是如何运作的 - 如何使用 sockets 在 Python 中编写一个基础的端口扫描器 - 线程是如何加速网络扫描这类任务的 - 如何仅凭简单的 if-else 规则来标记安全问题,而无需依赖任何 ML 模型或付费的漏洞数据库 - 如何将原始的扫描输出转化为非技术人员也能看懂的内容 ### 它解决了什么问题 像 Nmap 或 Nessus 这样的工具确实很棒,但它们非常庞大,而且老实说,如果你是个新手,去阅读它们的源码会有点困难。VulnScan 则恰恰相反——它很小巧,每一部分代码都是我自己编写并且能逐行解释的。这才是它的真正意义所在:作为一个完全透明的示例,展示扫描器在底层到底做了什么,这也使得它非常适合在答辩中进行演示。 ## 功能特性 - **多线程端口扫描** —— VulnScan 使用 Python 的 `ThreadPoolExecutor` 一次性检查多个端口,而不是逐个检查。如果没有这个功能,扫描所有 65,535 个端口会花非常长的时间。 - **常用端口扫描(快速模式)** —— 扫描 16 个广为人知的端口(FTP、SSH、HTTP、HTTPS、MySQL、RDP 等)。这是你平时最常使用的模式,因为它涵盖了大多数真实设备中真正重要的端口。 - **全端口扫描(1–65535)** —— 检查每一个端口。速度显然较慢,但如果你想更彻底,或者怀疑有程序运行在奇怪的非标准端口上,它会非常有用。 - **Banner grabbing** —— 对于每个开放端口,VulnScan 都会尝试读取服务返回的任何“banner”或欢迎信息。不同的服务会有不同的处理方式——对于 HTTP 服务器,它会先发送一个小请求以获取响应;而对于 SSH 或 FTP 这类服务,它只需监听即可,因为它们会自动向你发送问候。 - **实时进度条** —— 在扫描过程中,进度条和一段小文本标签(“正在扫描 45/65535 个端口...”)会让你随时了解进展,让你知道程序确实在运行而不只是卡死了。 - **预计剩余时间 (ETA)** —— 在扫描运行期间,VulnScan 会记录每个端口平均消耗的时间,并以此显示一个粗略的“剩余时间”估计。它会随着扫描的进度不断更新,因此越往后估计就越准确。 - **基于规则的漏洞检查** —— 每个开放端口都会与一小部分手写的规则进行比对。例如:如果 Telnet 是开放的,就会被标记为高风险,因为 Telnet 发送的所有数据都是未加密的。这不需要任何互联网连接或外部数据库。 - **风险评分** —— 每个发现都会对应一个严重程度(低、中、高),它们会汇总成针对该目标的整体得分和风险等级。 - **HTML 报告生成** —— 只需点击一下,VulnScan 就会将所有内容(包括目标信息、开放端口、banners、漏洞、风险等级)输出为一个排版精美的 HTML 文件。可在任何浏览器中打开,无需服务器。 - **深色主题 GUI** —— 使用 Tkinter 构建,因此无需安装任何额外软件,即可在 Windows、macOS 和 Linux 上保持一致的运行效果。 - **零外部依赖** —— 以上所有功能完全依靠 Python 的标准库运行。 ## 项目架构 本项目中的每个文件都各司其职,并将输出结果传递给下一个阶段: ``` User │ ▼ Tkinter GUI (main.py) │ ▼ Scanner (scanner.py) │ ▼ Banner Grabbing │ ▼ Vulnerability Checker (vulnerability_checker.py) │ ▼ Risk Scoring │ ▼ HTML Report Generator (report_generator.py) │ ▼ Reports Folder ``` 以下是各个层的具体作用: | 层级 | 功能 | |---|---| | Tkinter GUI (`main.py`) | 获取用户输入(IP、扫描模式),在后台启动扫描以防止窗口卡死,将结果显示在表格中,并更新进度条和状态消息。 | | 扫描器 (`scanner.py`) | 建立 TCP 连接以检查哪些端口是开放的,为了提高速度,会同时在多个线程中执行此操作。 | | Banner Grabbing | 对于发现的每个开放端口,读取服务返回的信息(或者对于像 HTTP 这样默认保持沉默的协议,先发送一个小探测包),以查明实际运行的服务。 | | 漏洞检查器 (`vulnerability_checker.py`) | 获取开放端口和 banners,通过一小部分规则进行比对,从而生成一份发现列表。 | | 风险评分 | 将所有发现的严重程度分数相加,并转化为一个整体得分和风险等级。 | | HTML 报告生成器 (`report_generator.py`) | 将所有内容——包括端口、banners、发现列表、风险得分——打包成一个排版精美的 HTML 文件。 | | 报告文件夹 (`reports/`) | 保存所有报告的地方,每份报告都带有时间戳,因此不会覆盖之前的报告。 | ## 项目文件夹结构 ``` VulnScan/ │ ├── main.py # Tkinter GUI - the entry point of the app ├── scanner.py # Port scanning + banner grabbing ├── vulnerability_checker.py # Rule-based vulnerability detection ├── report_generator.py # Builds the HTML report ├── utils.py # Small shared helper functions │ ├── reports/ # Generated HTML reports are saved here │ └── README.md # Explains what this folder is for │ ├── requirements.txt # Lists dependencies (there are none external) └── README.md # You are here ``` 各文件的简要说明: **main.py** 这是你要运行的文件。它构建了整个窗口——IP 输入框、扫描模式按钮、结果表格、进度条等所有元素。不过,它本身并不执行实际的扫描工作;当你点击“开始扫描”时,它会在后台线程中调用 `scanner.py` 中的函数,并仅负责显示返回的结果。 **scanner.py** 这里是进行实际网络工作的核心。它包含了常用端口列表、检查端口是否开放的函数 (`scan_port`)、读取 banner 的函数 (`grab_banner`),以及使用 `ThreadPoolExecutor` 在多个端口上同时运行这两个操作的多线程引擎 (`scan_ports`)。 **vulnerability_checker.py** 这里完全没有网络代码——它只负责处理 `scanner.py` 已经发现的结果。它会遍历开放端口,检查诸如“21 端口是否开放?”之类的简单条件,构建发现列表,然后计算出风险得分和一份简短的总结。 **report_generator.py** 接收目标、扫描结果、发现列表和风险信息,构建一段庞大的 HTML 字符串(直接在其中写入 CSS),并将其保存到 reports 文件夹中。 **utils.py** 仅包含一些在整个项目中使用的辅助小函数——用于验证用户输入的是否为真实的 IP 地址,以及格式化用于显示和文件名的日期/时间。 **reports/ 文件夹** 在你生成第一份报告之前,该文件夹是空的。每份报告都会获得一个唯一且带有时间戳的名称,例如 `report_2026-07-21_10-30-15.html`,因此旧报告永远不会被覆盖。 ## 使用的技术 | 技术 | 用途 | |---|---| | Python 3 | 整个项目完全使用 Python 编写——易于阅读,且标准库已经提供了网络和 GUI 开发所需的一切。 | | Tkinter | Python 内置的 GUI 工具包,用于构建整个桌面窗口,无需引入任何外部框架。 | | socket | 这里所有网络操作的核心——建立 TCP 连接以检查端口并读取 banner。 | | concurrent.futures.ThreadPoolExecutor | 管理一个工作线程池,使得数百个端口几乎可以同时被检查,而不是逐个进行——这正是让完整的 65,535 端口扫描能够在合理时间内完成的关键。 | | threading | 在独立于 GUI 的线程上运行整个扫描过程,确保窗口在扫描期间保持可点击状态,而不是在中途卡死。 | | time | 在发送请求和读取 banner 响应之间加入短暂的延迟,因为某些服务需要一点时间才能回复。 | | ipaddress | 在尝试扫描之前,验证用户输入的是否为有效的 IP 地址。 | | datetime | 为报告的“生成时间”字段和文件名添加时间戳。 | | os | 如果 `reports/` 文件夹缺失则创建它,并构建安全的文件路径。 | | html | 将任何来自网络的内容(如 banner)在放入 HTML 报告之前进行转义,以防止破坏页面布局。 | | HTML & CSS (纯手写) | 报告是一个自包含的 HTML 文件,使用纯内嵌 CSS 进行排版——没有使用 Bootstrap 或任何类似的框架。 | ## 环境要求 | 要求 | 详细信息 | |---|---| | Python 版本 | Python 3.8 或更高版本 | | 外部库 | 无——零第三方包 | | 使用的内置库 | tkinter, socket, threading, concurrent.futures, time, ipaddress, datetime, os, html | 由于没有任何外部依赖,`requirements.txt` 基本上只是一段用于解释此情况的注释,而不是一个真正的包列表。 ## 安装指南 **步骤 1 — 克隆仓库** ``` git clone https://github.com/your-username/VulnScan.git ``` 将项目副本下载到你的本地计算机中。 **步骤 2 — 进入项目文件夹** ``` cd VulnScan ``` 将终端切换到该文件夹中,以便后续命令能在正确的位置运行。 **步骤 3 — (可选) 创建虚拟环境** ``` python -m venv venv ``` 仅为这个项目设置一个隔离的 Python 环境。由于这里没有外部依赖,这一步并不是严格必需的,但这仍然是一个好习惯。 **步骤 4 — 激活环境** Windows: ``` venv\Scripts\activate ``` macOS/Linux: ``` source venv/bin/activate ``` 激活后,你通常会看到终端提示符的开头出现 `(venv)` 字样。 **步骤 5 — 检查你的 Python 版本** ``` python --version ``` 在继续下一步之前,确认你的 Python 版本是 3.8 或更高。 这就是整个安装过程——不需要执行 `pip install`,因为不需要任何外部组件。 ## 如何运行 项目设置完成后,运行: ``` python main.py ``` 接下来会发生以下过程: 1. `main.py` 加载并导入 scanner.py、vulnerability_checker.py、report_generator.py 和 utils.py。 2. 弹出一个标题为“VulnScan – Network Scanner”的窗口,大小为 1100×740,采用深色主题。 3. 你会看到一个空白的 IP 输入框、扫描模式选项、一个“开始扫描”按钮、一个“生成报告”按钮(目前处于灰色不可用状态)、一个空白的扫描结果表格,以及一个显示着“Ready...”的状态栏。 4. 此时不会自动进行任何扫描——它只会静静等待你输入 IP 并点击“开始扫描”。 ## GUI 操作指南 | 组件 | 用途 | |---|---| | 目标 IP 输入框 | 用于输入你想要扫描的 IP,例如 192.168.1.10。 | | 扫描模式 | 在“常用端口 (快速)”和“全端口扫描 (1–65535)”之间进行选择。下方的标签会更新,显示当前激活的是哪一个模式。 | | 开始扫描按钮 | 验证你输入的 IP,然后在后台启动扫描。在扫描运行期间,该按钮会被禁用,防止你意外同时启动两个扫描。 | | 进度条 | 随着端口的扫描逐渐填满,并配有类似“正在扫描 45/65535 个端口 (0.1%)”的文本标签。 | | ETA 标签 | 在扫描运行期间显示粗略的“剩余时间”估计,该时间是根据目前已扫描端口的平均耗时计算得出的。扫描完成后它会自动清空。 | | 状态栏 | 底部的长条区域,用于显示当前正在发生的操作——Ready...,Scanning...,或 Scan Completed。 | | 扫描结果表格 | 可滚动的表格,列出发现的每一个开放端口,包含 IP、端口、服务、状态、风险和 Banner 等列 | | 生成报告按钮 | 在扫描真正完成之前保持禁用状态。点击它会生成 HTML 报告,并向你显示保存位置。 | ## 扫描模式 | 模式 | 扫描范围 | 适用场景 | |---|---|---| | 常用端口 (快速) | 16 个广为人知的端口 —— FTP, SSH, Telnet, SMTP, DNS, HTTP, POP3, NetBIOS, IMAP, HTTPS, SMB, MySQL, RDP, PostgreSQL, VNC, HTTP-Alt | 适合日常快速检查。涵盖了大多数设备的重要端口,且完成速度极快。 | | 全端口扫描 (1–65535) | 每一个可能的 TCP 端口 | 当你想要进行彻底排查,或者怀疑有程序运行在不常见的端口上时使用。因为需要覆盖的范围大得多,所以耗时要长得多。 | 老实说,直接从“常用端口”开始就行了。除非你有特定理由需要检查每一个端口,否则没必要去折腾“全端口扫描”——它不仅耗时,而且会给你带来大量需要筛选的数据。 ## 扫描流程的工作原理 **步骤 1** 你输入目标 IP。 **步骤 2** 点击“开始扫描”会首先运行 `utils.validate_ip()`,以确保你输入的内容在执行任何其他操作之前确实是有效的 IP。 **步骤 3** 根据你选择的扫描模式,会将常用端口列表或完整的 1–65535 端口范围传递给 `scanner.scan_ports()`。 **步骤 4** `scan_ports()` 使用 ThreadPoolExecutor 通过 `scan_port()` 一次性检查大量端口,该函数仅建立一个快速的 TCP 连接来查看每个端口是否有响应。每当一个端口检查完毕,就会触发一个进度回调,该回调会更新进度条,并根据目前已扫描端口的平均耗时计算出 ETA。 **步骤 5** 对于每个被探测为开放的端口,`grab_banner()` 会立即尝试使用该端口通常对应的协议所特有的逻辑来读取(或请求)banner。 **步骤 6** 扫描完成后,完整的开放端口和 banner 列表将被发送至 `vulnerability_checker.check_vulnerabilities()`,该函数会标记出已知的高风险项,如 FTP 或 Telnet。 **步骤 7** `vulnerability_checker.calculate_risk()` 会汇总所有发现的严重程度分数,并计算出整体得分和风险等级。 **步骤 8** GUI 会在结果表格中显示每一个开放端口,并在其旁边显示相应的风险等级(如果没有匹配的规则,则显示为“Safe”)。 **步骤 9** 点击“生成报告”会调用 `report_generator.generate_html_report()`,该函数会将所有内容写入 reports 文件夹内一个带有时间戳的 HTML 文件中。 ## 风险评分 每一个发现都会对应一个严重程度,而每个严重程度都对应一定的分数: | 严重程度 | 分数 | |---|---| | 高 | 30 | | 中 | 20 | | 低 | 10 | 所有分数会被累加成一个总分,然后映射到对应的整体风险等级: | 得分范围 | 风险等级 | |---|---| | 0 – 20 | 低 | | 21 – 50 | 中 | | 50 以上 | 高 | 举例来说,假设一次扫描发现了一个高风险项(Telnet,30 分)和一个中风险项(FTP,20 分)——总分为 50 分,恰好落在中等风险范围内。 这是一个相当简单的积分系统,并非 CVSS 之类的行业标准,背后也没有任何机器学习算法。这是刻意为之——它易于阅读也易于解释,对于这样的项目来说,这一点才更为重要。 ## HTML 报告 生成的每份报告都包含: - 包含 VulnScan 标题和简短副标题的页眉 - 目标信息——扫描的 IP 地址以及报告生成的确切时间 - 整体的风险得分和等级,并根据严重程度显示相应的颜色(低风险为绿色,中风险为橙色,高风险为红色) - 开放端口表格——每一个被发现开放的端口、其服务、状态以及捕获到的 banner(如果有) - 漏洞发现表格——端口、服务、严重程度、问题的通俗描述以及修复建议 - 提醒你该工具仅供教育用途的页脚 这是一个完全自包含的 HTML 文件,因此可以在任何浏览器中正常打开,且不需要互联网连接。 ## 示例工作流 这是一个从头到尾的完整操作演示: 1. 运行 `python main.py`,窗口打开。 2. 在 IP 输入框中输入 `127.0.0.1`(你自己的机器)。 3. 保持模式为“常用端口 (快速)”。 4. 点击“开始扫描”——按钮变灰,进度条开始移动,片刻后下方会出现一个 ETA 标签,估算剩余时间。状态栏显示“Scanning...”。 5. 几秒钟后,表格中开始出现数据行——例如,端口 445 状态为 Open,服务为 SMB。 6. 状态栏更新为“Scan Completed”,并且“生成报告”按钮变为可点击状态。 7. 点击“生成报告”——弹窗会显示文件保存的路径。 8. 在浏览器中打开该文件即可查看完整的分析报告。 ## 预期输出 在结果表格中,你可能会看到类似下面的内容: | IP | 端口 | 服务 | 状态 | 风险 | Banner | |---|---|---|---|---|---| | 192.168.1.10 | 21 | FTP | Open | 中 | 220 (vsFTPd 3.0.3) | | 192.168.1.10 | 23 | Telnet | Open | 高 | No Banner | | 192.168.1.10 | 80 | HTTP | Open | 安全 | HTTP/1.1 200 OK ... | 而在漏洞发现列表中: | 端口 | 服务 | 严重程度 | 问题 | |---|---|---|---| | 21 | FTP | 中 | 检测到 FTP 服务 | | 23 | Telnet | 高 | 检测到 Telnet | 整体风险等级:中(得分:50) 报告会以类似 `reports/report_2026-07-21_10-30-15.html` 的名称保存,其中包含了上述所有信息,并以深色主题的页面呈现。 ## 项目演示 1. 启动应用:`python main.py` 2. 输入你想要扫描的 IP 3. 选择扫描模式——常用端口追求快速,全端口扫描追求彻底 4. 点击“开始扫描”(运行期间它会处于不可用状态) 5. 在程序运行时观察进度条、ETA 标签和状态栏 6. 仔细查看结果表格,特别是任何被标记为“中”或“高”的内容 7. 点击“生成报告” 8. 在浏览器中打开 reports 文件夹中的 HTML 文件 ## 常见问题排查 | 问题 | 可能原因 | 解决方法 | |---|---|---| | GUI 无法打开 | 缺少 Tkinter,或者安装的是最小化的 Python | 运行 `python -m tkinter` 进行检查——它应该会弹出一个小小的测试窗口。如果没有,请从 python.org 重新安装 Python。 | | "Invalid IP Address" 错误 | IP 输入框中有拼写错误 | 仔细检查输入——像 192.168.1.999 这样的地址是无效的,因为 999 不是一个有效的八位组。 | | 未发现开放端口 | 目标没有开放任何端口,防火墙阻止了连接,或者目标处于离线状态 | 先尝试扫描 127.0.0.1(你自己的机器),以确认扫描器本身能否正常工作。 | | ModuleNotFoundError | 从错误的文件夹运行了 main.py | 确保在运行之前,你的终端路径位于 VulnScan 文件夹内部。 | | 报告未能创建 | 对 reports/ 没有写入权限,或者你在扫描完成之前点击了“生成报告” | 先让扫描完整运行一遍,并检查文件夹权限。 | | 扫描时遇到权限错误 | 某些系统限制了特定的 socket 操作 | VulnScan 仅执行正常的 TCP connect 扫描,这通常不需要特殊权限——但有时杀毒软件可能会造成干扰。如果卡住了,请尝试暂时禁用杀毒软件。 | | 扫描耗时过长 | 你选择了全端口扫描,这会检查所有 65,535 个端口 | 这是正常的——它本身就是一项彻底的扫描。如果你只想快速检查一下,请使用常用端口模式。 | | 防火墙阻止了连接 | 你的防火墙(或目标的防火墙)悄悄丢弃了连接请求 | 这可能会让原本开放的端口看起来是关闭的。请先尝试扫描你自己局域网内的设备。 | ## 未来改进 - 除 HTML 外支持导出 PDF - 允许用户输入自定义的端口列表,而不仅是局限于两种固定的模式 - 支持扫描一个 IP 地址范围,而不是一次只能扫描一个 - 保存扫描历史记录,以便日后比较结果 - 增加更多的漏洞规则,覆盖更多的服务和过时版本 - 提供浅色主题选项 ## 教育目的 我开发 VulnScan 仅仅是为了学习和进行授权的网络测试,这也是我大学项目的一部分。 请不要将此工具用于任何你不拥有或未经明确许可的设备或网络。未经许可扫描网络在某些地区可能是违法的。我对任何人的滥用行为不承担责任。 ## 许可证 本项目采用 MIT 许可证——你可以使用、修改、分享它(包括用于你自己的学习),只需保留原作者署名即可。
标签:Python, Tkinter, 插件系统, 数据统计, 无后门, 端口扫描, 调试辅助, 逆向工具