mahirhacks/traffsucker
GitHub: mahirhacks/traffsucker
一款授权场景下的浏览器化 Web 攻击面映射工具,通过真实浏览器行为捕获流量并构建可分析的应用图谱,填补 URL 发现工具与漏洞扫描器之间的空白。
Stars: 0 | Forks: 0
# TraffSucker
**授权的浏览器 Web 映射工具 (v3.3)** —— 打开真实浏览器,像一个谨慎的人类一样进行探索(BFS + 可选本地 AI),将请求/响应流量捕获为 JSON,构建攻击面图谱,并通过单/多分析进行分类筛选。在开启 Ollama 的情况下,自由格式的 `context` 可以在传输过程中稀疏补丁现有的请求值。
TraffSucker 介于 URL 发现工具(例如 Katana)和漏洞扫描器(sqli / Nuclei / nmap)之间:它映射实时行为和攻击面;它**不会**抓取开放网络或宣称确认的发现。
技术栈:Python 3.12+、Typer、Rich、httpx、Playwright。映射输出**仅限 JSON**。
## 命令
```
traffsucker --help # command list
traffsucker --help --all # full options for every command
traffsucker doctor # local prerequisites
traffsucker scan # map authorized hosts (browser crawl)
traffsucker inspect # filter captured traffic by endpoint
traffsucker analysis # attack-surface triage via local Ollama
traffsucker graph # interactive HTML + AI-readable graph.json
```
## 快速路径
| 目标 | 需要的条件 | 命令格式 |
|------|----------------|---------------|
| **经典映射**(无 AI) | Python + Chromium | `traffsucker scan --url authorized.example --output results/probe` |
| **经典 + AI 排序** | + 本地 [Ollama](https://ollama.com/) | 添加 `--ollama`(任意不错的聊天模型) |
| **仅浏览保真度** | Chromium + 明确授权 | 添加 `--browse-only --profile-mode retained` |
| **任务模式**(目标驱动) | + **Ollama ≥8B**(推荐 14B+)+ 配置中的 `goal:` | `--mission-mode 900` |
| **极限模式**(穷举) | + Ollama;`context` 中的可选凭据 | `--max-mode`(除非 `--max-runtime` 否则时间无限制;耗尽同主机图谱) |
| **通过 Burp** | Burp 监听中(例如 `127.0.0.1:8080`) | 添加 `--burp 127.0.0.1 8080`(经典 / 任务 / 极限;不可与 `--browse-only` 同用) |
| **Web 图谱** | 已完成的映射结果目录 | `traffsucker graph --file results/probe --output results/probe/graph-analysis` |
任务模式(`--mission-mode <秒>`)根据配置驱动目标(登录、聊天、结账等),在不清除 session 状态的情况下链接 SPA 操作,并在发现流量证据时停止 —— 而非凭直觉。
**极限模式**(`--max-mode`)会一直运行,直到同主机页面/操作队列耗尽(可选 `--max-runtime`)。当 `context` 中包含凭据时,它会优先登录,并且**不会**在 `goal_achieved` 时提前停止。不能与 `--mission-mode` 组合使用。使用 `--batch 512`(默认值)可以让长时间运行的程序在 RSS(Python **或** Chromium/Node 子进程)、缓冲区或约 20 个页面超过阈值时,就地追加 `traffic.jsonl` / 合并 `traffic.har` —— 每个检查点都会**重启 Chromium**,这样 driver heap 就不会无限增长。运行中停止的数据依然可用。
**单行命令(任务):** 包含 `goal:` 的配置 + Ollama 14B → `traffsucker scan --config ./config.yaml --url authorized.example --output results/mission --mission-mode 900`
**单行命令(极限):** `traffsucker scan --config ./config.yaml --url authorized.example --output results/max --max-mode`
## 演示证明(来自真实的 `goal_achieved` 运行)
经过脱敏的截图 + 来自本地授权任务(登录 → 控制台 → 聊天 → 发送消息)的 JSON。凭据字段已被掩码处理;JSON 样本中的 host/chat id 已被替换为 `authorized.example`。

| 产物 | 展示内容 |
|----------|----------------|
| [`examples/demo-output/mission-success.png`](examples/demo-output/mission-success.png) | 全尺寸脱敏截图 + 证明条 |
| [`examples/demo-output/manifest.json`](examples/demo-output/manifest.json) | `status: goal_achieved`, `mode: mission`, `actions_executed: 5` |
| [`examples/demo-output/traffic.jsonl`](examples/demo-output/traffic.jsonl) | 登录 API + 聊天 POST + 仅记录外部请求 |
| [`examples/demo-output/actions.jsonl`](examples/demo-output/actions.jsonl) | 登录 → 控制台 → 聊天 → 发送消息 |
```
{
"mode": "mission",
"status": "goal_achieved",
"goal_status_final": "achieved",
"actions_executed": 5,
"target": "https://authorized.example/login"
}
```
## 安全边界
仅在你获得授权测试的系统上使用 TraffSucker。
- 映射探索**仅限于来自你的种子 URL** (`--url` / `--url-file`) 的主机。
- 浏览过程中产生的外部重定向、API 和 WebSocket 会在 `traffic.jsonl` 中被**记录**,但**绝不会**加入页面探索队列。
- 私有/元数据目的地保持被阻止状态。
- 在仅浏览模式下,测试凭据在本地解析以执行精确的登录流程;Ollama 仅接收可用性标志,绝不会接收凭据值。
- 机器人防御或速率限制挑战会停止浏览器上下文。TraffSucker 不会尝试绕过。
## 系统要求
- Python 3.12+
- Playwright Chromium (`python -m playwright install chromium`)
- 可选的本地 [Ollama](https://ollama.com/) 用于操作清单盘点、上下文感知决策和表单填充
- **任务模式:** 隐含开启 Ollama;使用 **≥8B** 的模型(理想情况为 **14B+**)。微小的 3B 模型经常排序不当或返回空的目标检查结果。
## 安装
**pipx(推荐)**
```
python -m pip install --user pipx
python -m pipx ensurepath
pipx install git+https://github.com/mahirhacks/traffsucker.git
python -m playwright install chromium
```
```
python -m pip install --user pipx
python -m pipx ensurepath
pipx install git+https://github.com/mahirhacks/traffsucker.git
python -m playwright install chromium
```
**从本地克隆安装**
```
pipx install .
python -m playwright install chromium
```
```
pipx install .
python -m playwright install chromium
```
## 操作员配置
稳定的设置存放在**本地** `config.yaml` 中(切勿提交此文件):
| 平台 | 默认路径 |
|----------|--------------|
| Linux / macOS | `~/.config/traffsucker/config.yaml` |
| Windows | `%APPDATA%\traffsucker\config.yaml` |
```
mkdir -p ~/.config/traffsucker
cp examples/config.yaml ~/.config/traffsucker/config.yaml
```
```
New-Item -ItemType Directory -Force "$env:APPDATA\traffsucker" | Out-Null
Copy-Item examples\config.yaml "$env:APPDATA\traffsucker\config.yaml"
```
参见 [`examples/config.yaml`](examples/config.yaml)。使用 `--config path/to/config.yaml` 进行覆盖。
在此处配置 Ollama 默认设置和可选的自由格式 **`context`**。Context **仅在开启 Ollama 时使用**(`--ollama`、`ollama.enabled: true` 或 `--mission-mode`);如果没有 Ollama,它将被忽略,表单填充保持确定性(使用 Faker),且不填充密码。
```
ollama:
enabled: true
endpoint: http://127.0.0.1:11434
model: qwen2.5:14b # ≥8B recommended for mission mode
context: |
email: your-test-address@example.com
password: set-this-from-your-local-secret-store
# --mission-mode 运行所需
goal: |
Log in, open dashboard, send one chat message. Avoid purchases.
```
写下任何有助于模型的内容:凭据、角色设定、区域提示。本地模型将 `context` 用于操作排序、风险提示和表单填充(密码仅从 context 获取 —— 绝不凭空捏造)。
对于 `--browse-only`,契约更为严格:凭据值会绕过模型,并且仅对确定性的精确登录填充器可用。注册、常规更改、消息、上传、购买、删除、注销、账户更改、模糊操作以及模型尝试扩大策略范围的行为仍然被禁止。
## 映射工作原理(BFS + AI)
1. 打开浏览器并 GET 每个种子 URL(捕获 HTML + 流量)。
2. 根据 HTML 构建可操作元素的确定性候选池。
3. **去重**会跳过已执行过的签名以及区域/主题噪音重复。
4. 使用 Ollama 时,模型会利用 `context`、可选的 `goal` 和紧凑的运行**记忆**对候选池进行排序;不使用 Ollama 时,会尝试每个候选者,并且忽略 `context`。
5. 逐一执行操作(点击、填写表单/聊天、提交)。记忆会记录结果以供下次决策使用。
6. 将新的同主机 URL 加入 BFS 队列;重复此过程直到队列为空或达到预算限制 / 目标停止。
### 经典 vs 任务 vs 极限模式
| | 经典 | 任务 (`--mission-mode 900`) | 极限 (`--max-mode`) |
|--|---------|-------------------------------|--------------------|
| 目标 | 可选 / 被忽略 | 配置中**必需**的 `goal:` | 配置为空时自动设定目标;从不在 `goal_achieved` 时提前停止 |
| Ollama | 可选 | 隐含开启(**≥8B / 14B+**) | 隐含开启 |
| 停止条件 | 达到 max-pages / actions / depth / runtime **或队列清空** | 挂钟时间预算 + `goal_status` | 队列 + 操作耗尽,或可选的 `--max-runtime` |
| 软上限 | 你设置的 max-* 标志 | pages≤500, actions≤100, depth≤20 | pages≤100000, actions≤5000, depth≤1000 |
| 批处理检查点 | `--batch N` MiB(默认 **512**,`0`=关闭) | 相同 | 相同 —— 就地追加 JSONL / 合并 HAR |
```
# Classic
traffsucker scan --url authorized.example --output results/classic --ollama
# Mission — 探索至目标,直到 budget 或 goal_status 停止
traffsucker scan --config ./config.yaml --url authorized.example --output results/mission --mission-mode 900
# Max — 穷尽同 host 探索(context 中有 creds 时进行 auth;无提前 goal 停止)
traffsucker scan --config ./config.yaml --url authorized.example --output results/max --max-mode
# 可选 wall-clock 上限 + 更严格的 RAM 检查点
traffsucker scan --config ./config.yaml --url authorized.example --output results/max --max-mode --max-runtime 21600 --batch 256
# 路由 Playwright → Chromium → Burp → target(Burp 必须处于监听状态;HTTPS 使用 ignore_https_errors)
traffsucker scan --config ./config.yaml --url authorized.example --output results/max --max-mode --burp 127.0.0.1 8080
```
```
traffsucker scan --url authorized.example --output results\classic --ollama
traffsucker scan --config .\config.yaml --url authorized.example --output results\mission --mission-mode 900
traffsucker scan --config .\config.yaml --url authorized.example --output results\max --max-mode
traffsucker scan --config .\config.yaml --url authorized.example --output results\max --max-mode --burp 127.0.0.1 8080
```
预算(经典模式):`--max-pages`、`--max-actions`(每页)、`--max-depth` 和 `--max-runtime`(秒;默认 600)。
### Burp Suite 代理
经典 / 任务 / 极限映射可以通过 Burp 发送所有 Chromium 流量:
`Playwright → Chromium → Burp (HOST:PORT) → target`
示例:`--burp 127.0.0.1 8080`。TraffSucker 仍会像往常一样捕获 HAR/JSONL 和 AI 决策;Burp 可以看到实时的浏览器流量。HTTPS 通过 Playwright 的 `ignore_https_errors` 工作(Burp 的 MITM 证书)。不能与 `--browse-only` 组合使用(该路径使用 TraffSucker 自己的 SOCKS 范围代理)。必须确保 Burp 已经在监听,否则抓取会在连接时失败。
### 仅浏览模式保真度
仅浏览模式保真度使用一个持久化的 Chromium 上下文、正常的浏览器缓存、启用的 service worker,以及从启动的浏览器中报告的连贯身份。它通过真实的导航、点击、聚焦、悬停、有边界的视口滚动、分页、历史记录、拒绝同意和精确的测试账户登录来发现流量。它不会伪造 DOM 事件、随机化指纹或声称可以逃避自动化检测。
所有浏览器连接都会遍历一个仅限环回的 SOCKS5 范围代理。目标权限被明确授权;范围内页面请求的公共第三方依赖项可能会被记录,但绝不会添加到 BFS 队列中。私有、元数据、模糊 DNS、不允许的端口和超出预算的目的地会直接失败关闭。
保留的配置文件会在多次运行之间保留 cookies、local storage、IndexedDB、service worker 状态和 HTTP 缓存。它们与目标和角色绑定、被独占锁定、存放在本地操作员配置目录下,并且被刻意排除在结果导出和版本控制之外。**请将保留的配置文件目录视为敏感的 session 材料。** 结果产物是经过脱敏审查的材料,但仍应作为敏感测试数据进行处理。
```
python -m traffsucker scan --config .\config.yaml --url https://leadbondhuai.online/ --output results\leadbondhuai-browser-fidelity --max-runtime 600 --max-pages 30 --max-actions 12 --max-depth 5 --browse-only --profile-mode retained --profile-name leadbondhuai-proof --ollama --model llama3.2:3b
python scripts\verify_browser_fidelity.py results\leadbondhuai-browser-fidelity --config .\config.yaml --require-retained --expect-model llama3.2:3b
```
该命令仅用于明确授权的 LeadBondhu 测试账户。当不需要进行无凭据的等价性扫描时,请从验证器中省略 `--config`。
### 操作风险调节 (`--allow-action`)
每个 UI 操作都会获得一个从 **1**(最安全)到 **10**(最危险)的风险分数。调节器允许执行任何等于或低于阈值的操作:
| 值 | 效果 |
|-------|--------|
| `0` 或 `1` | 仅限最安全的导航 |
| `3`–`4` | 普通浏览 + 轻量表单 |
| `5`–`6` | 登录 / 注册 / 密码流程 |
| `8`–`9` | 仍然会阻止大多数破坏性操作 |
| `10` | 执行所有操作(默认) |
你可以调低此参数以进行谨慎的运行。使用 `--ollama` 时,分数可能会受到模型的微调影响。
## 基础用法
```
traffsucker doctor
# 单个 host(允许裸 host) — 默认 allow-action 10
traffsucker scan --config ./config.yaml --url authorized.example --output results/probe --ollama
# 保守模式:仅低风险点击
traffsucker scan --url authorized.example --allow-action 3 --output results/safe
# 多个 seeds(逗号分隔或可重复)
traffsucker scan --url authorized.example,authorized.example/login --output results/seeds
traffsucker scan --url authorized.example --url authorized.example/pricing --max-pages 30
# Katana 风格的 URL 列表
traffsucker scan --url-file links.txt --output results/from-katana --max-runtime 1800 --ollama
```
```
traffsucker doctor
traffsucker scan --config .\config.yaml --url authorized.example --output results\probe --ollama
traffsucker scan --url authorized.example --allow-action 3 --output results\safe
traffsucker scan --url-file links.txt --output results\from-katana --max-runtime 1800 --ollama
```
所有种子 URL 都在深度 0 加入队列。主机仅来自种子列表;浏览期间发现的外部主机仅保持记录模式。
### 输出文件
| 文件 | 内容 |
|------|----------|
| `manifest.json` | 扫描 id、目标、状态、模式、目标、预算、模型 |
| `traffic.jsonl` | 完整的请求生命周期记录、所有权、span 关联、header、时间、缓存/service worker 来源,以及有边界的脱敏正文 |
| `traffic-lifecycles.jsonl` | request-started、response-headers 以及刚好一个终止生命周期事件 |
| `spans.jsonl` | 导航/操作流量集合和有边界的完成原因 |
| `streams.jsonl` | WebSocket、SSE 和长连接流连接元数据 |
| `stream-events.jsonl` | 有边界的脱敏帧/消息,包含方向、字节计数、哈希和省略信息 |
| `proxy-decisions.jsonl` | 无密钥的范围代理允许/拒绝决策和字节计数 |
| `bot-defense-events.jsonl` | 挑战/速率限制证据及由此产生的停止决定 |
| `traffic.har` | 累积的 Playwright HAR(已净化);在上下文关闭后的**每个批处理检查点追加**,并在运行结束时再次追加 |
| `actions.jsonl` | 清单盘点 + 执行结果;去重跳过记录 |
| `pages.jsonl` | 映射的同主机页面 |
| `ai-decisions.jsonl` | Ollama 清单盘点 / goal_status 决策 |
| `memory.jsonl` | 紧凑的运行记忆事实 |
| `screenshots/` | 每个映射页面对应一张截图 |
## 映射后命令
在 `scan` 之后,使用:
```
traffsucker doctor
traffsucker inspect --file results/latest --endpoint /api/profile
traffsucker inspect --file results/latest --endpoint /api/profile --output results/latest/inspect-profile.json
# Attack-surface 分诊(本地 Ollama)
traffsucker analysis --triage-single --file results/latest/traffic.har --output results/latest
traffsucker analysis --query IDOR 5 --file results/latest --table
# Graphify 风格的交互式地图 + AI 可读 graph
traffsucker graph --file results/latest --output results/latest/graph-analysis
traffsucker analysis --multi-analysis results/latest/graph-analysis/graph.json --output results/latest
```
```
traffsucker doctor
traffsucker inspect --file results\latest --endpoint /api/profile
traffsucker inspect --file results\latest --endpoint /api/profile --output results\latest\inspect-profile.json
traffsucker analysis --triage-single --file results\latest\traffic.har --output results\latest
traffsucker analysis --query IDOR 5 --file results\latest --table
traffsucker graph --file results\latest --output results\latest\graph-analysis
traffsucker analysis --multi-analysis results\latest\graph-analysis\graph.json --output results\latest
```
### 分析(单分类筛选 / 多分类筛选)
`analysis` 执行基于本地 Ollama 的被动攻击面分类。类别标记的是渗透测试人员应
探测的表面(例如 `?id=287` → IDOR 表面),而不是已确认的漏洞。
`potential` 表示探测优先级。产物存放在 `single-triage/` 或
`multi-triage/` 下(`vuln-cat-2` schema)。
Ollama 默认值:`http://127.0.0.1:11434`。参见 [`docs/analysis.md`](docs/analysis.md)。
### 图谱
`graph` 为已完成的映射结果构建一个 Graphify 风格的视图:
| 文件 | 用途 |
|------|---------|
| `graph.html` | 交互式 vis-network 地图(在浏览器中打开) |
| `graph.json` | 节点/边/社区以及用于多分类筛选的攻击面 / 链条包 |
| `GRAPH_REPORT.md` | 简短的人类可读摘要 + 建议的问题 |
CDN/分析主机已被过滤;上帝节点优先选择目标主机和高连通性的应用页面/端点。建议写在 `graph-analysis/` 下。参见 [`docs/graph.md`](docs/graph.md)。
## 限制
- 外部主机仅限记录 —— 绝不进行 BFS 探索。
- 滚动、悬停、聚焦、分页和历史记录是有边界的确定性原语;其覆盖范围不等同于无约束的手动浏览。
- 封闭的 shadow DOM、被拒绝/跨源的 frame、浏览器内部流量以及不支持的加密应用 payload 可能会被省略,并被报告而非凭空捏造。
- WebSocket/SSE/文本流 payload 预览是有边界的。空的 stream 产物意味着 `not_observed_live`,而不是该站点没有流协议。
- 机器人挑战和速率限制会停止保真度上下文;它们绝不会绕过。
- 覆盖范围受页面、操作、深度和运行时间的边界限制。
- 任务质量取决于本地模型大小(≥8B / 14B+)。
## 本地开发
```
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\Activate.ps1
python -m pip install -e ".[dev]"
python -m playwright install chromium
cp examples/config.yaml ~/.config/traffsucker/config.yaml
```
根目录下的 `config.yaml` 和 `results/` 已被 gitignore —— 请将密钥和扫描输出排除在仓库之外。
## 验证
单元和属性测试已在此仓库中发布:
```
python -m pip install -e ".[dev]"
python -m pytest tests/unit tests/property -q
```
集成 / 浏览器 / Postgres 支持的测试位于 `tests/integration` 下,除非你配置了本地数据库和 Playwright fixture,否则这些测试将被跳过。CI 运行单元测试 + 属性测试套件。
## 延伸阅读
- [`docs/analysis.md`](docs/analysis.md) — 攻击面分类筛选 (`analysis`)
- [`docs/harness.md`](docs/harness.md) — 底层请求值补丁层(开启 Ollama)
- [`docs/graph.md`](docs/graph.md) — Web 图谱 (`graph`)
- [`docs/exports.md`](docs/exports.md) — 产物 / 原始捕获说明
- [`examples/demo-output/`](examples/demo-output/) — 任务产物示例
- [`SECURITY.md`](SECURITY.md) — 授权与脱敏
- [`CONTRIBUTING.md`](CONTRIBUTING.md) — 开发工作流
- [`CHANGELOG.md`](CHANGELOG.md) — 发布说明
- [`LICENSE`](LICENSE)
标签:AI风险缓解, Blue Team, CISA项目, Playwright, Python, 攻击面测绘, 无后门, 流量抓取, 特征检测, 自动化爬虫, 运行时操纵, 逆向工具