创建网站安全漏洞扫描工具
码不停提
用 Python 搭建一个网站安全漏洞扫码工具,覆盖全部安全漏洞类型,但是因为有些漏洞通过直接扫描不能完确定,所以在扫描时会将可疑的点标记为 suspect.*,后续需要手动确认。本项目开发耗时 5天。
码不停提
用 Python 搭建一个网站安全漏洞扫码工具,覆盖全部安全漏洞类型,但是因为有些漏洞通过直接扫描不能完确定,所以在扫描时会将可疑的点标记为 suspect.*,后续需要手动确认。本项目开发耗时 5天。

Cyber Walker 系统功能与后台操作流程
目标:把“它能做什么、后台怎么用、一次扫描在系统里怎么跑完”讲清楚。
适用读者:使用控制台的管理员(admin)/审计只读(reader)、开发/运维。
Cyber Walker 是一个“面向授权资产的安全扫描与证据留存平台”。它把一次扫描拆成多个阶段(Recon → URL 发现 → 证据采集 → 规则分析 → 产出 Findings/RunLog),并通过 Scope 门禁、Safe/Authorized 模式、Verify 手动验证门禁 来控制风险。
与传统“一键跑完所有漏洞验证”的扫描器不同:
flowchart LR
U[用户/管理员] -->|浏览器| C[Console 控制台]
C -->|JWT Bearer| API[FastAPI API]
API --> DB[MySQL]
API -->|投递任务| Q[Celery Broker 通常为 Redis]
W[Celery Worker] -->|取任务| Q
W -->|HTTP/Playwright| T[目标站点/资产]
W -->|写入| DB
API -->|只读查询/列表| DB
C -->|查看结果/下载报告| API
要点:
uvicorn --reload 会自动重载,但 Celery Worker 不会热重载,需要重启 Worker 才能生效。suspect.* 候选类)reader:只读查看(Targets/Scans/Findings/Exchanges 等)admin:可写操作(创建/修改 Target、Profile、创建/克隆 Scan、触发 Verify 等)flowchart TD
A[1. 创建 Target
设置 entry_url] --> B[2. 配置 Scope
allowed_hosts/schemes/ports/path_prefix]
B --> C{需要登录态?}
C -- 否 --> E[4. 创建 Scan
选择 Target + Safe/Authorized]
C -- 是 --> D[3. 创建 Login Profile
cookie/token/form_login]
D --> E
E --> F[5. 运行 Scan
(后台 Worker 执行)]
F --> G[6. 查看结果
RunLog/Urls/Exchanges/Findings/Recon/Enum]
G --> H{需要高风险确认?}
H -- 否 --> I[结束:输出报告/复盘]
H -- 是 --> J[7. 选择 URL/Exchange
发起 Verify(手动)]
J --> K[8. Verify 结果落库
生成 verify.* Findings + 证据]
K --> I
操作要点:
系统倾向于把 Scan 当作“不可变的一次执行记录”。当你想调整配置(比如动态发现预算、是否启用枚举、recon ports 等),推荐做法是:
收益:
这一节用“从哪些页面进入、点什么、看什么”来描述后台操作流程,适合给运维/安全同学当操作手册。
entry_urlallowed_hosts:把域名白名单收紧到你确定拥有授权的域名/子域allowed_schemes:通常仅允许 http/httpsallowed_ports:建议明确列出目标服务端口(例如 80/443/8080)path_prefixes:当只允许扫某个路径空间时使用(例如 /app)当扫描需要登录态才能覆盖更多页面/接口时:
推荐路径:
mode: safe/authorized(授权模式通常伴随更严格审计)suspect.* 与 verify 结论)”常见入口是从 Urls/Exchanges/Findings 选中目标后发起 Verify(具体 UI 入口随控制台实现而定)。
执行前建议:
下面给两个“容易理解、便于复用”的思路,实际字段请以控制台表单/Scan config schema 为准。
dynamic_discovery_enabled=trueconfirm_interaction=trueenable_post_form_submit=true下面是“一次 Scan 在 Worker 里”典型会经历的阶段。具体启用与否由 Scan 配置与门禁共同决定(例如 scope、预算、dynamic discovery 开关等)。
flowchart TD
S[Scan 入队/开始] --> L[加载 Scan + Target + Profile
生成 effective_config 快照]
L --> G{Scope 门禁校验
entry_url 是否可扫}
G -- 不通过 --> X[Scan 失败/取消
RunLog 记录原因]
G -- 通过 --> R1
subgraph Recon[Recon(信息收集)]
R1[DNS 解析] --> R2[端口探测(safe)]
end
R2 --> D1
subgraph Discovery[URL 发现(Discovery)]
D1[静态提链
HTML/headers 解析] --> D2{动态发现 enable?}
D2 -- 否 --> D5[得到 URL 集合]
D2 -- 是 --> D3[Playwright 网络监听
抓取 XHR/fetch/document]
D3 --> D4{允许交互?
confirm_interaction=true}
D4 -- 否 --> D5
D4 -- 是 --> D6[交互探索
click/forms(受预算限制)]
D6 --> D5
end
D5 --> E1
subgraph Evidence[证据采集(Evidence)]
E1[抓取 URL
写入 HttpExchange] --> E2[写入 EvidenceBody
FULL/SUMMARY + hash/snippet]
end
E2 --> A1
subgraph Analysis[规则分析(Findings)]
A1[基线/低风险规则
输出 Findings] --> A2[候选规则
输出 suspect.*]
end
A2 --> O[写入 RunLog/统计]
O --> DONE[Scan 完成
succeeded/failed]
系统会尽量把“跳过原因”写进 RunLog,便于排查。
常见门禁:
target.scope.allowed_ports 取交集;交集为空时 Recon 端口探测会跳过dynamic_discovery_enabled=true 才会启用 Playwright 网络监听confirm_interaction=trueenable_post_form_submit=truescan.config.recon.safe.ports(显式端口列表)normalize_ports(config) ∩ target.scope.allowed_ports设计原则:不做“扫描全部 scope 端口”的隐式兜底;端口探测必须是可预期、可解释、可审计的。
路径枚举是“信息收集/扩展 URL”能力:
enum_runs / enum_path_results(Recon 风格表)这张图用于解释“你点了运行后,到底发生了什么”,也方便排查问题落在哪一段。
sequenceDiagram
autonumber
actor Admin as Admin/Reader
participant Console as Console
participant API as FastAPI API
participant DB as MySQL
participant Q as Celery Broker
participant Worker as Celery Worker
participant Target as Target Site
Admin->>Console: 创建/克隆 Scan(填写配置)
Console->>API: POST /api/scans
API->>DB: 写入 Scan + config 快照
API-->>Console: 返回 scan_id
Admin->>Console: 点击运行
Console->>API: POST /api/scans/{id}/run
API->>Q: enqueue scan task
API->>DB: 写入 RunLog(开始)
API-->>Console: 200
Worker->>Q: 获取 scan task
Worker->>DB: 读取 Scan/Target/Profile
Worker->>Target: Recon/抓取/动态发现(受门禁)
Worker->>DB: 写 HttpExchange/EvidenceBody/Urls
Worker->>DB: 写 Findings(含 suspect.*)
Worker->>DB: 写 RunLog(统计/skip 原因)
Worker->>DB: 更新 Scan 状态
Console->>API: GET /api/scans/{id}
API->>DB: 查询 Scan/聚合计数
API-->>Console: 状态 + 结果索引
这部分把数据落库与控制台视图对齐,方便你定位“我该去哪里看”。
recon_runs / dns_records / open_ports → Scan 详情的 Recon 区块urls → Urls 页面(或 Scan 详情的 URL 列表)http_exchanges → Exchanges 页面evidence_bodies → Exchange 详情的 Evidence 预览findings → Findings 页面run_logs → Scan 详情的 RunLogenum_runs / enum_path_results → 枚举结果页面/Scan 详情的 Enum 区块Verify 用来做“高风险、可能造成副作用、但确认价值更高”的验证。它不随普通扫描自动批量执行,而是由 admin 明确触发。
flowchart TD
A[选择目标 URL/Exchange] --> B[选择 Verify 规则/规则模板]
B --> C[门禁校验
角色=admin + 授权/预算/强度]
C -- 不通过 --> X[拒绝执行
返回原因]
C -- 通过 --> D[Worker 执行 Verify
HTTP/Playwright 探测]
D --> E[产出证据 + verify.* Findings]
E --> F[控制台查看/导出]
Verify 的关键点:
建议把 Verify 当作“最终确认工具”,而不是“把所有主动攻击都塞进自动扫描”。
常见场景:
suspect.* 候选:需要把“提示”变成“可复现的结论”强度选择建议:
下面用“你在控制台里经常会做的事”来组织。
entry_urlallowed_hosts、allowed_schemes,并按需要配置 allowed_ports、path_prefixessuspect.*:候选提示,建议结合证据与业务上下文再决定是否 Verifyverify.*:手动验证后的确认型结果(更适合作为最终结论)dynamic_discovery_enabledconfirm_interaction=trueenable_post_form_submit=truetarget.scope.allowed_ports 是否包含目标端口scan.config.recon.safe.ports 是否为空或被 scope 交集后为空这一节更偏运维视角:如何部署组件、如何理解任务队列、如何配置 .env,以及上线后怎么排查。
适合:PoC/测试环境/单机演示。
flowchart TB
subgraph Host[一台服务器/一台开发机]
N[Nginx/反向代理-可选]
API[FastAPI :uvicorn/gunicorn]
W[Celery Worker]
R[(Redis
Celery broker/backend)]
DB[MySQL]
end
User[用户浏览器] -->|HTTPS/HTTP| N
N -->|/api/*| API
N -->|/ console 静态资源 可选:后端同源托管| API
API --> DB
API --> R
W --> R
W --> DB
W --> Target[目标站点/资产]
说明:
/api。CELERY_ENABLED=false 时,API 会用 FastAPI BackgroundTasks 在 API 进程里跑扫描(仅适合 dev/回归,不建议生产)。适合:正式测试环境/多人使用/需要更稳定的 worker 执行。
flowchart TB
User[用户浏览器] -->|HTTPS| N[Nginx/Ingress]
N -->|/| Static[console 静态站点 可由 Nginx 托管]
N -->|/api/*| API[FastAPI API 可水平扩容]
API --> DB[MySQL]
API --> R[Redis broker/backend]
W1[Worker 1] --> R
W2[Worker 2] --> R
W1 --> DB
W2 --> DB
W1 --> Target[目标站点/资产]
W2 --> Target
W1 --> OSS[OSS 可选 快照/证据对象存储]
要点:
-c 以及 verify/爬虫预算共同约束。推荐启停顺序:
常用启动命令(示例):
cd server && ./.venv/bin/python -m uvicorn app.main:app --reload --host 127.0.0.1 --port 8000cd server && ./.venv/bin/python -m celery -A app.celery_app worker -l info -n cw@%h -c 2注意:Worker 不会热重载;任何扫描/验证相关代码改动都需要重启 Worker。
系统对 Celery 做了偏“至少一次投递”的配置(at-least-once):
task_acks_late=true:任务执行完成后才 acktask_reject_on_worker_lost=true:worker 崩溃时任务可被 broker 重新投递worker_prefetch_multiplier=1:减少未开始但已预取的任务堆积CELERY_VISIBILITY_TIMEOUT_SECONDS(Redis broker):控制“未 ack 任务”的重投递时间窗口运维含义:
.env 配置项说明(按类别)后端默认读取 server/.env(示例见 server/.env.example),完整项可参考 server/app/core/config.py。
DATABASE_URL:MySQL 连接串(格式:mysql+pymysql://user:pass@host:port/db)JWT_SECRET_KEY:JWT 签名密钥(务必改为随机值)APP_SECRET_KEY:应用级加密/签名用途(后续里程碑会更依赖)APP_ENV:dev/prod,影响部分错误返回细节LOG_LEVEL:日志级别CELERY_ENABLED:是否启用 Celery 入队CELERY_BROKER_URL:Redis brokerCELERY_RESULT_BACKEND:结果后端(通常同 Redis)CELERY_VISIBILITY_TIMEOUT_SECONDS:未 ack 任务的可见性超时(重投递窗口)EVIDENCE_BODY_LIMIT_BYTES / EVIDENCE_SNIPPET_BYTES:响应体 FULL/SUMMARY 阈值与摘要片段大小SNAPSHOT_STORAGE_BACKEND:db 或 ossSNAPSHOT_OSS_STRICT:strict 时 OSS 上传失败会导致快照生成失败(并在 Exchanges 里记录 error)OSS_ENDPOINT / OSS_BUCKET / OSS_ACCESS_KEY_ID / OSS_ACCESS_KEY_SECRET / OSS_PREFIXOSS_PUBLIC_BASE_URL / OSS_STORE_URL_ENABLEDVERIFY_MAX_*:批量验证的硬上限VERIFY_DEDUPE_TTL_SECONDS:重复验证去重窗口VERIFY_STRENGTH_*:不同强度档位的预算/超时/并发CRAWL_MAX_URLS_HARD_LIMIT / CRAWL_MAX_DEPTH_HARD_LIMITCRAWL_MIN_REQUEST_INTERVAL_MS / CRAWL_REQUEST_TIMEOUT_SECONDS动态发现/枚举/出站代理等也有对应配置项(例如 dynamic discovery 的预算与交互确认默认值、出站代理与 UA 池),建议以 server/app/core/config.py 为准。
使用动态发现(Playwright)或表单登录(form_login)时:
python -m playwright install chromiumpython -m playwright install --with-deps chromium(取决于发行版/权限策略)GET /api/health 返回正常server/scripts/init_db.sql(或对应迁移).env 中的 JWT_SECRET_KEY / APP_SECRET_KEY 已替换为随机值X-Request-Id/X-Trace-Id)CELERY_ENABLED=true 且 broker 配置正确;确认 Worker 在线且无报错这一节给出可直接复制的模板。假设代码部署在:/opt/cyber-walker。
/opt/cyber-walker/
console/
dist/ # 可选:前端 build 产物
server/
.venv/
.env
app/
scripts/
sudo adduser --system --group --home /opt/cyber-walker --shell /usr/sbin/nologin cyberwalker
sudo chown -R cyberwalker:cyberwalker /opt/cyber-walker
也可以沿用你现有的部署用户;关键是 API/Worker 不要以 root 运行。
创建 /etc/systemd/system/cyber-walker-api.service:
[Unit]
Description=Cyber Walker API (FastAPI)
After=network.target
[Service]
Type=simple
User=cyberwalker
Group=cyberwalker
WorkingDirectory=/opt/cyber-walker/server
EnvironmentFile=/opt/cyber-walker/server/.env
# 生产建议用多个 worker,并交给 Nginx 反代
ExecStart=/opt/cyber-walker/server/.venv/bin/python -m uvicorn app.main:app \
--host 127.0.0.1 --port 8000 --workers 2
Restart=always
RestartSec=2
# 让日志进入 journald
StandardOutput=journal
StandardError=journal
# 基础安全加固(可按需调整)
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
[Install]
WantedBy=multi-user.target
启用并启动:
sudo systemctl daemon-reload
sudo systemctl enable --now cyber-walker-api
sudo systemctl status cyber-walker-api --no-pager
创建 /etc/systemd/system/cyber-walker-worker.service:
[Unit]
Description=Cyber Walker Worker (Celery)
After=network.target
[Service]
Type=simple
User=cyberwalker
Group=cyberwalker
WorkingDirectory=/opt/cyber-walker/server
EnvironmentFile=/opt/cyber-walker/server/.env
# -c 并发建议结合机器资源与扫描预算调优
ExecStart=/opt/cyber-walker/server/.venv/bin/python -m celery -A app.celery_app worker \
-l info -n cw@%H -c 2
Restart=always
RestartSec=2
StandardOutput=journal
StandardError=journal
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
[Install]
WantedBy=multi-user.target
启用并启动:
sudo systemctl daemon-reload
sudo systemctl enable --now cyber-walker-worker
sudo systemctl status cyber-walker-worker --no-pager
常用排查命令:
sudo journalctl -u cyber-walker-api -f
sudo journalctl -u cyber-walker-worker -f
CELERY_ENABLED=true 且 CELERY_BROKER_URL/CELERY_RESULT_BACKEND 指向可达的 Redis。两种常见方式:
console/dist 静态文件(推荐)+ /api 反代到后端/ 与 /api 都反代到后端(后端检测到 console/dist 时会同源托管)创建(或修改)/etc/nginx/sites-available/cyber-walker.conf:
server {
listen 80;
server_name _;
# 静态站点(console build 输出)
root /opt/cyber-walker/console/dist;
index index.html;
# SPA history fallback
location / {
try_files $uri $uri/ /index.html;
}
# API 反代
location /api/ {
proxy_pass http://127.0.0.1:8000/api/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 可选:超时按环境调整(动态发现/大响应可能更慢)
proxy_connect_timeout 30s;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
}
启用配置并 reload:
sudo ln -sf /etc/nginx/sites-available/cyber-walker.conf /etc/nginx/sites-enabled/cyber-walker.conf
sudo nginx -t
sudo systemctl reload nginx
如果你不想让 Nginx 直接接触静态目录,可以这样做:
server {
listen 80;
server_name _;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
前提:你已经在服务器上 cd console && pnpm build,保证 /opt/cyber-walker/console/dist 存在。
目标:只暴露对外必需端口,把内部服务端口(例如 8000)限制在本机。
推荐策略:
22(SSH)、80/443(HTTP/HTTPS)127.0.0.1:8000,不对公网开放UFW 示例(按需调整):
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw enable
sudo ufw status verbose
如果你的 API 不是只监听 127.0.0.1(不推荐),务必额外限制 8000 端口来源。
建议优先做 HTTPS:控制台登录与 JWT 传输需要 TLS 保护(尤其在非内网环境)。
步骤概览:
示例命令(Ubuntu 常用):
sudo apt update
sudo apt install -y certbot python3-certbot-nginx
# 替换成你的域名与邮箱
sudo certbot --nginx -d your.domain.example \
--non-interactive --agree-tos -m you@example.com
sudo nginx -t
sudo systemctl reload nginx
续期检查:
sudo certbot renew --dry-run
目标:更新代码/依赖/配置时,尽量避免“任务执行中途被打断”与“API/Worker 版本不一致”。
# 1) 停止 worker(避免新任务继续执行)
sudo systemctl stop cyber-walker-worker
# 2) 更新代码(示例:git pull;实际可用你们的发布流程)
cd /opt/cyber-walker
sudo -u cyberwalker git pull
# 3) 更新后端依赖(如 requirements 有变化)
cd /opt/cyber-walker/server
sudo -u cyberwalker ./.venv/bin/python -m pip install -r requirements.txt
# 4) 如有 DB 升级:执行 init_db.sql 或对应 migrate 脚本(按发布说明)
# 注意:这一步属于“有风险操作”,请确保备份与变更评审。
# 5) 重启 API
sudo systemctl restart cyber-walker-api
# 6) 健康检查
curl -sS http://127.0.0.1:8000/api/health
# 7) 启动 worker
sudo systemctl start cyber-walker-worker
# 8) 观察日志
sudo journalctl -u cyber-walker-api -n 50 --no-pager
sudo journalctl -u cyber-walker-worker -n 50 --no-pager
server/.env 权限建议:仅部署用户可读(例如 chmod 600 /opt/cyber-walker/server/.env)JWT_SECRET_KEY / APP_SECRET_KEY 必须替换为随机值,并避免提交到代码库最低要求(建议按组织规范增强):
当你需要快速回答这些问题时,Flower 很有用:
注意:Flower 属于可选组件,默认不随依赖安装。
在运行 Worker 的同一个 venv 中安装(推荐):
cd /opt/cyber-walker/server
sudo -u cyberwalker ./.venv/bin/python -m pip install flower
绑定本机回环地址,避免直接暴露到公网:
cd /opt/cyber-walker/server
# 确保 server/.env 中已经配置 CELERY_BROKER_URL
sudo -u cyberwalker /opt/cyber-walker/server/.venv/bin/python -m celery \
-A app.celery_app flower --address=127.0.0.1 --port=5555
访问方式(推荐二选一):
ssh -L 5555:127.0.0.1:5555 your_server 然后本地打开 http://127.0.0.1:5555强烈建议:Flower 只监听 127.0.0.1:5555,不要直接对公网暴露;外部访问通过 Nginx 受控反代。
sudo apt update
sudo apt install -y apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd_flower admin
/flower/):# Flower (Celery monitoring)
location /flower/ {
# 基本认证
auth_basic "Flower";
auth_basic_user_file /etc/nginx/.htpasswd_flower;
# 可选:再加一层 IP 白名单(推荐内网)
# allow 10.0.0.0/8;
# allow 192.168.0.0/16;
# deny all;
# 反代到本机 Flower
proxy_pass http://127.0.0.1:5555/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket 支持(部分页面/功能可能用到)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 300s;
}
sudo nginx -t
sudo systemctl reload nginx
访问:https://your.domain.example/flower/(会弹 Basic Auth)。
创建 /etc/systemd/system/cyber-walker-flower.service:
[Unit]
Description=Cyber Walker Flower (Celery Monitoring)
After=network.target
[Service]
Type=simple
User=cyberwalker
Group=cyberwalker
WorkingDirectory=/opt/cyber-walker/server
EnvironmentFile=/opt/cyber-walker/server/.env
# 强烈建议只监听 127.0.0.1,再通过 SSH tunnel 或 Nginx 受控反代访问
ExecStart=/opt/cyber-walker/server/.venv/bin/python -m celery -A app.celery_app flower \
--address=127.0.0.1 --port=5555
Restart=always
RestartSec=2
StandardOutput=journal
StandardError=journal
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
[Install]
WantedBy=multi-user.target
启用并启动:
sudo systemctl daemon-reload
sudo systemctl enable --now cyber-walker-flower
sudo systemctl status cyber-walker-flower --no-pager
如果你不想安装 Flower,也可以用 Celery 自带 inspect 做快速排查:
cd /opt/cyber-walker/server
sudo -u cyberwalker /opt/cyber-walker/server/.venv/bin/python -m celery -A app.celery_app status
sudo -u cyberwalker /opt/cyber-walker/server/.venv/bin/python -m celery -A app.celery_app inspect active
sudo -u cyberwalker /opt/cyber-walker/server/.venv/bin/python -m celery -A app.celery_app inspect reserved
sudo -u cyberwalker /opt/cyber-walker/server/.venv/bin/python -m celery -A app.celery_app inspect stats
一般判断思路:
status 看 worker 是否在线active 看是否有卡住的长任务reserved 看是否有明显队列堆积 暂无目录