n40y/VoightNim
GitHub: n40y/VoightNim
一个使用 Nim 编写的轻量级无依赖 TCP 端口扫描器和服务指纹识别工具,通过异步事件循环和内置签名库实现快速端口探测与多协议服务识别。
Stars: 0 | Forks: 0
# VoightNim



一个轻量级、无依赖的 TCP 端口扫描器和服务指纹识别工具,使用 Nim 从头编写,作为一个学习项目构建(没有封装 `nmap`、`rustscan` 或任何其他外部扫描工具)。
```
██╗ ██╗ ██████╗ ██╗ ██████╗ ██╗ ██╗ ████████╗ ███╗ ██╗ ██╗ ███╗ ███╗
██║ ██║ ██╔═══██╗ ██║ ██╔════╝ ██║ ██║ ╚══██╔══╝ ████╗ ██║ ██║ ████╗ ████║
██║ ██║ ██║ ██║ ██║ ██║ ███╗ ███████║ ██║ ██╔██╗ ██║ ██║ ██╔████╔██║
╚██╗ ██╔╝ ██║ ██║ ██║ ██║ ██║ ██╔══██║ ██║ ██║╚██╗██║ ██║ ██║╚██╔╝██║
╚████╔╝ ╚██████╔╝ ██║ ╚██████╔╝ ██║ ██║ ██║ ██║ ╚████║ ██║ ██║ ╚═╝ ██║
╚═══╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝
```
## 功能
- **基于事件循环的异步扫描** (`std/asyncdispatch` + `std/asyncnet`) — 没有为每个端口分配 OS 线程的开销
- **跨平台** — 无需平台特定的 socket 代码即可在 Windows、Linux 和 macOS 上运行
- **自动并发校准** — 读取系统的文件描述符限制(POSIX 上的 `ulimit -n`)并据此限制并发连接数,而不是依赖盲目的、固定的线程数
- **多协议服务指纹识别** — 抓取开放端口的 banner,并使用纯 Nim 正则表达式引擎(无 PCRE/C 依赖)将它们与内嵌的签名数据库(HTTP 服务器标头、SSH、FTP、SMTP、Redis)进行匹配
- **堆叠式、多结果检测(不同于单一判定扫描器)** — 单个 banner 可以一次显示*多个*独立的发现(例如 Web 服务器 + runtime + 框架 + OS),而不是将每个端口折叠为一个猜测
- **基于 banner 提示的 OS 指纹识别** — 从其他服务泄漏的线索(例如 `Server: Apache/2.4.41 (Ubuntu)`,暗示 Windows 的 IIS)推断底层 OS(Ubuntu、Debian、CentOS、RHEL、Fedora、Windows),独立于服务检测进行呈现
- **JSON 输出模式**,可用于编写脚本和通过管道传递给其他工具
- **自定义端口列表或范围** (`22,80,443` 或 `8000-8010`),默认内置常用端口列表
## 环境要求
- [Nim](https://nim-lang.org/) 2.x
- [Nimble](https://github.com/nim-lang/nimble) (随 Nim 一起提供)
- Nimble 包:`docopt`、`regex`
## 安装说明
```
git clone https://github.com/n40y/VoightNim.git
cd VoightNim
nimble install docopt
nimble install regex
```
## 构建说明
```
# Debug build
nim c src/VoightNim.nim
# Release build(推荐用于实际扫描 — 显著更快)
nim c -d:release src/VoightNim.nim
```
这将生成 `src/VoightNim`(或在 Windows 上生成 `src/VoightNim.exe`)。
## 用法
```
voightnim port [-s ] [-v] [--json]
voightnim [-s ] [-v] [--json]
Options:
-s Max concurrent connections (auto-capped by system limits) [default: 10]
-v, --verbose Also display closed ports
--json Output results as JSON (disables colored/banner output)
-h, --help Show this help
```
### 示例
扫描特定端口:
```
./VoightNim 10.10.10.5 port 22,80,443,8080
```
以更高的并发扫描端口范围:
```
./VoightNim 10.10.10.5 port 1-1000 -s 200
```
不带 `port` 参数将扫描内置的常用端口列表:
```
./VoightNim 10.10.10.5
```
详细模式(也会显示关闭的端口):
```
./VoightNim 10.10.10.5 port 20-30 -v
```
机器可读的输出:
```
./VoightNim 10.10.10.5 port 22,80,443 --json | jq .
```
## 项目结构
| 路径 | 职责 |
|------|-----------------|
| `VoightNim.nim` | 主入口点(扫描编排 + 指纹识别 + 显示) |
| `cli.nim` | CLI 参数管理 (docopt) |
| `prober.nim` | 端口扫描和 banner 获取(async,无 threads) |
| `topports.nim` | 常用端口列表 |
```
src/
├── VoightNim.nim
├── cli.nim
├── prober.nim
├── topports.nim
│
├── fingerprint/ # Moteur de fingerprinting
│ ├── engine.nim # API haut niveau : detect, detectAll, detectOs, detectAllOs
│ ├── matcher.nim # Applique les règles de signatures sur un banner
│ ├── types.nim # Types partagés (ServiceId, OsId, Fingerprint, OsFingerprint...)
│ ├── services.nim # Base de connaissances des services (getService)
│ ├── osCatalog.nim # Base de connaissances des OS (getOs)
│ ├── registry.nim # Registre des sondes (getAllProbes)
│ └── utils.nim # Fonctions utilitaires (conversion bytes/string, split headers...)
│
├── probes/ # Une sonde par protocole (connexion + payload uniquement)
│ ├── http.nim # appelle signatures/http/init.nim + signatures/os/init.nim
│ ├── ssh.nim # appelle signatures/ssh/init.nim + signatures/os/init.nim
│ ├── ftp.nim # appelle signatures/ftp/init.nim
│ ├── smtp.nim # appelle signatures/smtp/init.nim
│ └── redis.nim # appelle signatures/redis/init.nim
│
└── signatures/ # Règles de détection, organisées par protocole/axe
├── http/
│ ├── init.nim # Agrège toutes les catégories ci-dessous
│ ├── webservers.nim # Nginx, Apache, Caddy, IIS, Traefik, Envoy...
│ ├── runtimes.nim # PHP, ASP.NET
│ ├── frameworks.nim # Express, Laravel, Django, Flask
│ └── monitoring.nim # Grafana, Prometheus, Elasticsearch/Kibana
├── ssh/
│ ├── init.nim
│ └── servers.nim # OpenSSH, libssh, Dropbear, Cisco SSH, SunSSH
├── ftp/
│ ├── init.nim
│ └── servers.nim # vsftpd, ProFTPD, FileZilla, Pure-FTPd, Microsoft FTP
├── smtp/
│ ├── init.nim
│ └── servers.nim # Postfix, Exim, Microsoft Exchange, Sendmail
├── redis/
│ ├── init.nim
│ └── servers.nim # Redis
└── os/
├── init.nim
├── linux.nim # Ubuntu, Debian, CentOS, RHEL, Fedora
└── windows.nim # Windows (via IIS, ASP.NET, en-tête Server)
```
## 法律免责声明
此工具仅用于授权的安全测试、CTF 环境和个人实验室用途。扫描您不拥有或没有明确书面测试许可的系统可能在您的司法管辖区属于违法行为。作者不对滥用行为承担任何责任。
## 路线图 / 后续步骤
- [ ] **真正的 nmap 同级 top-1000 端口列表** — 从真实的 `nmap-services` 数据文件中派生出一个统计排名列表,以取代当前精心挑选的约 150 个端口的列表
- [ ] **扩展签名数据库** — 更多服务(数据库:MySQL/PostgreSQL/MongoDB 握手 banner,RDP,SNMP),更多 OS 版本和系列(FreeBSD、OpenBSD、macOS 信号)
- [ ] **SYN 扫描模式** — raw-socket 半开扫描 (`SOCK_RAW`),作为完整 TCP 连接扫描的更快、更隐蔽的替代方案;需要提升的权限且在 Windows 上支持有限
- [ ] **单元测试** — 针对已知输入验证 `parsePorts`、`getMaxConcurrency` 以及 matcher/engine 层;针对本地 mock 服务的集成测试(例如 `python -m http.server`、本地 SSH daemon)
- [ ] **UDP 扫描支持** — 目前仅支持 TCP
- [ ] **自适应超时** — 根据观察到的 RTT 调整每次探测的超时时间,而不是使用固定值
- [ ] **基于置信度的去重** — 当多个规则匹配同一服务时,保留置信度最高的结果,而不是返回所有匹配项
- [ ] **作品集完善** — 终端截图/录制,简要记录设计决策(为什么选择 async 而不是 threads,为什么使用纯 Nim 正则表达式引擎,为什么采用 probe/signature/engine 分离设计),并在 GitHub Pages 上与其他项目一起展示
标签:Nim, Scrypt密钥派生, 异步网络, 插件系统, 数据泄露防护, 数据统计, 服务指纹识别, 瑞士军刀, 端口扫描, 网络探测