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, 加密, 插件系统, 数据统计, 无后门, 漏洞扫描器, 端口扫描, 逆向工具