xD4O/bnb-table
GitHub: xD4O/bnb-table
一款本地托管的「Backdoors & Breaches」应急响应卡牌游戏桌面应用,支持局域网多人协作和单人 AI 对战两种模式。
Stars: 0 | Forks: 0
# Backdoors & Breaches — 本地多人 + 单人 RPG
一个本地托管的 [Backdoors & Breaches](https://www.blackhillsinfosec.com/projects/backdoorsandbreaches) 桌面
(Black Hills InfoSec 推出的应急响应卡牌游戏,基于 Creative Commons 协议发布),
提供两种游玩方式:
- **团队模式(局域网多人):** 一名 Game Master 秘密持有 4 张**攻击链**卡牌;
Defenders 投掷 d20 骰子进行检测;Viewers 进行旁观。当团队发现卡牌时,其实时展示。
- **单人模式(对战 AI Incident Master):** 一名分析师对战电脑。本地 LLM
(Ollama)像 RPG 一样叙述整个事件 —— 开场场景、程序失败的原因
(“EDR 许可证已过期,且那些日志从未被转发”),以及每次成功揭示了什么,
并提示下一步行动。
隐藏目标的保证在**服务端强制执行**:未揭示的攻击卡牌(以及
检测地图和其他玩家的聊天记录)绝不会发送给不该看到它们的客户端。
需要 **Node 18+**(使用原生 `fetch`/WebSocket 流)。单人模式叙述还
额外使用了本地 [Ollama](https://ollama.com/) 模型,但在未安装的情况下也能平稳降级。
## 设置说明
```
git clone https://github.com/xD4O/bnb-table.git
cd bnb-table
npm install
npm run fetch-cards # one-time: downloads official Core v3.1 + Expansion art (~56MB)
npm start
```
启动时,服务器会打印所有的 URL、Game Master PIN 以及叙述模型:
```
Players / Viewers: http://localhost:3000/
on your network: http://192.168.1.42:3000/ <- share on Wi-Fi
Game Master: http://localhost:3000/gm
Solo (vs AI IM): http://localhost:3000/solo
How-to-Play guide: http://localhost:3000/help
Game Master PIN: 7421 (random — set BNB_PIN to fix it)
Narrator (Ollama): qwen2.5:7b @ http://localhost:11434 (falls back to templates if offline)
```
### 环境变量
| 变量 | 默认值 | 用途 |
|-----|---------|---------|
| `PORT` | `3000` | HTTP/WS 端口 |
| `BNB_PIN` | 随机 4 位数字 | 固定的 Game Master PIN |
| `BNB_DECK` | `CoreV3.1` | 起始卡组 |
| `BNB_OLLAMA_URL` | `http://localhost:11434` | 用于单人叙述的 Ollama endpoint |
| `BNB_OLLAMA_MODEL` | `qwen2.5:7b` | 用于叙述单人模式的模型 |
```
BNB_PIN=1234 PORT=8080 BNB_OLLAMA_MODEL=llama3.1:8b npm start
```
刚接触这款游戏?打开 **`/help`** 查看应用内的玩法指南(角色、设置、规则、单人模式)。
## 界面
UI 采用了极具凝聚力的“SOC 命令控制台”主题:动画网格背景上的玻璃拟态面板,Rajdhani / JetBrains-Mono 字体搭配,HUD 风格的追踪栏,颜色编码且在揭示时会发光的攻击链“案件档案”卡牌,高级的动画 d20 骰子,点击放大卡牌,以及一致的悬停/聚焦状态。向下兼容响应至手机端;离线状态下 Web 字体会平稳降级为系统字体。页面包括:`/`(玩家/观众),`/gm`,`/solo`,`/help`。
## 角色与人数(团队模式)
| 角色 | URL | 能看到隐藏的攻击链吗? | 可执行操作? | 容量 |
|------|-----|--------------------|----------|----------|
| Game Master | `/gm` (PIN) | 是 | 完全控制 | 最多 2 人 |
| Defender | `/` | 否(直到被揭示) | 掷 d20,选择程序,聊天 | 1–5(一支队伍) |
| Viewer | `/` | 否 | 观看,聊天(仅限观众频道) | 无限制 |
在低于最低玩家数限制时,GM 依然可以点击 **Force start**(用于测试/演示)。
## 游玩 — 团队模式
1. **GM** 打开 `/gm`,选择一副卡组,然后点击 **Randomizes** 随机生成或手动构建场景:
- **attack chain**(一张 Initial Compromise / Pivot & Escalate / C2 & Exfil / Persistence 卡牌);
- 4 个 **Established** 程序;
- 可选的 **detection map**(指定哪些程序可以检测到每张攻击卡牌 —— 参考卡牌原图),用于启用自动揭示;
- **rules**(全部可由 GM 编辑,具有默认值):回合限制 `10`,成功阈值 `≥14`,加在掷骰结果上的 **Established 奖励 `+3`**,在 `3` 次失败后触发 inject 提示,**cooldown `3` 回合**。
2. **Defenders** 选择一个程序并 **roll d20**(结果骰子会有动画)。Established 的 d20 结果将播放动画。总点数为 `d20 + Established 奖励 (如果处于 Established 状态) + 修正值`,达到阈值即算成功 —— 因此在使用经典默认设置(`+3`,阈值 `14`)时,Established 程序实际上只需要掷出 11+,其他则需要 14+,其中 `+3` 会可见地加到掷骰结果中。系统还提供了一个 `±modifier` 字段,负数的 inject 修正值会从总数中扣除(包含奖励)。
3. 成功时的 **检测 / 揭示**:
- 有 detection map 时:匹配的卡牌自动揭示;如果有多张匹配,系统会提示 GM 进行选择;如果均不匹配,则不揭示任何卡牌;
- 无 map 时:如果只剩下一张卡牌则自动揭示,否则由 GM 挑选。
4. **Cooldown:** 在掷过某个程序后,该程序将被锁定 *N* 个回合(默认 3 回合,可由 GM 编辑,0 = 关闭);冷却中的卡牌会显示 ❄ 标记,并在掷骰选择器中被禁用。
5. **Injects:** 由 GM 打出 Inject 卡牌(在连续 3 次失败后 UI 会进行提示)。**掷出自然 1 或 20 会自动打出一张 Inject**。一张 inject 可以携带一个 **standing roll modifier**(例如“所有程序 -3”),由 GM 进行设置 —— 随后它将应用于之后的每一次掷骰,直到被清除。
6. **Consultants:** GM 会向团队发放一次性的 Consultant 协助。
7. **Chat:** Defenders 在 **team** 频道聊天;Viewers 在 **viewers** 频道聊天;GM 可以看到两个频道并进行发言。Viewers 永远看不到 team 的聊天记录,反之亦然。
8. 当所有 4 张攻击卡牌被检测到时 **Win**。若首先耗尽回合限制则 **Lose**。
点击任意卡牌(objective、procedure、inject、consultant)可在灯箱中放大查看。
## 游玩 — 单人模式
打开 `/solo`,输入名称和可选的场景风格(“一家地区性医院”、“一家金融科技初创公司”),然后点击 **Begin**。服务器将会:
- 生成随机的 attack chain + established procedures 并立即开始(你是 Defender;系统是你的 Incident Master);
- 在点击 **Begin** 时,AI 会叙述 **opening scene**;
- 每回合你选择一个程序并掷骰。**成功**将按顺序检测到攻击链的下一阶段,AI 会叙述**你的发现**并提示下一步;**失败**则会得到一个符合游戏世界观的合理**理由**解释为何一无所获;inject 和输/赢状态也会被加以叙述。
每个事件都会获得一份**全新的随机简报** —— 行业、threat actor、tooling,以及一组一致的 IOC(attacker IP、C2 domain/port、file hash、compromised account、host、CVE、MITRE ATT&CK techniques)—— 讲述者会将这些元素贯穿整个故事。结合随机的模型种子和持续累积的故事进展,没有哪两次游戏会以相同的方式被叙述。可以在开始界面选择叙述模型。
单人模式的进展是确定性的,因此**即使 Ollama 没有运行**,游戏也完全可玩 —— 叙述将退回到填充了 IOC 的模板中(每次游戏依然会随机化)。`↺ New incident` 可开启全新场景。
## 项目结构
```
server.js HTTP static + WebSocket; team room + per-player solo rooms; role-filtered
broadcasts; solo narration hooks
src/game.js Pure game logic (state machine, redaction, rules, solo mode) — unit-tested
src/narrator.js Ollama client + offline fallback templates for solo narration
test/game.test.js node:test suite (35 tests)
scripts/fetch-cards.js Downloads official card data + art into assets/
src/scenario.js Randomized per-incident IOC brief for solo narration
public/ index.html · app.js (team) solo.html · solo.js (solo)
help.html (How-to-Play guide) styles.css (design system)
assets/decks// carddb.json + card PNGs (git-ignored; regenerate with fetch-cards)
```
使用 `npm test` 运行测试。测试覆盖率包括 objective 脱敏、roll 阈值、
cooldown、检测驱动/单人模式的揭示、自然掷出 1/20 的自动 inject、激活的 roll modifier、
聊天频道可见性、人数上限以及输/赢状态转换。
## 致谢与版权声明
**Backdoors & Breaches** 由 **Black Hills Information Security** 创建,基于
Creative Commons 协议免费发布。这是一个围绕这些卡牌构建的**非官方**粉丝自制本地桌面应用,
与 Black Hills InfoSec 没有任何附属关系或受其认可。
- **卡牌数据与美术资源**将在构建时通过 `scripts/fetch-cards.js` 从官方的
[B&B web engine](https://play.backdoorsandbreaches.com/) 下载。其美术资源
**并未在本仓库中重新分发**(`assets/decks/` 已被 git 忽略) —— 每位用户需自行获取,
其版权依然归 Black Hills InfoSec 所有,并遵循其 Creative Commons 条款。
- **单人模式叙述**由本地 [Ollama](https://ollama.com/) 模型生成。
本仓库中的应用程序**代码**按“原样”提供,仅供本地/个人使用。请
尊重 Black Hills InfoSec 对游戏及其卡牌的许可要求。
标签:AI风险缓解, GNU通用公共许可证, LLM评估, MITM代理, Node.js, Ollama, WebSocket, 依赖分析, 多人联机, 多模态安全, 数据可视化, 本地部署, 桌面游戏, 自定义脚本