AbhiramVSA/Consensus-KoTH

GitHub: AbhiramVSA/Consensus-KoTH

一个基于仲裁共识机制的分布式攻防山丘网络靶场平台,解决多节点环境下挑战所有权验证和公平计分问题。

Stars: 0 | Forks: 0

# Consensus KoTH Consensus KoTH 是一个分布式的 King of the Hill (攻防山丘) 网络靶场,具备集中式裁判、基于仲裁的所有权验证、复制的挑战节点,以及用于生命周期控制、计分、健康验证和恢复的操作员工具。 它专为那些不能仅凭单次写入单台机器就宣布所有权的活动而构建。选手仍然需要攻破服务并将他们的队伍名称写入 `/root/king.txt`,但只有当裁判在各个副本中收集到足够健康的证据来信任该声明时,才会进行积分奖励。 - 生产运行时是位于 `referee-server/` 目录下的分布式裁判管理模型,以及位于 `node1/node2/node3` 上的节点本地 `h1..h8` 目录。 - `Series HN/docker-compose.yml` 文件是按系列部署的制品,会被复制到节点本地的 `hN/` 目录中,并在系列激活前由裁判进行验证。 - 根目录下的 `docker-compose.yml` 和 `rotate.sh` 仅限本地/开发使用的制品,绝不能被视为生产控制平面。 - 操作员应使用 `/api/runtime`、`/api/recover/validate` 和 `/api/recover/redeploy` 进行运行时检查和恢复。 - 仪表板现在包含了管理员团队控制功能:创建团队、手动封禁团队和手动解封团队。新的团队名称必须满足与 `king.txt` 所有权相同的声明规则,因此诸如 `unclaimed` 等保留字或格式错误的名称将被拒绝。 - `:9000` 上的公开参赛者面板现在显示当前的访问窗口、组织者公告、硬性规则、实时排行榜以及领先团队的累计积分图。 - `:8000` 上的管理仪表板现在会渲染完整的团队表格,而不是截断显示前 25 支队伍。 - 手动测试执行指南:[docs/manual-tester-checklist.md](docs/manual-tester-checklist.md) - 裁判规则验证指南:[docs/referee-rule-validation-checklist.md](docs/referee-rule-validation-checklist.md) - 独立的攻击者风格 Codex 提示词:[docs/codex-h1a-player-prompt.md](docs/codex-h1a-player-prompt.md) ## 为什么会有这个项目 传统的 KoTH 基础设施通常假设一个目标、一个所有者,并采用简单的“最后写入获胜”或“首个稳定所有者获胜”模型。一旦你引入以下情况,这种模型就会失效: - 多个挑战节点 - 它们前方的负载均衡器 - 复制延迟或不同的本地状态 - 主机或容器健康状态漂移 - 活动进行中的操作员恢复 Consensus KoTH 通过赋予裁判绝对权威来解决这一问题。节点负责暴露服务;而由裁判决定所有权何时生效。 ## 核心能力 - 跨三个挑战节点的分布式挑战运行时 - 负责计分、生命周期、验证和恢复的中央裁判 - 基于仲裁的所有权接受机制,取代单节点信任 - 跨 `H1` 到 `H8` 的自动化系列轮换 - 感知 HAProxy 的路由和后端状态可见性 - 面向操作员的管理仪表板和面向选手的独立参赛者面板 - 具备封禁/解封控制和声明名称验证的团队管理 - 用于验证和受控重新部署的恢复 API - 协议感知的 QA 套件,用于负载检查和安全的漏洞验证 - 详细的部署运行手册和验证清单 ## 安全提示 本仓库包含故意设置漏洞的服务以及针对它们执行真实漏洞探测的工具。 仅将其用于: - 自有的实验室环境 - 授权的培训练习 - 私人或经批准的竞赛 请勿将其部署在您无法控制的基础设施上。 ## 所有权运作机制 Consensus KoTH 不是简单的文件写入竞速。计分流程如下: 1. 选手攻击当前暴露的公共挑战端口。 2. 成功的选手获取 root 权限,并将其确切的队伍名称写入 `/root/king.txt`。 3. 裁判按固定间隔轮询每个活跃变体的所有健康副本。 4. 裁判过滤掉无效、过时、格式错误或不健康的观测结果。 5. 只有当该声明在健康节点中达到仲裁数量时,新所有者才会被接受。 6. 一旦被接受,该所有者即成为该变体的权威所有者。 7. 只要被接受的所有者保持仲裁优势,该团队就会在每个轮询周期获得积分。 8. 如果副本出现分歧,裁判可以将已接受的所有权协调回健康节点。 这种设计使得所有权在部分故障下具有持久性,并且在日志中是可防御的。 ## 系统架构 典型的生产拓扑结构: ``` Players | v HAProxy + Referee Host |- FastAPI admin dashboard (:8000) |- Participant board (:9000) |- Scheduler / scorer / recovery logic |- SQLite runtime state | +----> node1 +----> node2 +----> node3 |- active series containers |- per-series docker-compose.yml |- local king.txt observations ``` 重要的运行时属性: - 一个裁判进程拥有控制平面和计分板。 - 三个挑战节点托管当前活跃的系列。 - HAProxy 仅暴露活跃的公共服务。 - 裁判通过 SSH 与节点通信。 - 状态持久化在 SQLite 中,以便运行时意图在重启后得以保留。 - 恢复是显式的:先验证,再慎重重新部署,仅在健康状态恢复后才继续执行。 ## 活动结构 活动分为八个系列: - `H1` - `H2` - `H3` - `H4` - `H5` - `H6` - `H7` - `H8` 每个系列包含三个机器变体: - `A` - `B` - `C` 这使得在整个活动中总共有 24 个挑战目标。 ## 挑战矩阵 每台机器都有一个初始访问向量和一个权限提升路径。 | 机器 | 端口配置 | 初始向量 | 权限提升向量 | |---|---|---|---| | `machineH1A` | `10001` | WordPress Reflex Gallery RCE | SUID `/usr/bin/find` | | `machineH1B` | `10002` | Redis 未授权访问 | 写入 SSH 密钥到 `/root/.ssh/` | | `machineH1C` | `10004` | PHP ping 命令注入 | SUID `/usr/local/bin/net-search` | | `machineH2A` | `10010` | Jenkins Script Console | 无密码 `sudo python3` | | `machineH2B` | `10011` | PHP SQL 注入 | MySQL FILE/UDF 权限 | | `machineH2C` | `10012` | Tomcat 默认凭据 | PwnKit | | `machineH3A` | `10020` | SMB 匿名共享泄露 SSH 密钥 | `lxd` 容器逃逸 | | `machineH3B` | `10022` | Drupalgeddon2 | 可写的 root cron `tar *` 路径 | | `machineH3C` | `10023` | 暴露的 `.git` 泄露应用凭据 | 带有 `cap_setuid` 的 `/usr/bin/perl` | | `machineH4A` | `10030` | Node.js 反序列化 | 备份中的明文 root 密码 | | `machineH4B` | `10031` | Spring4Shell | `.bash_history` 中的 root 密码 | | `machineH4C` | `10032` | 针对内部 API 的 SSRF | 内部 root API 命令执行 | | `machineH5A` | `10040` | Webmin RCE | 直接以 root 执行 | | `machineH5B` | `10041` | ElasticSearch 动态脚本 RCE | 可写的 `/etc/passwd` | | `machineH5C` | `10042` | Apache Struts RCE | 带有 `LD_PRELOAD` 的 `sudo` | | `machineH6A` | `10050` | distcc RCE | NFS `no_root_squash` | | `machineH6B` | `10052`, `10054` | 无认证的 MongoDB,随后复用 SSH 凭据 | `docker` 组逃逸 | | `machineH6C` | `10053`, `10055` | Heartbleed 泄露 SSH 凭据 | `sudo systemctl start ` | | `machineH7A` | `10060`, `10061` | SNMP public community | 共享的 root `tmux` socket 劫持 | | `machineH7B` | `10062` | Grafana 目录遍历至管理员执行 | 全局可写的 `/etc/shadow` | | `machineH7C` | `10063` | 匿名 rsync 写入 | root cron 中的 PATH 劫持 | | `machineH8A` | `10070` | 带有空密码的 PHPMyAdmin root | MySQL UDF shell | | `machineH8B` | `10071` | Flask/Jinja2 SSTI | 全局可写的 sudo policy trick | | `machineH8C` | `10072` | Laravel Ignition RCE | SUID `bash_suid -p` | ## 运行时状态模型 裁判使用明确的比赛状态: - `stopped` - `starting` - `running` - `paused` - `rotating` - `faulted` - `stopping` 运行保证: - 暂停期间不计分 - 不会静默推进失败的部署或轮换 - 没有健康证据则不接受所有权 - 缺失的探测数据被视为失败,而非成功 - 恢复期间保持活动暂停,直到操作员验证当前系列 ## 仓库结构 ``` . |-- README.md |-- docker-compose.yml # local aggregate stack, not production control |-- rotate.sh # local legacy helper, not production rotation logic |-- Series H1/ ... Series H8/ # challenge content by series |-- referee-server/ | |-- app.py # FastAPI apps and API routes | |-- scheduler.py # lifecycle, deploy, rotate, recover | |-- scorer.py # quorum-based winner selection | |-- poller.py # node and container observations | |-- enforcer.py # rule and violation enforcement | |-- db.py # SQLite persistence | |-- ssh_client.py # SSH execution layer | |-- templates/ # admin and participant UI templates | `-- tests/ # referee runtime tests |-- qa/ | |-- load_suite.py # protocol-aware load probes | |-- vuln_suite.py # safe exploit validation probes | `-- deployment/ # deployment and recovery validation tooling `-- docs/ # runbooks, design docs, validation guides ``` ## 两种运行方式 ### 1. 生产模式 生产环境使用分布式裁判管理模型: - 每个挑战节点上的本地 `h1` 到 `h8` 目录 - 复制到这些节点上的、按系列的 `docker-compose.yml` 制品 - 运行 FastAPI、调度器和 HAProxy 的中央裁判主机 - 仅服务于活跃系列的 HAProxy 这是预期的活动拓扑结构。 ### 2. 本地 / 开发模式 仓库根目录还包括: - [`docker-compose.yml`](docker-compose.yml),用于在本地启动全套挑战 - [`rotate.sh`](rotate.sh),作为本地辅助工具 这些对于开发和内容测试很有用,但它们并非权威的生产编排路径。 ## 快速开始 ### 在本地运行裁判 ``` cd referee-server python -m venv .venv ``` 激活虚拟环境: - macOS/Linux:`source .venv/bin/activate` - PowerShell:`.venv\Scripts\Activate.ps1` 安装依赖并启动裁判: ``` pip install -r requirements.txt pytest uvicorn app:app --host 0.0.0.0 --port 8000 ``` 打开: - 管理仪表板:`http://127.0.0.1:8000` - 参赛者面板:`http://127.0.0.1:9000` - 参赛者排行榜:`http://127.0.0.1:9000/leaderboard` ### 运行测试 ``` python -m pytest referee-server/tests -q ``` ## 配置说明 裁判首先从进程环境加载设置,如果存在则从 `referee-server/.env` 加载。 ### 重要的环境变量 | 变量 | 用途 | |---|---| | `ADMIN_API_KEY` | 默认情况下管理员访问需要此密钥 | | `DB_PATH` | 运行时状态的 SQLite 路径 | | `NODE_HOSTS` | 逗号分隔的挑战节点主机 | | `NODE_PRIORITY` | 相同观测结果的决胜顺序 | | `NODE_SSH_TARGETS` | 可选的按节点 `user@host` SSH 目标 | | `SSH_USER` | 默认 SSH 用户名 | | `SSH_PORT` | 默认 SSH 端口 | | `SSH_PRIVATE_KEY` | SSH 私钥路径 | | `SSH_TIMEOUT_SECONDS` | SSH 命令超时时间 | | `SSH_STRICT_HOST_KEY_CHECKING` | 主机密钥强制校验开关 | | `VARIANTS` | 预期的变体,通常为 `A,B,C` | | `TOTAL_SERIES` | 系列数量,默认为 `8` | | `MIN_HEALTHY_NODES` | 所有权的仲裁阈值 | | `MAX_CLOCK_DRIFT_SECONDS` | 性能降级前的时钟漂移容忍度 | | `POLL_INTERVAL_SECONDS` | 计分轮询频率 | | `ROTATION_INTERVAL_SECONDS` | 系列轮换频率 | | `POINTS_PER_CYCLE` | 每个保留周期奖励的积分 | | `DEPLOY_HEALTH_TIMEOUT_SECONDS` | 部署/轮换期间的健康门超时时间 | | `DEPLOY_HEALTH_POLL_SECONDS` | 健康门轮询间隔 | | `REMOTE_SERIES_ROOT` | 节点上包含 `h1` 到 `h8` 的根目录 | | `DOCKER_COMPOSE_CMD` | 远程使用的 Compose 命令 | | `CONTAINER_NAME_TEMPLATE` | 节点操作的容器名称格式 | | `BACKEND_URL` | 可选的外部团队名册 / 积分接收端 | | `WEBHOOK_URL` | 用于事件通知的可选 webhook | | `REFEREE_LOG_PATH` | 裁判日志路径 | | `HAPROXY_LOG_PATH` | HAProxy 日志路径 | | `HAPROXY_CONFIG_PATH` | HAProxy 配置路径 | | `HAPROXY_ADMIN_SOCKET_PATH` HAProxy 管理 socket 路径 | ### `.env` 示例 ``` ADMIN_API_KEY=replace-me DB_PATH=./referee.db NODE_HOSTS=192.168.0.70,192.168.0.103,192.168.0.106 NODE_PRIORITY=192.168.0.70,192.168.0.103,192.168.0.106 NODE_SSH_TARGETS=node1@192.168.0.70,node2@192.168.0.103,node3@192.168.0.106 SSH_USER=root SSH_PORT=22 SSH_PRIVATE_KEY=~/.ssh/koth_referee SSH_TIMEOUT_SECONDS=8 SSH_STRICT_HOST_KEY_CHECKING=true VARIANTS=A,B,C TOTAL_SERIES=8 MIN_HEALTHY_NODES=2 MAX_CLOCK_DRIFT_SECONDS=2 POLL_INTERVAL_SECONDS=30 ROTATION_INTERVAL_SECONDS=3600 POINTS_PER_CYCLE=1.0 REMOTE_SERIES_ROOT=/opt/KOTH_orchestrator DOCKER_COMPOSE_CMD=docker compose CONTAINER_NAME_TEMPLATE=machineH{series}{variant} ``` ## 管理员与参赛者界面 ### 管理仪表板 管理仪表板是操作员的控制界面。它暴露了: - 比赛生命周期控制 - 轮换和重启控制 - 恢复验证和重新部署操作 - 排行榜和团队管理 - 路由可见性 - 主机和容器遥测 - 声明时间线和近期事件 - 参赛者面板配置和手动通知 ### 参赛者面板 参赛者面板专为选手设计。它暴露了: - 当前系列 - 公共主机和端口信息 - 组织者标题和副标题 - 当前的参赛者通知 - 包含公共排名的独立实时排行榜页面 ## API 概览 ### 公共 / 参赛者 - `GET /` - `GET /leaderboard` - `GET /api/public/dashboard` - `GET /api/public/leaderboard` ### 管理员 / 受保护 - `GET /api/status` - `GET /api/runtime` - `GET /api/lb` - `GET /api/routing` - `GET /api/telemetry` - `GET /api/logs/referee` - `GET /api/logs/haproxy` - `GET /api/claims` - `GET /api/teams` - `GET /api/events` - `POST /api/competition/start` - `POST /api/competition/stop` - `POST /api/pause` - `POST /api/resume` - `POST /api/rotate` - `POST /api/rotate/restart` - `POST /api/rotate/skip` - `POST /api/poll` - `POST /api/recover/validate` - `POST /api/recover/redeploy` - `POST /api/admin/teams` - `POST /api/admin/teams/{name}/ban` - `POST /api/admin/teams/{name}/unban` - `GET /api/admin/public/config` - `PUT /api/admin/public/config` - `GET /api/admin/public/notifications` - `POST /api/admin/public/notifications` - `DELETE /api/admin/public/notifications/{id}` 除非明确启用了不安全启动,否则所有管理员端点都需要 `X-API-Key`。 ## 部署与运维 关于实际的部署流程,请从这些文档开始: - [docs/full-deployment-runbook.md](docs/full-deployment-runbook.md) - [docs/deployment-validation-checklist.md](docs/deployment-validation-checklist.md) - [docs/referee-per-node-ssh-targets.md](docs/referee-per-node-ssh-targets.md) - [docs/haproxy-full-config.md](docs/haproxy-full-config.md) 关于活动执行和验证: - [docs/manual-tester-checklist.md](docs/manual-tester-checklist.md) - [docs/referee-rule-validation-checklist.md](docs/referee-rule-validation-checklist.md) - [docs/production-remediation-design.md](docs/production-remediation-design.md) ## QA 与验证工具 ### 裁判测试套件 [`referee-server/tests/`](referee-server/tests/) 涵盖: - 仲裁获胜者选择 - 时钟漂移处理 - 部署和轮换回滚行为 - 恢复与保障机制 - API 授权 - 路由和遥测端点 - 公共仪表板流程 ### Stack QA [`qa/README.md`](qa/README.md) 涵盖服务级别的探测: - `qa/load_suite.py`,用于协议感知的负载检查 - `qa/vuln_suite.py`,用于非破坏性的漏洞验证 ### 部署 QA [`qa/deployment/README.md`](qa/deployment/README.md) 涵盖主机和部署验证: - `validate_koth_node.sh` - `validate_referee_lb.sh` - `emulate_referee_paths.py` - `prebuild_series_cache.sh` - `configure_koth_ufw.sh` ## 文档导航 如果你刚接触这个项目,请按以下顺序阅读: 1. 本 README 2. [docs/full-deployment-runbook.md](docs/full-deployment-runbook.md) 3. [docs/deployment-validation-checklist.md](docs/deployment-validation-checklist.md) 4. [docs/manual-tester-checklist.md](docs/manual-tester-checklist.md) 5. [docs/referee-rule-validation-checklist.md](docs/referee-rule-validation-checklist.md) 如果你正在验证或扩展控制平面,也请阅读: - [docs/production-remediation-design.md](docs/production-remediation-design.md) 如果你想要一个攻击者风格的单机基准测试: - [docs/codex-h1a-player-prompt.md](docs/codex-h1a-player-prompt.md) ## 贡献指南 当贡献遵循实际的运行时模型时,会最易于审查: - 将 `referee-server/` 视为生产控制平面 - 将根目录的 `docker-compose.yml` 和 `rotate.sh` 视为本地/开发辅助工具 - 让生成的状态、日志和本地数据库远离源代码控制 - 倾向于保留显式生命周期和恢复行为的更改 - 更改部署前提假设时,请更新相关的运行手册或清单 对于非微小的更改,请包含: - 正在更改的运行时行为 - 对操作员的影响 - 恢复或回滚的影响 - 测试覆盖范围或手动验证说明 ## 开源整洁性 本仓库故意忽略了本地运行时制品,例如: - `.env` 文件 - 本地 SQLite 数据库 - 本地日志 - 活动的备份目录 - 生成的 QA 结果文件 这使得仓库保持可发布状态,而不会与特定活动的本地状态混淆。 ## 当前状态 Consensus KoTH 已经可用作私人活动平台,但它具有一定的主观设定: - 它假设采用三节点挑战拓扑结构 - 它假设有一个中央裁判主机 - 它假设采用基于仲裁的所有权机制,而不是独立的按节点计分 如果这与您的活动设计相符,本仓库将为您提供核心靶场、控制平面和验证工具的整合体。
标签:Docker, Docker Compose, King of the Hill, KoTH, Quorum, Root权限, TGT, Web仪表盘, Web报告查看器, 内存分配, 分布式系统, 响应大小分析, 安全防御评估, 容器化部署, 容错机制, 排行榜, 提权, 攻防演练, 无线安全, 法定人数, 版权保护, 状态监控, 系统恢复, 网络安全, 网络安全审计, 网络靶场, 自动化运维, 裁判系统, 请求拦截, 逆向工具, 隐私保护, 集群高可用