wittymastodon/lightweight-vulnerability-scanner

GitHub: wittymastodon/lightweight-vulnerability-scanner

一个用 Python 编写的教育性漏洞扫描器,通过并发端口扫描、服务指纹识别和本地 SQLite CVE 数据库匹配,帮助学习者理解安全扫描的完整架构。

Stars: 0 | Forks: 0

# 轻量级漏洞扫描器 ## 概述 本项目是一个教育性质的漏洞扫描器,使用 Python 编写,是我向高级攻击性安全职位专业发展的一部分。 在 2023 年尝试了 OSCP 之后,我确定了三个我想要加强的领域: 编程 Git 和软件开发工作流 网络枚举的技术方法论 我没有独立地学习这些主题,而是设计了一个单一的项目,让我能够同时提升这三方面的能力。 该扫描器执行并发 TCP 端口扫描、服务枚举、Banner 抓取、使用本地 SQLite 数据库进行 CVE 查找、OWASP 映射,并生成 Markdown 和 JSON 报告。 长期目标是使用这个 Python 实现作为参考架构,未来完全用 Rust 重写,从而让我能够比较不同语言之间的设计决策、性能和可维护性。 这个仓库既代表了我的学习过程,也代表了完成的软件。我欢迎反馈、建议和建设性的批评。 ## 目标 构建一个并发 TCP 端口扫描器,用于识别开放的服务、抓取 Banner,将已知的产品/版本与本地 CVE 数据库进行匹配,并 将发现的结果映射到 OWASP Top 10:2025 类别 —— 同时生成机器 可读 (JSON) 和人类可读 (Markdown) 的报告。 ## 为什么选择这个项目 将其作为第一个作品集项目,因为它是独立的,有明确的 成功标准(它能在已知存在漏洞的目标上找到真实的 CVE 吗?),并且 教授基础知识 —— 并发、错误处理、API 集成、本地 数据存储 —— 这些知识将延伸到路线图中的所有其他项目。 ## 架构 ``` scanner.py → port scanning, banner grabbing, CVE lookup, reporting build_cve_db.py → bulk-pulls CVE data from the NVD API into local SQLite owasp_mapping.py → maps CWE IDs (from CVE data) to OWASP Top 10:2025 categories cve_data.db → local SQLite mirror of NVD data (synced weekly, not live) ``` **关键设计决策:** CVE 数据在本地进行镜像,而不是在每次扫描时实时查询 NVD。这是在构建过程中遇到 NVD 的速率限制后,做出的一项深思熟虑的架构 更改 —— 请参阅问题与修复。这也符合生产级扫描器(Nessus、OpenVAS) 的实际工作方式:定期同步,针对快速的本地副本进行扫描。 ## 设置 1. `python3 -m venv .venv && source .venv/bin/activate` 2. `pip install -r requirements.txt` (仅需 `requests`) 3. 获取免费的 NVD API key: https://nvd.nist.gov/developers/request-an-api-key 4. `python3 init_db.py` — 使用 schema 创建 `cve_data.db` 5. `python3 build_cve_db.py` — 批量拉取受跟踪产品的 CVE 数据 (OpenSSH, Apache, vsftpd, ProFTPD, Samba, MySQL, Postfix, BIND) 6. `python3 owasp_mapping.py` - 允许在报告中引用 CWE 7. `python3 scanner.py --ports 1-1024 --workers 100` ## 发生了什么 经过几天的时间增量构建:首先是并发端口扫描器(在做任何 其他事情之前先针对 `localhost` 进行了测试),然后是针对明文 服务的 Banner 抓取,接着是针对 HTTPS 的封装 TLS 的 Banner 抓取器, 然后是主机名解析,接着是 CVE 流水线(本地 SQLite 镜像 + NVD 同步脚本), 然后是 OWASP CWE 类别映射,最后是 JSON/Markdown 报告输出。 针对 `scanme.nmap.org`(可以安全扫描而无需担心权限问题)和 本地的 Metasploitable2 虚拟机进行了验证,这产生了真实的 CVE 匹配 —— 例如, 针对 `OpenSSH_4.7p1` 正确识别了四个 CVE,针对 `Apache/2.2.8` 正确识别了两个。扫描还通过 Banner 文本发现了 Metasploitable 在端口 1524 上已知的未授权 root shell(`ingreslock` 后门),以及端口 6667/6697 上故意 存在漏洞的 UnrealIRCd 服务 —— 这两个都没有被扫描器的关键字列表直接 定位,但在原始 Banner 输出中可见,这很好地说明了即使 当某个产品未被识别时,捕获原始 Banner 也是有价值的。 ## 问题与修复 对于任何尝试进行类似构建的人来说,这是最有用的部分 —— 这些 大多数都是常见的、容易重复犯的错误,而不是什么离奇的 Bug。 - **自动补全悄悄破坏了一个 import。** `import sqlite3` 在某个时候变成了 `from dbm import sqlite3`(可能是编辑器自动补全的建议)—— 这是一个 技术上有效但完全不同的模块。它导致每次 CVE 查找都悄无声息地失败, 而不是崩溃,这比直接报错难发现得多。教训:当某些东西开始悄无声息地失败 且没有 traceback 时,应明确验证 import。 - **缩进改变了 `else` 所属的分支**,导致了 `TypeError: 'NoneType' object is not subscriptable` —— 一条 print 语句 引用了在该分支中为 `None` 的变量。Python 将缩进作为分组方式,这意味着 一个错位的空格会在没有任何警告的情况下悄然改变逻辑。 - **NVD API 返回了 404**,结果发现是由代码中遗留的 占位符 API key(`"YOUR_KEY_HERE"`)引起的,而不是实际的端点问题。 - **NVD API 返回了 429(受到速率限制)**,这发生在对一个宽泛 关键字(`Apache`,3,299 个结果)进行批量同步时。通过重试/退避逻辑 (遇到 429 时渐进式等待)解决了这个问题,而不仅仅是增加固定的延迟, 后者只会减少触及限制的*几率*而无法处理它。 - **一条 `SELECT` 语句和其对应的 return 语句在更新时 不同步** —— return 行在查询本身更新为实际选择它之前, 就被更新为期望一个 `raw_json` 列,导致了 `IndexError: tuple index out of range`。 - **运行了完全错误的文件** —— 正在 `scanner_v3.py` 中进行调试 修复,而终端命令仍然指向较旧的 `scanner_v2.py`。这提醒我们在活跃开发期间,当同一文件夹中存在多个版本 副本时,务必仔细检查实际执行的是哪个文件。 - **在造成浪费的工作之前抓住了范围不匹配的问题:** OWASP Top 10 类别是漏洞*类别*,而不是可搜索的产品关键字 —— 将它们直接添加到 NVD 关键字列表中会拉取数千个 不相关的 CVE。取而代之的解决方案是在 报告生成时应用 CWE 到 OWASP 的映射,并使用已存储的 CVE 数据中已有的 CWE ID。 ## 结果 针对 Metasploitable2(`X.X.X.102`,端口 1–20000)的示例输出: 发现了 25 个开放端口;为 OpenSSH 4.7p1 和 Apache 2.8 找到了真实的 CVE 匹配,并为每个匹配附加了 OWASP Top 10:2025 类别映射。完整输出 请见 `report.json` / `report.md`。 ## 经验教训 - **CVE 匹配使用针对自由文本描述的子字符串搜索**, 而不是正确的版本范围比较。这可能会产生漏报 —— 如果 特定版本的字符串没有逐字出现在 CVE 的描述文本中,那么存在漏洞的版本就不会 被标记。更健壮的 版本应该解析语义化版本边界,而不是进行字符串匹配。 - **正则表达式是解析非结构化文本**(Banner)的正确工具,但 对于结构化/嵌套数据(JSON)来说是错误的工具 —— 值得去理解*为什么*, 而不仅仅是出于习惯去选择哪一个。 - **对于针对受速率限制、有时不可靠的外部源重复运行的工具来说,本地镜像 胜过实时的 API 调用** —— 周期性同步, 其余时间快速离线查询。 - **“没有输出”和“没有错误”并不等同于“工作正常”** —— 此次构建中的几个 Bug(`dbm` 导入、缺少的 `raw_json` 列)都是悄无声息地失败而不是崩溃,这比直接的报错 更难被发现。 - 随着构建过程中架构变得更加清晰,项目范围自然地扩大了 (实时 NVD 调用 → 本地 SQLite 镜像;临时打印 → 结构化 报告输出)。这被视为流程中合理的一部分,而不是 初期规划糟糕的迹象。 ## 参考 - [NVD API 2.0 文档](https://nvd.nist.gov/developers/vulnerabilities) - [OWASP Top 10:2025](https://owasp.org/Top10/) - Metasploitable2(故意存在漏洞的测试目标)
标签:CVE查询, OSCP, Python, SQLite, 加密, 插件系统, 数据统计, 无后门, 漏洞扫描器, 端口扫描, 逆向工具