atk0309/project_ZeroDay

GitHub: atk0309/project_ZeroDay

一套基于 TypeScript/Fastify 构建的 ARG 风格顺序解谜竞赛平台,专为小规模黑客主题教育活动设计,集成了闯关引擎、反作弊系统和管理后台。

Stars: 1 | Forks: 0

``` ███████╗███████╗██████╗ ██████╗ ██████╗ █████╗ ██╗ ██╗ ╚══███╔╝██╔════╝██╔══██╗██╔═══██╗██╔══██╗██╔══██╗╚██╗ ██╔╝ ███╔╝ █████╗ ██████╔╝██║ ██║██║ ██║███████║ ╚████╔╝ ███╔╝ ██╔══╝ ██╔══██╗██║ ██║██║ ██║██╔══██║ ╚██╔╝ ███████╗███████╗██║ ██║╚██████╔╝██████╔╝██║ ██║ ██║ ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ s e q u e n t i a l h a c k e r h u n t ``` ![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/99/993938d8ce5e902ccfb9d6747725c320d855dea3235ed9a304cedf0d94c9321f.svg) ![Node](https://img.shields.io/badge/node-24_LTS-43853d) ![TypeScript](https://img.shields.io/badge/typescript-7.x-3178c6) ![Fastify](https://img.shields.io/badge/fastify-5.x-000000) ![SQLite](https://img.shields.io/badge/sqlite-better--sqlite3-003b57) ![License](https://img.shields.io/badge/license-MIT-yellow.svg) ![Status](https://img.shields.io/badge/status-prelaunch-39ff14)
# ZeroDay ARG — 顺序黑客狩猎 一个面向约 10–30 名 11/12 年级学生的多子域名 ARG 风格黑客寻宝游戏。剧情融合了**《黑客帝国》**、**《黑客》(1995)** 和**《战争游戏》**,并带有真实的黑客传奇色彩(Mitnick、Poulsen、Torvalds 等)。玩家将被招募进一个神秘的组织,必须通过 19 项试炼才能“攻破 GIBSON”。 ## 游戏玩法 **顺序试炼。** 每位玩家每次推进一个阶段 —— 只有在解决第 N 项后,第 N+1 项才会开启。卡住太久?管理员可以手动帮他们跳过某个阶段;排行榜会用 `⚠` 标记这种辅助。 **D-Day 倒计时。** 整个体验由一个巨大的终端绿倒计时时钟驱动。发布前,它会倒数至 **GIBSON GOES LIVE**;在 T-0 时,它会翻转倒数至 **GIBSON GOES COLD**。当第二个计时器归零时,排行榜将冻结,最终挑战将永远锁定。 **随时招募,D-Day 前进入受限大厅。** 注册 + magic-link 会立即生效。在正式发布前,被招募的操作员会看到一个 CRT 主题大厅,其中包含倒计时、邀请名额、同期学员墙以及带有氛围感的 `tail -f` 效果 —— 没有任何挑战列表。在 T-0 时,该页面会过渡到中心枢纽。 **操作员发放邀请。** 每位操作员会获得两个邀请名额(可配置)。待处理和已接受的邀请会占用名额;撤销或过期则会释放名额。Token 将在 72 小时后失效。需要第三个名额?请询问管理员 —— 控制台中有一个包含批准/拒绝操作的请求流程。 **玩家专属 flag。** 每个 flag 都会根据用户专属的 salt 进行 HMAC 处理。在操作员之间共享 flag **不会**共享访问权限 —— Bob 的提交 endpoint 会拒绝 Alice 的 flag。两次提供 flag 会导致提供者被冻结;一次使用他人的 flag 会导致使用者被冻结。 **控制台驱动所有设置。** 运行时的值不需要配置 `.env`。操作员访问 `/admin`,通过一个故意设计得很古怪的、点击 5 次空字段的彩蛋来设置引导密码,然后通过 UI 配置启动/结束时间戳和邮件子系统(Resend 或 SMTP)。 ## 快速开始 ``` # 前提条件:Node 24 LTS 以及 Python 3、make,和用于 # 原生 Argon2 和 SQLite 模块的 C++ 编译器。Docker 可以避免使用本地 toolchain。 git clone https://github.com/atk0309/project_zeroday cd project_zeroday npm ci cp .env.example .env # 编辑 .env — 运行时只需要关心 SESSION_SECRET、FLAG_SECRET 和 PUBLIC_ORIGIN。 npm run migrate # create SQLite schema + seed challenge registry npm run dev # tsx watch on port 3000 # 在另一个 terminal 中: open http://localhost:3000/admin # initialize the game (see docs/operator.md) ``` 通过 Caddy + Docker Compose 的生产环境部署位于 `ops/` 目录中 —— 请参阅 [`docs/operator.md`](docs/operator.md)。Railway 托管文档请见 [`docs/hosting-railway.md`](docs/hosting-railway.md)。 ## 项目结构 ``` app/src/ challenges/ registry.ts # the 19 challenges, ordered 1 → 19, with metadata types.ts # ChallengeModule interface handlers/ index.ts # id → handler module mapping; stub fallback stub.ts # placeholder for unauthored challenges *.ts # one file per authored puzzle cron/dripHints.ts # 09:00 stuck-detection job db/ index.ts # SQLite singleton + path resolution schema.sql # tables (users, challenges, solves, app_settings, …) migrate.ts # apply schema + additive ALTERs + seed registry lib/ adminAuth.ts # admin sessions, password, magic-link audit.ts # admin_audit_log writer cheat.ts # strike system, dossiers, admin recovery cheatDetect.ts # shape-gated flag-supplier reverse lookup content.ts # email + lobby copy (seeded defaults, token interp) flags.ts # generateFlag(user, challengeId) — HMAC, per-player salt gibson.ts # GIBSON key fragments + status for the setup panel hints.ts # cost curve + labels invitations.ts # operator invite quota, claim flow, sweep inviteRequests.ts # operator → admin extra-slot requests mail.ts # Resend + SMTP wrapper, env-seed phase.ts # uninitialized | prelaunch | live | frozen playerAuth.ts # signup, magic-link, sessions progress.ts # ordinal advance + admin skip (transactional) settings.ts # app_settings cache (30s TTL, write-through) middleware/ adminAuthMiddleware.ts playerAuthMiddleware.ts # loadPlayer / requirePlayer / enforcePlayerState routes/ admin/login.ts # the 5-click easter egg + 3-mode login admin/setup.ts # first-run wizard (timing, review) + /admin/account (password, sessions, mail) admin/dashboard.ts # KPIs, players, hints, audit, JSON drawer API admin/templates.ts # email + lobby copy workspace admin/invitations.ts # admin JSON API + public /claim/:token hub.ts # main player terminal at hack.example.com lobby.ts # operator-side invite endpoints leaderboard.ts # /board + /api/leaderboard recruit.ts # red/blue pill landing submit.ts # POST /api/submit, advances current_ordinal strikeNotice.ts # /strike-notice (supplier) + /frozen (consumer) privacy.ts # GET /privacy — cookie + analytics disclosure server.ts # Fastify bootstrap, host-based subdomain dispatch, consent-banner onSend hook app/test/ # vitest — see "Testing" below assets/ # author-side puzzle assets, NOT served via /static (e.g. c17/cover.png) ops/ # Caddyfile, docker-compose.yml, Dockerfile scripts/check-base.mjs # pretest guard: refuse stale-branch test runs tools/ # author helpers (stego-encode.py for #17, …) web/views/ admin/ # login, setup, account, dashboard (dense + narrative), # players, feed, hints, _topbar / _sidenav / _drawer / _head # _players_invitations / _requests / _emails tabs hub.ejs / lobby.ejs / leaderboard.ejs / locked.ejs uninitialized.ejs / manual.ejs # hub.ejs covers live + frozen + completed recruit-step1.ejs / recruit-decide.ejs / recruit-step2.ejs / recruit-blue.ejs claim.ejs / claim-dead.ejs # invitation claim flow account-frozen.ejs / strike-notice.ejs # anti-cheat takeover screens privacy.ejs # /privacy — cookie + analytics disclosure web/static/ terminal.css + terminal.js # lobby/hub/leaderboard UI (countdown, polling) recruit-flow.css + recruit-flow.js # CRT recruit theme + typewriter / boot violation.css # cheater + supplier vocabulary (klaxons, dossier) admin.css # operator-grade CRT vocabulary admin.js # drawer fetch, hint dropdowns, 5s feed polling consent.css + consent.js # cookie-consent banner + Clarity gate (injected on public pages) .github/ # CI, Dependabot, issue forms, pull-request template docs/ # operator + challenge-authoring + hosting guides ``` ## 技术栈 - **运行时**:Node 24 LTS、TypeScript (ES modules) - **Web**:Fastify 5 + `@fastify/{cookie, formbody, view, static, rate-limit}` - **DB**:通过 `better-sqlite3` 实现的 SQLite(同步模式,对于约 30 名并发玩家来说性能完全足够) - **模板**:通过 `@fastify/view` 实现的 EJS - **Auth**:使用 argon2id 作为管理员密码;使用 HMAC-SHA256 作为玩家专属 flag - **邮件**:Resend (HTTP API) 或 SMTP (nodemailer) —— 在运行时通过管理员控制台进行选择 - **Cron**:`node-cron` (09:00 卡顿检测) - **测试**:结合 `app.inject()` 进行端到端 HTTP 测试的 vitest 4 - **运维**:Caddy(通过 Cloudflare DNS-01 实现泛域名 TLS)+ Docker Compose,或者 Railway ## 测试 ``` npm run check # type check + vitest; pretest runs check-base.mjs npm run build # emit production JavaScript npm run audit # fail on high/critical dependency advisories npm run test:watch # interactive CHECK_BASE_SKIP=1 npm test # bypass the "is your branch behind dev?" guard ``` 如果当前的 `claude/*` 分支落后于 `origin/dev`,`scripts/check-base.mjs` 将判定测试运行失败。CI 会设置 `CI=true`,因此该检查在那里会被跳过。在新会话中的经验法则:首先在 `origin/dev` 上进行 rebase,然后再进行编辑。 CI 会在 Node 24 LTS 上重复执行锁定的安装、审计、类型检查和测试套件, 然后构建生产容器并进行 HTTP 冒烟测试。第三方 Actions 和生产镜像均被固定为不可变的摘要;Dependabot 会针对 `dev` 提出兼容的更新建议。 ## 状态 | 组件 | 状态 | |---|---| | 顺序引擎 | ✅ | | D-Day 阶段状态机 + 倒计时 | ✅ | | 玩家专属加盐 flag 引擎 | ✅ | | 管理员引导(5 次点击彩蛋) | ✅ | | 管理员登录(3 种模式:未初始化 / 密码已设置 / 邮件已配置) | ✅ | | 管理员设置向导(时间设置、审查) | ✅ | | 管理员仪表板 —— 密集的运维数据 + 剧情变体(cookie 切换) | ✅ | | 玩家详情抽屉(`GET /admin/api/player/:id`) | ✅ | | 玩家列表上的搜索 + 仅卡顿过滤器 | ✅ | | KPI 迷你图(活跃 <1 小时、提交/小时) | ✅ | | 实时 feed 轮询(`GET /admin/api/events?since=`,5 秒间隔) | ✅ | | 每行提示下拉菜单(L1–L5,可编辑正文,带有审计标签) | ✅ | | 反作弊检测 + 2 次警告系统 + 管理员恢复 | ✅ | | 作弊者接管 + 供应商“我们注意到了”体验 | ✅ | | 管理员账户页面 —— 密码轮换 + 会话 + 邮件 | ✅ | | 每个会话的撤销(`POST /admin/account/sessions/:id/revoke`) | ✅ | | 玩家 magic-link auth + 会话 | ✅ | | 大厅 / 中心枢纽 / 锁定 / 冻结 / 未初始化视图 | ✅ | | 排行榜(阶段 X/19 + 积分 + ⚠) | ✅ | | 滴漏提示 cron(仅排队;仍需管理员点击) | ✅ | | 招募落地页(红/蓝药丸,记忆消除告别) | ✅ | | 位于 `/manual` 的操作员手册 | ✅ | | 邀请后端 —— 操作员名额、认领流程、管理员覆盖、请求 | ✅ | | 邮件模板工作区(6 个系列 + 大厅风味,实时预览,测试发送) | ✅ | | Caddyfile + docker-compose | ✅ | | Railway 托管文档(生产环境 + 模拟环境) | ✅ | | **已创作的挑战** | 事实来源:`handlers/index.ts` 中的 `authoredChallengeIds()`。全部 19 个已创作。存根处理程序保留为引擎后备。 | | GIBSON 关键部分 | `lib/gibson.ts` 中的 `gibsonKeyStatus()`。全部 3 个已连接(#7、#13、#17)并被 #19(`hack-the-planet`)使用。 | | OSINT 页面 (#18) | ✅(`ghost-shell` —— `mitnick.example.com/staff` 上的每个玩家专属剧情秘密,通过 `/robots.txt` 提供面包屑导航) | | Git repo seed (#16) | ✅(`tools/git-seed.sh` 将规范秘密植入公共仓库的历史记录中) | | 学员矩阵视图(操作员 × 试炼热力图) | 延期 | | `tools/stego-encode.py` | ✅(覆盖图生成 + 参考编解码器) | 如需查看实时测试计数,请运行 `npm test` —— vitest 会进行报告。 ## 更多文档 - [`CLAUDE.md`](CLAUDE.md) —— 不变量、陷阱、代码路径。**对于接手此仓库的 AI 助手来说是必读内容**。 - [`docs/operator.md`](docs/operator.md) —— 首次运行设置、邮件、跳过卡顿玩家、邀请、冻结、恢复 - [`docs/authoring-challenges.md`](docs/authoring-challenges.md) —— 如何编写新的挑战模块 - [`docs/hosting-railway.md`](docs/hosting-railway.md) —— Railway 上的生产环境 + 模拟环境,Cloudflare 泛域名 TLS ## 许可证 该项目基于 MIT 许可证授权 —— 请参阅 [`LICENSE`](LICENSE)。 版权所有 (c) 2026 atk0309
标签:ARG游戏, Fastify, MITM代理, SQLite, TypeScript, 安全插件, 版权保护, 自动化攻击, 黑客游戏