PrincetonAfeez/Port-Scanner
GitHub: PrincetonAfeez/Port-Scanner
portsleuth 是一个面向网络与协议教学的教育性 Python CLI 端口扫描器,提供 TCP 扫描、HTTP/TLS 探测和数据包结构演示等核心功能。
Stars: 1 | Forks: 0
# portsleuth
`portsleuth` 是一个安全的教育性 Python CLI 端口扫描器,专为网络与协议顶点项目设计。它优先关注可移植的核心功能:DNS 解析、授权、asyncio TCP 连接扫描、速率限制、本地实验服务、原始 HTTP 探测、WSGI 演示、结构化输出以及数据包头部/校验和证据。
它不是 `nmap` 的克隆版,也不包含隐秘扫描、逃避检测、欺骗、绕过 IDS、凭证攻击或漏洞利用检查。
## 快速开始
在此文件夹下:
```
python -m pip install -e .
portsleuth doctor
portsleuth scan 127.0.0.1 --ports 9089-9091
```
除非有服务正在监听,否则上述默认扫描端口为空。要查看
开放端口,请先启动实验装置(参见下方的演示脚本),或扫描一个您已知正在使用的端口。
在未安装的情况下,请使用:
```
$env:PYTHONPATH="src"
python -m portsleuth doctor
```
用于检查自签名实验目标证书字段的可选扩展
(`probe tls --insecure`);验证路径及其他所有功能均无需额外依赖:
```
python -m pip install -e ".[tls]"
```
## 核心命令
```
portsleuth scan 127.0.0.1 --ports 8000-8010
portsleuth scan 127.0.0.1 --ports 80,443,8080 --format json
portsleuth scan 127.0.0.1 --ports 9090 --probe
portsleuth probe http 127.0.0.1 --port 8080 --show-preview
portsleuth probe banner 127.0.0.1 --port 9090
portsleuth probe tls example.com --port 443 --authorized --reason "owned test target"
portsleuth discover 127.0.0.1 --authorized --reason "lab sweep"
portsleuth lab serve-tcp --port 9090 --banner "portsleuth fixture"
portsleuth lab serve-wsgi --port 8080
portsleuth lab serve-udp --port 5353
portsleuth packet demo --protocol all
portsleuth benchmark 127.0.0.1 --ports 1-1000
portsleuth report scan-report.json --format table
portsleuth config
```
`--probe` 也可以写成 `--banner`,并且 `--format grep` 是
`grepable` 的别名。TLS 探测默认会验证证书;对于自签名的实验目标,请传入 `--insecure`。
解析为 IPv4 和 IPv6 的主机名默认使用 IPv4(即可移植的核心功能);使用 `--family ipv6` 或 `--family auto` 可更改此设置。
使用 `--family auto` 时,双栈主机名会为每个地址生成一行结果。
`--top N` 从精选的静态列表(而非 nmap 频率排名)中选择前 N 个端口。
`scan --probe-insecure` 会在进行 `--probe` 时跳过 HTTPS 端口的 TLS 验证;
独立的 `probe tls` 同样使用 `--insecure`。
`portsleuth --version` 打印版本信息;`--verbose` 会将 stderr 上的诊断日志级别提升至 INFO。
扫描结果输出到 stdout;警告和错误输出到 stderr。
有意义的退出码:`0` 成功,`1` 常规错误,`2` 无效用法,
`3` 授权被拒绝,`4` 目标解析失败,`5` 不支持的技术/平台,
`6` 权限不足(当原始套接字不可用时的 `doctor --require-raw`),
`7` 部分扫描失败(包含错误、权限被拒绝、未知或不可达端口结果),
`8` 实验启动失败,
`130` 被中断(如果有可用结果,将写入部分结果;如果部分结果包含错误、权限被拒绝、未知或不可达状态,则返回退出码 `7`)。
## 配置
可以通过工作目录(或 `PORTSLEUTH_CONFIG` 中的路径)下的 `scan.toml` 文件覆盖默认设置。
命令行参数始终优先于配置文件,而配置文件优先于内置默认值。
复制 `scan.toml.example` 为 `scan.toml` 开始配置,并运行 `portsleuth config` 查看实际生效的值及其来源。
```
[defaults]
timeout = 0.75
concurrency = 100
rate = 200.0
```
## 安全模型
所有目标在任何扫描开始前都必须经过授权门禁。
- 默认允许回环目标。
- 非本地私有目标需要 `--authorized`。
- 公共目标需要 `--authorized` 和 `--reason`。
- CIDR 范围需要 `--authorized` 和 `--reason`(包括诸如 `127.0.0.0/30` 之类的回环 CIDR,它们依然需要这些标志并会写入审计记录)。
- 通过门禁的私有、公共或 CIDR 目标扫描会将审计记录写入 `.portsleuth/audit.jsonl`
(路径相对于当前目录;可使用 `--audit-file` 覆盖)。单个回环目标不写入审计记录。
相同的审计跟踪也适用于 `discover`、`benchmark` 和授权的 `probe` 命令。
授权的本地实验扫描示例:
```
portsleuth scan 192.168.1.10 --ports 22,80,443 --authorized --reason "home lab"
```
## 扫描器演示内容
- 从主机名到套接字地址的 DNS 解析。
- TCP 连接扫描,支持开放、关闭、被过滤、不可达和未知状态分类。
- 带有信号量和令牌桶速率限制器的 `asyncio` 并发。
- 保守的超时设置,避免在无响应的主机上挂起。
- 通过 TCP 手动编写的 HTTP 请求字节。
- HTTP 状态行和头部解析。
- TLS 握手检查,包括证书主题、颁发者、有效期和 SANs。
- 针对丢弃 ICMP 的主机的 TCP-ping 主机发现(`portsleuth discover`)。
- 作为 Python 应用程序接口的 WSGI,通过 `wsgiref.simple_server` 进行演示。
- 通过 `portsleuth doctor` 实现具备平台感知的原始套接字能力检查。
- 通过 IPv4、TCP、UDP、ICMP 和校验和模块展示数据包层面的知识。
## 已实现与计划中
| 领域 | 状态 |
|------|--------|
| TCP 连接扫描器、asyncio 引擎、速率限制 | 已实现 |
| 授权门禁、审计 JSONL(Unix fcntl 锁;Windows 进程内锁) | 已实现 |
| HTTP/TLS 探测、WSGI 实验、TCP-ping 发现 | 已实现 |
| 数据包头部打包/解包证据(`portsleuth packet demo`) | 已实现 |
| `probe banner`、`lab serve-udp`、`docs/` 下的答辩文档 | 已实现 |
| 原始 SYN 扫描、UDP 扫描、ICMP 扫描 | 计划中(受能力门控限制;参见 ADRs) |
| `classify.py` / 专用异步引擎模块 | 已合并至 `scan/connect.py` + `scan/classify.py` |
| Django 仪表板、nmap 对比 | 延伸目标 / 超出范围 |
请参阅 `docs/adr/` 了解设计决策(异步并发和速率限制:[ADR 0007](docs/adr/0007-async-concurrency-rate-limiting.md))。答辩材料:[`docs/demo-script.md`](docs/demo-script.md)、[`docs/protocol-mastery-checklist.md`](docs/protocol-mastery-checklist.md)、[`docs/rubric.md`](docs/rubric.md)、[`docs/platform-notes.md`](docs/platform-notes.md)。
## 演示脚本
有关完整的通过/失败演示,请参见 [`docs/demo-script.md`](docs/demo-script.md)。快速版本:
终端 1:
```
portsleuth lab serve-tcp --port 9090 --banner "portsleuth fixture"
```
终端 2:
```
portsleuth scan 127.0.0.1 --ports 9089-9091 --probe
```
终端 3:
```
portsleuth lab serve-wsgi --port 8080
```
终端 4:
```
portsleuth probe http 127.0.0.1 --port 8080 --show-preview
portsleuth benchmark 127.0.0.1 --ports 1-100
```
## 平台说明
请参见 [`docs/platform-notes.md`](docs/platform-notes.md)。摘要:
原始数据包行为因操作系统而异。`portsleuth doctor` 会报告是否可以创建原始 ICMP 和原始 TCP 套接字。
数据包头部模块作为协议证据包含在内;除非未来添加特权实现,否则可移植扫描器路径会按预期将原始 SYN 扫描报告为不支持。
## 开发
为了实现可复现的审计和 CI 运行,请安装锁定的开发依赖:
```
python -m pip install -r requirements-dev.lock.txt
python -m pytest
python -m pytest --cov=portsleuth --cov-report=term-missing
python -m ruff check src tests
```
对于具有灵活最低版本要求的日常开发,请改用 `requirements-dev.txt`:
```
python -m pip install -r requirements-dev.txt
```
该套件包含 200 多个单元和集成测试(`src/portsleuth` 上的代码行覆盖率约为 92%)。
测试仅使用回环装置,不会扫描公共主机。
可选扩展:
```
python -m pip install -r requirements-tls.txt # certificate field extraction for probe tls --insecure
```
特权原始套接字测试位于 `tests/privileged/` 中,仅在设置了 `PORTSLEUTH_PRIVILEGED_TESTS=1` 且平台支持原始套接字时才会运行。
## 生产环境反思
生产环境级别的扫描器将需要更强大的 IPv6 支持、更丰富的指纹识别、可恢复的任务、持久的报告存储、RBAC、签名的扫描策略、企业白名单、更深入的 UDP 重试机制、稳健的取消操作,以及在受控实验室中与成熟工具进行系统性对比。
审计日志会追加换行符分隔的 JSON 数据,在 Unix 上使用 `fcntl` 文件锁定,在 Windows 上使用进程内锁定,
这对于单操作员的本地使用已经足够;而生产环境构建版本会使用数据库或集中式日志记录,从而确保在每个平台上的并发扫描都能被安全地序列化。
## 许可证
MIT — 详见 [LICENSE](LICENSE)。
标签:DNS查询工具, Python, 内核驱动, 并发处理, 底层编程, 异步IO, 插件系统, 教育工具, 无后门, 端口扫描器, 网络协议, 网络工具, 计算机取证, 逆向工具