DipesThapa/PortScanner

GitHub: DipesThapa/PortScanner

基于 Nmap 的安全工程化扫描平台,提供 Python CLI 引擎、FastAPI 服务与 React 前端,支持插件扩展、基线差异报告和 SIEM 就绪的 JSON 输出。

Stars: 1 | Forks: 0

# PortScanner — 网络侦察与漏洞编排平台 [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/DipesThapa/PortScanner/actions/workflows/ci.yml) [![CodeQL](https://static.pigsec.cn/wp-content/uploads/repos/cas/53/539e9a6bf48ad24469a4363bff3aa68124154549e26592783d3d8577f2acbbfc.svg)](https://github.com/DipesThapa/PortScanner/actions/workflows/codeql.yml) [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/) [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](#license) 一个安全工程化的平台,将 **Nmap** 转变为完整的扫描服务:一个模块化的 Python 引擎,一个用于威胁情报/自动化响应/深度分析工具的插件系统,历史基线记录,以及一个经过认证的 FastAPI + React Web 应用程序,用于启动和审查扫描。 📝 **撰写:** [*加固我自己的 Nmap Web UI:我发布的安全漏洞,以及真正拯救了我的东西*](https://dev.to/dipesthapa/i-shipped-an-unauthenticated-rce-in-my-own-port-scanner-heres-the-whole-chain-and-how-i-killed-35kl) (dev.to) · [源码](docs/writeup-rce-to-hardened.md) ## 为什么做这个项目 大多数“端口扫描器”项目只是将 `nmap` 包装在一个 subprocess 调用中然后就止步了。 这个项目的构建就像是一个安全团队真正可以部署的产品: - **设计上的纵深防御** — Web 层经过身份验证,每个扫描输入都经过验证,命令执行被列入白名单,并且密钥在日志中被脱敏。[威胁模型](#threat-model) 是文档化的,而不是隐含的。 - **可扩展引擎** — 插件、导出器、凭据提供者和分布式工作程序抽象是一等公民,而不是后期附加的。 - **可操作性** — 容器化(非 root)、健康检查、CI 测试,并且在每次推送时都由 CodeQL、Bandit 和 pip-audit 进行扫描。 ## 架构 ``` flowchart LR subgraph Client UI[React + Vite dashboard] end subgraph Web tier - FastAPI AUTH[API-key auth\nX-API-Key / ws token] API[REST + WebSocket API] JOBS[JobManager\nbackground tasks] DD[DeepDiveExecutor\nallowlisted, shell=False] end subgraph Engine - portscanner package CLI[CLI / orchestrator] SCAN[Nmap runner\nvalidated argv + -- sentinel] PARSE[XML parser] PLUG[Plugins: threat-intel,\nauto-responder, deep-dive] BASE[Baseline store + diff] end DB[(SQLite\nscans, schedules, workers)] NMAP[[nmap binary\ncap_net_raw only]] UI -->|X-API-Key| AUTH --> API API --> JOBS --> CLI --> SCAN --> NMAP CLI --> PARSE --> PLUG --> BASE JOBS --> DB API --> DD --> NMAP API <-->|/ws/status| UI ``` **请求生命周期:** UI 提交扫描(`POST /api/scans`)并附带 API 密钥 → `JobManager` 验证输入,持久化记录,并在后台线程中运行 CLI 引擎 → 引擎构建安全的 `nmap` argv,解析 XML,运行插件,并写入产出物 + 基线 → UI 通过 `/ws/status` 流式传输状态,并在完成后下载产出物。 ## 组件映射 | 层级 | 路径 | 职责 | |-------|------|----------------| | Web API | `webapp/main.py` | 路由、认证装配、SPA 服务 | | Auth | `webapp/security.py` | API 密钥生成、验证、WebSocket 认证 | | Jobs | `webapp/jobs.py` | 扫描生命周期、产出物收集、日志脱敏 | | Deep-dive | `webapp/deepdive.py` | 白名单内的后续命令执行 | | Models | `webapp/models.py` | Pydantic 请求/响应 + 输入验证 | | Engine | `portscanner/` | Nmap 运行器、解析器、插件、基线、导出器 | | Frontend | `webapp/frontend/` | React + Vite 仪表板 | ## 安全模型 完整细节请见 [SECURITY.md](SECURITY.md)。亮点: - **到处都是身份验证。** 每个 `/api/*` 路由和 `/ws/status` WebSocket 都需要 `X-API-Key`。密钥来自 `PORTSCANNER_API_KEY` 或者在首次启动时生成到 `web_runs/.api_key`(模式 `0600`)— 该服务从不匿名运行。`GET /api/health` 特意为健康检查而开放。 - **输入验证。** 目标、端口、脚本名称和额外的 nmap 参数都经过严格验证。类似标志的目标和危险标志(`--script`、`-oN`、`--datadir`、…)会被拒绝,并且一个 `--` 哨兵会在目标之前终止 nmap 选项解析(针对参数注入的纵深防御)。 - **命令执行被列入白名单**,并使用 `shell=False` 运行。上传的脚本不能自行授权;除非设置 `PORTSCANNER_ENABLE_SCRIPT_UPLOAD=1`,否则脚本上传是被禁用的。 - **密钥清理。** 密码、token、bearer header 和 `secret://` 引用在扫描日志持久化之前会被脱敏。 - **加固的容器。** 以非 root 用户运行;`cap_net_raw` 仅授予 nmap 二进制文件,因此无需以 root 身份运行服务即可进行 raw 扫描。 ### 威胁模型 | # | 威胁 | 向量 | 缓解措施 | |---|--------|--------|------------| | T1 | 未经身份验证的访问 | 暴露的 API / WebSocket | 所有 `/api` 路由 + WS 上的 API 密钥认证;常数时间比较 | | T2 | 远程命令 / NSE 执行 | 通过目标/参数注入 `--script=…` | 目标和参数验证,危险标志黑名单,`--` 哨兵 | | T3 | 通过脚本上传执行任意代码 | `POST /api/plugins/scripts` | 默认禁用;上传的内容永远不会自动加入白名单 | | T4 | 深度分析中的命令注入 | 伪造的命令字符串 | 显式白名单 + `shell=False` + `shlex` 分词 | | T5 | 密钥泄露 | 扫描日志持久化到数据库 | 持久化前进行脱敏处理;`.api_key`/凭据被 gitignored | | T6 | 权限提升 | 服务以 root 身份运行 | 非 root 容器;能力范围仅限于 nmap 二进制文件 | | T7 | 供应链漂移 | 未锁定的依赖项 | 锁定 `requirements.txt`;CI 中的 pip-audit + CodeQL | | T8 | 扫描滥用 / SSRF 式侦察 | 未受限制的目标 | 认证门控;部署在具有源 IP 白名单的代理之后(参见 SECURITY.md) | ## 快速开始 ### Docker(推荐) ``` docker compose up --build # API + UI 在 http://localhost:8000 # 首次启动时,生成的 API key 会打印到日志并存储在 web_runs/.api_key ``` 设置您自己的密钥而不是生成的密钥: ``` PORTSCANNER_API_KEY=$(openssl rand -base64 32) docker compose up --build ``` ### 本地开发 ``` # Backend python -m venv .venv && source .venv/bin/activate pip install -r requirements.txt export PORTSCANNER_API_KEY=$(openssl rand -base64 32) uvicorn webapp.main:app --reload # http://127.0.0.1:8000 # Frontend(单独的终端) cd webapp/frontend npm install npm run dev # http://127.0.0.1:5173 (proxies /api to :8000) ``` UI 在首次加载时会提示输入 API 密钥,并将其存储在 `localStorage` 中。 ### 经过身份验证的 API 示例 ``` KEY=$(cat web_runs/.api_key) # or your PORTSCANNER_API_KEY curl -s http://localhost:8000/api/health # open curl -s -H "X-API-Key: $KEY" http://localhost:8000/api/scans # authenticated curl -s -H "X-API-Key: $KEY" -H 'Content-Type: application/json' \ -d '{"target":"scanme.nmap.org","ports":"1-1024","intel":true}' \ http://localhost:8000/api/scans ``` ### Web API 端点 | 方法 | 路径 | 描述 | |--------|------|-------------| | `GET` | `/api/health` | 存活检查(未经身份验证) | | `POST` | `/api/scans` | 提交扫描(与 CLI 选项相同) | | `GET` | `/api/scans` | 列出任务及其状态、摘要、插件输出 | | `GET` | `/api/scans/{id}` | 检查任务:日志、差异、产出物 | | `GET` | `/api/scans/{id}/artifacts/{path}` | 下载生成的产出物 | | `POST` | `/api/scans/{id}/deepdive` | 运行白名单内的后续命令 | | `WS` | `/ws/status?token=KEY` | 实时任务/worker/深度分析状态流 | ## CLI 引擎 相同的引擎可以在没有 Web 层的情况下独立运行。 ``` python3 port_scanner.py --target example.com --ports 1-1024 --intel ```
更多 CLI 示例(批处理、插件、基线、凭据、配置) ### 批量扫描与并发 ``` python3 port_scanner.py \ --targets 192.168.1.10 192.168.1.11 \ --ports 1-65535 --concurrency 2 \ --output-dir scans/ --output-json combined.json ``` ### 服务情报 ``` python3 port_scanner.py --target web.example.com --intel \ --intel-scripts banner,http-title,ssl-cert ``` ### 插件与自动化 ``` python3 port_scanner.py --target 192.168.1.42 --intel \ --plugins threat-intel auto-responder deep-dive \ --plugin-config plugin-options.json ``` ``` { "auto-responder": {"min_severity": "critical", "forbidden_ports": ["23", "3389"]}, "deep-dive": {"commands": {"http": ["nuclei -target {target}:{port}"]}} } ``` ### 差异报告与基线 ``` python3 port_scanner.py --targets 192.168.1.10 192.168.1.11 \ --baseline-json baselines/latest.json \ --diff-report diffs/today.json --output-json reports/today.json ``` ### 凭据存储 ``` python3 port_scanner.py --target core-switch.local \ --credential-file creds.json --secret-file secrets.json --plugins deep-dive ``` ### 配置文件 ``` python3 port_scanner.py --config scan-config.json ``` ### 使用保存的 XML ``` python3 port_scanner.py --xml-file scan.xml --save-report recap.txt --save-vulns recap.json ```
### 关键输出与选项标志 - `--save-xml PATH` / `--save-vulns PATH` / `--save-report PATH` / `--output-json PATH` - `--output-dir DIR` — 针对特定目标的 `*.xml` 和 `*.vulns.json` - `--intel [--intel-scripts …]` — 服务信息丰富 + 补救提示 - `--baseline-json PATH` / `--diff-report PATH` / `--baseline-store DIR` - `--plugins … [--plugin-config PATH]`、`--exporters … [--exporter-config PATH]` - `--credential-file PATH` / `--secret-file PATH` / `--secret-prefix PREFIX` - `--asset-file PATH`、`--orchestrator-config PATH`、`--job-file PATH` 运行 `python3 port_scanner.py --help` 获取完整列表。 ## 测试与质量门禁 ``` export PORTSCANNER_API_KEY=test-key-0123456789 pytest -q ``` CI(`.github/workflows/`)在每次推送和 PR 时运行: - **`ci.yml`** — pytest(Python 3.11 & 3.12)、**Bandit** 静态安全扫描、**pip-audit** 依赖项漏洞检查,以及前端构建。 - **`codeql.yml`** — 针对 Python 和 JavaScript/TypeScript 的 GitHub CodeQL 分析,每周及在 PR 时运行。 ## 配置参考 | 变量 | 用途 | 默认值 | |----------|---------|---------| | `PORTSCANNER_API_KEY` | API 密钥(16+ 个字符) | 自动生成到 `web_runs/.api_key` | | `PORTSCANNER_ENABLE_SCRIPT_UPLOAD` | 允许 `POST /api/plugins/scripts` | 禁用 | | `PORTSCANNER_SAFE_CONFIG` | 安全扫描配置的路径 | `/config_safe.json` | | `DEEP_DIVE_ALLOWLIST` | 允许的深度分析命令(CSV 或文件) | `testssl.sh,nmap,nuclei` | | `DEEP_DIVE_ALLOWLIST_FILE` | 允许命令的 JSON/文本文件 | – | | `DEEP_DIVE_ALLOW_ALL` | `1` 禁用白名单强制执行(不安全) | 禁用 | ## 项目布局 ``` portscanner/ Core engine (scanner, parser, plugins, baselines, exporters) webapp/ FastAPI backend (main, security, jobs, deepdive, models) webapp/frontend/ React + Vite dashboard tests/, webapp/tests/ Pytest suites .github/workflows/ CI + CodeQL Dockerfile, docker-compose.yml Container build (non-root) SECURITY.md Security & threat model ``` ## 许可证 MIT — 详见 `LICENSE`(如果不存在请添加)。
标签:AV绕过, CTI, FastAPI, Python, RESTful API, 提示词优化, 插件系统, 数据统计, 无后门, 端口扫描, 请求拦截, 逆向工具