ToluGuy/heimdall-vscanner

GitHub: ToluGuy/heimdall-vscanner

Heimdall 是一款采用服务器-Agent 架构的分布式局域网漏洞评估扫描器,通过统一仪表盘调度 Nmap、Nikto 和 NSE 实现内网资产的自动化安全巡检。

Stars: 0 | Forks: 0

# Heimdall V-Scanner 专为内部办公网络使用的分布式漏洞评估扫描器。Heimdall 通过中央服务器和多个远程 agent 协调扫描任务,提供统一的仪表盘,以全面了解整个局域网内的网络漏洞。 ## 架构 Heimdall 采用服务器-agent 模型: - **后端服务器** — 一个 FastAPI 应用程序,负责管理任务队列、agent 注册、调度和扫描结果。由 PostgreSQL 提供支持。 - **远程扫描器** (`scanner.py`) — 与后端一起在中央服务器上运行。处理针对无法直接运行 agent 的目标(如防火墙、交换机和打印机)的无代理远程扫描。 - **Agent** (`agent/agent.py`) — 运行在网络上的任何端点。轮询服务器获取任务,并从该机器的网络位置执行扫描。 - **本地扫描器** (`agent/local_scanner.py`) — 适用于任何端点的完全独立扫描工具。运行自己的本地 Web UI,不需要中央服务器,并将结果保留在当前会话的内存中。 - **仪表盘** — 由后端提供的 Web 界面,用于创建任务、监控 agent、查看扫描结果、管理调度和生成报告。 ## 法律声明 Heimdall V-Scanner 采用 [MIT 许可证](LICENSE)授权。 此工具仅限在您拥有或获得**明确书面授权**测试的网络和系统上使用。未经授权的扫描在大多数司法管辖区都是非法的。使用本软件即表示您同意 [DISCLAIMER.md](DISCLAIMER.md) 中的条款。 ## 扫描工具 Heimdall 会自动将三个工具链接在一起: - **Nmap** — 端口发现和服务检测。每次扫描首先运行此工具。 - **Nikto** — Web 漏洞扫描。当 Nmap 发现开放的 Web 端口时自动触发。 - **NSE (Nmap Scripting Engine)** — 针对非 Web 服务(SSH、SMB、RDP、数据库等)的漏洞脚本扫描。 仪表盘使用通俗易懂的语言表示扫描类型。内部名称(在 API 和数据库中使用)显示在括号中供参考。 ## 扫描类型 | 仪表盘标签 | 内部名称 | 描述 | |-----------------|---------------|-------------| | 端口扫描 | `nmap_scan` | 发现开放端口;自动对发现的任何 Web 端口运行快速的 Web 扫描(轻量级 profile)。要运行彻底的 Web 扫描,请显式创建 Web 扫描任务。 | | Web 扫描 | `nikto_scan` | 针对特定端口的独立 Web 漏洞扫描 | | 漏洞扫描 | `nse_scan` | 针对非 Web 服务的基于脚本的漏洞检查;排除 Web 端口 | ## 扫描 Profiles | Profile | Nmap 标志 | Web 扫描标志 | 漏洞脚本 | 描述 | |---------|-----------|----------------|--------------|-------------| | Light | `-F` | `-Tuning 1` | `safe` | 前 100 个端口,快速,非侵入式 | | Standard | `-sV` | default | `vuln` | 前 1000 个端口,包含服务检测 | | Full | `-sV -O -p-` | `-Tuning x6` | `vuln,exploit` ⚠️ | 所有端口,深度扫描 — exploit 脚本具有侵入性 | ## 快速安装(Linux 服务器) 安装程序会处理一切:依赖项、数据库、环境配置和 systemd 服务。 ``` git clone https://github.com/ToluGuy/heimdall-vscanner.git cd heimdall-vscanner chmod +x install.sh ./install.sh ``` 请使用具有 sudo 权限的普通用户运行,不要使用 root 用户。 安装程序将执行以下操作: - 安装系统软件包(nmap、nikto、postgresql、python3-venv) - 创建 Python 虚拟环境并安装依赖项 - 提示输入仪表盘凭据和数据库设置,然后写入 `.env` - 设置 PostgreSQL 数据库、用户和所有必需的权限 - 自动运行所有 schema 迁移 - 安装并可选择启动 `vapt-server` 和 `vapt-scanner` systemd 服务 - 如果 UFW 处于活动状态,则在其中开放端口 8000 ## 更新 发布新版本时,请运行更新程序而不是重新安装: ``` git pull chmod +x update.sh ./update.sh ``` 更新程序会拉取最新的代码,更新 Python 依赖项,运行所有新的数据库迁移,并重启服务。您的 `.env`、现有扫描数据和 agent 注册信息都将被保留。在服务重启期间,仪表盘将不可用几秒钟。 如果您是在没有 git 的情况下安装的(手动下载),请手动替换项目文件,然后运行 `./update.sh` 来处理依赖项、迁移和重启。 ## 手动设置 如果您不想使用安装程序: ### 1. 克隆仓库 ``` git clone https://github.com/ToluGuy/heimdall-vscanner.git cd heimdall-vscanner ``` ### 2. 安装系统依赖 ``` sudo apt install nmap nikto postgresql python3-venv python3-pip ``` ### 3. 创建并激活虚拟环境 ``` python3 -m venv venv source venv/bin/activate ``` ### 4. 安装 Python 依赖项 ``` pip install -r requirements.txt ``` ### 5. 设置 PostgreSQL ``` sudo -u postgres psql ``` ``` CREATE DATABASE vapt; CREATE USER vapt_user WITH PASSWORD 'your-password'; GRANT ALL PRIVILEGES ON DATABASE vapt TO vapt_user; ALTER DATABASE vapt OWNER TO vapt_user; GRANT ALL ON SCHEMA public TO vapt_user; \q ``` ### 6. 配置环境变量 在项目根目录下创建一个 `.env` 文件: ``` DASHBOARD_USERNAME=admin DASHBOARD_PASSWORD=your-strong-password DB_HOST=localhost DB_PORT=5432 DB_NAME=vapt DB_USER=vapt_user DB_PASSWORD=your-password ``` ### 7. 运行数据库迁移 ``` python3 -c " from backend.app.db import engine, Base from backend.app.models import Agent, Job, Result, DiscoverySweep, Schedule, Host, Setting Base.metadata.create_all(bind=engine) " ``` 如果是从早期版本升级,还需运行以下 SQL 语句: ``` ALTER TABLE results ADD COLUMN IF NOT EXISTS cleared BOOLEAN DEFAULT FALSE; ALTER TABLE jobs ADD COLUMN IF NOT EXISTS cleared BOOLEAN DEFAULT FALSE; ALTER TABLE jobs ADD COLUMN IF NOT EXISTS mode VARCHAR DEFAULT 'remote'; ALTER TABLE jobs ADD COLUMN IF NOT EXISTS profile VARCHAR DEFAULT 'standard'; ALTER TABLE jobs ADD COLUMN IF NOT EXISTS started_at TIMESTAMP; ALTER TABLE jobs ADD COLUMN IF NOT EXISTS completed_at TIMESTAMP; ALTER TABLE jobs ADD COLUMN IF NOT EXISTS next_run_at TIMESTAMP; ALTER TABLE jobs ADD COLUMN IF NOT EXISTS port INTEGER; ALTER TABLE jobs ADD COLUMN IF NOT EXISTS ports VARCHAR; ALTER TABLE agents ADD COLUMN IF NOT EXISTS is_stale BOOLEAN DEFAULT FALSE; CREATE TABLE IF NOT EXISTS schedules ( id SERIAL PRIMARY KEY, name VARCHAR NOT NULL, type VARCHAR NOT NULL, target VARCHAR NOT NULL, mode VARCHAR DEFAULT 'remote', profile VARCHAR DEFAULT 'standard', priority VARCHAR DEFAULT 'medium', ports VARCHAR, interval_hours INTEGER NOT NULL, paused BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT NOW(), last_run_at TIMESTAMP, next_run_at TIMESTAMP ); CREATE TABLE IF NOT EXISTS settings ( key VARCHAR PRIMARY KEY, value VARCHAR NOT NULL ); GRANT ALL ON TABLE schedules TO vapt_user; GRANT ALL ON TABLE settings TO vapt_user; GRANT USAGE, SELECT ON SEQUENCE schedules_id_seq TO vapt_user; ``` `discovery_sweeps` 和 `hosts` 表会在启动时由 SQLAlchemy 自动创建。 ### 8. 启动服务器 ``` uvicorn backend.app.main:app --host 0.0.0.0 --port 8000 ``` 仪表盘可通过 `http://localhost:8000/dashboard` 访问。 ## 部署(生产环境) ### 推荐设置 在您可用的任何 hypervisor(ESXi、Proxmox、VirtualBox 等)上使用专用的 Linux 虚拟机。后端服务器和远程扫描器均在此虚拟机上运行。Agent 单独在各个端点上运行。 **最低虚拟机规格:** - 2 vCPU,2 GB 内存,20 GB 磁盘 - Ubuntu 22.04 或 24.04 LTS - 办公局域网上的静态 IP ### ESXi 设置 1. 下载 Ubuntu 24.04 LTS 服务器 ISO 2. 在 ESXi 中,创建一个新虚拟机:2 vCPU,2 GB 内存,20 GB thin-provisioned 磁盘 3. 挂载 ISO,安装 Ubuntu 并启用 OpenSSH 4. 通过 netplan 设置静态 IP: ``` # /etc/netplan/00-installer-config.yaml network: version: 2 ethernets: ens160: addresses: [192.168.1.200/24] gateway4: 192.168.1.1 nameservers: addresses: [8.8.8.8, 1.1.1.1] ``` ``` sudo netplan apply ``` 5. 通过 SSH 登录并运行安装程序。 ### Systemd 服务 安装程序会自动设置两个服务: ``` # 状态 sudo systemctl status vapt-server sudo systemctl status vapt-scanner # 启动 / 停止 / 重启 sudo systemctl start vapt-server vapt-scanner sudo systemctl restart vapt-server vapt-scanner # 开机启用 sudo systemctl enable vapt-server vapt-scanner # 实时日志 journalctl -u vapt-server -f journalctl -u vapt-scanner -f ``` ### 网络要求 必须从局域网能够访问服务器上的 8000 端口,以便 agent 和浏览器连接: ``` sudo ufw allow 8000/tcp ``` | 方向 | 来源 | 目标 | 端口 | 用途 | |-----------|------|----|------|---------| | 出站 | 服务器/扫描器 | 扫描目标 | any | Nmap, Nikto, NSE | | 出站 | Agents | 服务器 | 8000 | 任务轮询、心跳、结果 | | 入站 | 浏览器 | 服务器 | 8000 | 仪表盘访问 | Agent 只需要对服务器上 8000 端口的出站访问权限。它们不需要可被入站访问。 ## 仪表盘 通过 `/dashboard` 访问仪表盘。首次加载时,系统会提示您输入凭据。 在仪表盘中,您可以: - **网络发现** — 以 CIDR 表示法扫描子网以查找活动主机;在分配扫描任务之前查看结果 - **计划任务** — 按可配置的时间间隔设置定期扫描;随时暂停、恢复或删除计划任务 - **创建任务** — 手动为任何 IP 提交扫描任务,并控制扫描类型、profile、模式和优先级 - **Agents** — 监控已注册的 agent、它们的在线/离线状态以及最后一次心跳;显示或隐藏过期 agent;恢复或忽略它们 - **任务** — 查看任务队列以及正在运行的任务的实时耗时计时器;按状态过滤;批量删除待处理和失败的任务 - **扫描结果** — 展开结果以查看端口表、漏洞发现和 Web 扫描发现;在当前结果和历史记录之间切换 - **洞察** — 分析仪表盘,显示一段时间内的扫描活动、风险分布以及逐台主机的详细信息 - **拓扑** — 交互式 D3 网络地图,显示所有发现的主机,按子网聚类,按风险级别着色 - **报告** — 为任何扫描结果生成可打印的 HTML 报告,可通过浏览器打印对话框导出为 PDF - **导出** — 将扫描结果下载为结构化的 JSON,支持单个或批量导出 ## AI 分析 Heimdall 可以使用您选择的 AI 提供商,自动为每个扫描结果生成风险评估和修复计划。在您的 `.env` 中添加以下内容: ``` AI_PROVIDER=anthropic # anthropic | openai | groq | ollama AI_API_KEY=your-api-key AI_MODEL= # optional — leave blank for the provider default AI_BASE_URL= # only needed for ollama AI_AUTO_ANALYSE=true # set to false to trigger analysis manually per result ``` | 提供商 | 默认模型 | |----------|--------------| | `anthropic` | claude-sonnet-4-5 | | `openai` | gpt-4o-mini | | `groq` | llama-3.3-70b-versatile | | `ollama` | llama3 (本地) | 也可以在运行时从仪表盘的“设置”面板中开启/关闭 AI 分析,而无需重启服务器。 ## Agents 有关 Linux 和 Windows 端点的完整 agent 设置说明,请参阅 [`agent/SETUP_GUIDE.md`](agent/SETUP_GUIDE.md)。 ### 快速入门 — Linux ``` cd agent/ pip install requests python-dotenv VAPT_AGENT_NAME=office-pc-1 \ VAPT_SERVER_URL=http://192.168.1.200:8000 \ VAPT_CAPABILITIES=nmap_scan,nikto_scan,nse_scan \ python3 agent.py ``` ### 快速入门 — Windows 在 PowerShell 中以管理员身份运行 `agent/setup_agent.ps1`。它会自动处理 Python、Nmap、依赖项、配置和桌面快捷方式。 ``` Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass .\agent\setup_agent.ps1 ``` ### 本地扫描器(任何端点,不需要服务器) ``` python3 agent/local_scanner.py ``` 在 `http://127.0.0.1:9731` 打开基于浏览器的扫描 UI。支持端口扫描和漏洞扫描。结果保存在当前会话的内存中,可以在关闭前导出为 JSON。 ## 调度 计划任务从仪表盘创建并存储在数据库中。每个计划任务定义扫描类型、目标、profile、模式、优先级以及以小时为单位的重复间隔。调度器每 60 秒检查一次是否有到期的计划任务,并自动创建相应的扫描任务。 计划任务在创建时立即触发,然后按配置的间隔重复。恢复已暂停的计划任务需等待一个完整的间隔才会再次触发。 ## 过期 Agent 清理 未在可配置阈值(默认为 24 小时)内发送心跳的 Agent 将被后台清理线程自动标记为过期。过期 agent 会从默认 agent 视图中隐藏,但可以通过“显示过期”开关显示。从那里可以恢复或永久忽略它们。 可以从仪表盘的“设置”面板调整阈值,或者在 `.env` 中设置 `STALE_AGENT_HOURS`。 ## 优先级队列 任务支持三个优先级:`high`、`medium` 和 `low`。调度器总是首先选择符合条件且优先级最高的任务。在同一优先级内,特定 agent 的任务优先于任意 agent 的任务,并且旧任务会先于新任务被选中。每个 agent 最多同时处理 2 个并发任务。 ## 项目结构 ``` heimdall-vscanner/ ├── agent/ │ ├── agent.py # Endpoint agent — polls server, runs scans locally │ ├── local_scanner.py # Standalone scan tool with browser UI (no server needed) │ ├── setup_agent.ps1 # Windows endpoint setup script │ └── SETUP_GUIDE.md # Agent and local scanner setup guide ├── backend/ │ └── app/ │ ├── main.py # FastAPI server, all endpoints, dashboard HTML │ ├── models.py # SQLAlchemy database models │ ├── schemas.py # Pydantic request/response schemas │ ├── db.py # Database connection and session │ ├── logger.py # Logging configuration │ └── ai_analysis.py # AI-powered scan analysis (optional) ├── tools/ │ ├── check_db.py # Database health check │ ├── reset_stuck_jobs.py # Unstick jobs that got stuck in 'running' │ ├── purge_history.py # Permanently delete archived scan history │ ├── reset_db.py # Wipe all scan data (dev/test use only) │ ├── seed_test_jobs.py # Create test jobs against localhost │ ├── test_connection.py # Verify agent-to-server connectivity │ └── test_ports.py # Open netcat listeners for scan testing ├── scanner.py # Agentless remote scanner (runs on central server) ├── install.sh # Automated Linux installer ├── update.sh # Lightweight updater for new releases ├── vapt-server.service # Systemd service file — backend server ├── vapt-scanner.service # Systemd service file — remote scanner ├── requirements.txt ├── .env # Not committed — created by installer or manually └── logs/ # Not committed — created at runtime ``` ## 环境变量 ### 服务器 | 变量 | 描述 | 默认值 | |----------|-------------|---------| | `DASHBOARD_USERNAME` | 仪表盘登录用户名 | `admin` | | `DASHBOARD_PASSWORD` | 仪表盘登录密码 | `vapt-admin` | | `DB_HOST` | PostgreSQL 主机 | `localhost` | | `DB_PORT` | PostgreSQL 端口 | `5432` | | `DB_NAME` | 数据库名称 | `vapt` | | `DB_USER` | 数据库用户 | `vapt_user` | | `DB_PASSWORD` | 数据库密码 | — | | `STALE_AGENT_HOURS` | agent 被标记为过期前的小时数 | `24` | | `AI_PROVIDER` | 用于扫描分析的 AI 提供商(`anthropic`、`openai`、`groq`、`ollama`) | — | | `AI_API_KEY` | 所选 AI 提供商的 API 密钥 | — | | `AI_MODEL` | 模型覆盖 — 留空则使用提供商默认值 | — | | `AI_BASE_URL` | Ollama 的 Base URL(例如 `http://localhost:11434`) | — | | `AI_AUTO_ANALYSE` | 每次扫描后自动运行 AI 分析 | `true` | ### Agent | 变量 | 描述 | 默认值 | |----------|-------------|---------| | `VAPT_SERVER_URL` | 后端服务器的 URL | `http://127.0.0.1:8000` | | `VAPT_AGENT_NAME` | 此 agent 实例的名称 | `agent-default` | | `VAPT_CAPABILITIES` | 此 agent 处理的、以逗号分隔的扫描类型 | `nmap_scan,nikto_scan,nse_scan` | | `VAPT_KEY_FILE` | 存储 agent 密钥的路径 | `{agent-name}_key.txt` | ## 故障排除 **服务器无法启动** 检查日志:`journalctl -u vapt-server -n 50`。最常见的原因是 `.env` 文件损坏或 PostgreSQL 未运行(`sudo systemctl status postgresql`)。 **Agent 在仪表盘中显示离线** 心跳超时为 30 秒。如果 agent 在该时间窗口内未发送心跳,则会显示为离线。请确认 agent 正在运行且能够访问服务器上的 8000 端口。 **计划任务因权限错误而失败** `schedules` 表在创建时数据库用户没有写入权限。请以 postgres 超级用户身份运行: ``` GRANT ALL ON TABLE schedules TO vapt_user; GRANT USAGE, SELECT ON SEQUENCE schedules_id_seq TO vapt_user; ``` **Web 扫描 (Nikto) 挂起** 由 Nikto 2.6.x 中的 CIRT.net 更新提示引起。扫描器会使用 `input="n\n"` 自动抑制它。如果扫描仍然挂起,请使用 `nikto -Version` 检查 Nikto 是否正确安装。 **漏洞扫描未返回任何结果** 如果目标在可发现的端口上没有运行非 Web 服务,这是正常的。漏洞扫描会特意跳过 Web 端口(80、443、8080、8443、8000、8888)— 请使用 Web 扫描进行 Web 表面测试。 **Agent 无法访问端口 8000** 检查服务器防火墙:`sudo ufw status`。如果处于活动状态,请运行 `sudo ufw allow 8000/tcp`。 **启动时出现 PostgreSQL 权限错误** ``` GRANT ALL ON SCHEMA public TO vapt_user; ALTER DATABASE vapt OWNER TO vapt_user; ``` **AI 分析未显示** 检查 `.env` 中是否设置了 `AI_PROVIDER` 和 `AI_API_KEY`,并确认服务器已重启。您也可以在仪表盘中点击任何结果上的“分析”来手动触发分析。验证在“设置”面板中是否已启用该设置。 **更新弄坏了某些东西** 每次更新只会增加列 — 它永远不会删除或修改现有列。如果更新后出现异常,请检查 `journalctl -u vapt-server -n 50` 以查看启动错误,并将您的 `.env` 与上面的环境变量表进行比较,看看是否有任何新的必需值。
标签:AV绕过, CTI, FastAPI, Nmap, 分布式架构, 插件系统, 测试用例, 网络安全, 虚拟驱动器, 逆向工具, 隐私保护