emirhankaplan/kalkan-cyber-range

GitHub: emirhankaplan/kalkan-cyber-range

一个自托管的网络安全靶场平台,提供动态 flag、浏览器内攻击终端和隔离容器编排,支持 CTF 与渗透测试练习。

Stars: 0 | Forks: 0

🛡️ KALKAN — 自主网络靶场

一个自托管的 网络靶场(CTF / 渗透测试练习)。选择一台故意留有漏洞的 机器 → 平台将为你启动一个 隔离的容器 → 发起攻击 → 找到 基于会话的动态 flag → 提交它。精神上类似于 HackTheBox / TryHackMe,但每次 会话的 flag 都是唯一的(攻略 write-up 毫无用处),并且它内置了一个 真正的浏览器内攻击 shell,让你无需任何设置即可开始黑客攻击。

engine web typescript docker labs status

## ✨ 亮点 - **基于会话的动态 flag** — 为每个会话生成并注入 `Kalkan{<32 hex>}`,**仅在服务端存储**,使用恒定时间(constant-time)验证。共享 / 旧的 / 互联网上的 flag 永远无效。 - **真正的浏览器内攻击 shell** — 直接连接到一个已经处于目标网络中的攻击者盒子(box)的实时 PTY(xterm.js ↔ WebSocket ↔ `docker exec`)。客户端零设置。同时提供 WireGuard。 - **经过强化的隔离编排** — 每个会话使用一个无出口网络 + `cap-drop ALL` 以及资源受限的容器;配置过程实时流式传输;在停止/到期时自动销毁。 - **8 个可用的漏洞实验环境**,涵盖不同类别 — 每一个都通过真实引擎验证了端到端的 rooting 过程。 - **实时运营感** — 全局“谁在线”状态 + 基于 WebSocket 的 rooting 实时动态,每台机器的任务简报,行动后报告,以及忠实还原的终端级设计移植。 ## 状态 — 所有阶段均已实现 ✅ | 阶段 | 范围 | 状态 | | ----- | ----------------------------------------------------------- | :---: | | 0 | 框架搭建 + 从设计中移植的完整前端 | ✅ | | 1 | 引擎:经过强化的 Docker 编排 + 实时 WS 日志 | ✅ | | 2 | 动态 flag + 服务端验证 + 防作弊 | ✅ | | 3 | 浏览器内的攻击者终端(PTY ↔ WS ↔ xterm.js) | ✅ | | 4 | JWT 认证、真实目录、排行榜 + 积分系统 | ✅ | | 5 | WireGuard VPN(“自带 Kali”) | ✅¹ | ¹ 第 5 阶段始终签发真实的基于会话的 `.conf` 文件;当在 WireGuard 网关主机上设置 `KALKAN_WG_ENABLED=true` 时,将激活实时的主机配置(`wg`/`ip`)。 **端到端验证:** 所有 **8 个实验环境**(命令注入、SQLi、LFI、SSRF、反序列化、SSTI、IDOR、JWT-bypass)均可成功预置 → 从攻击者盒子发起利用 → 泄露**精确的**基于会话的 flag → 提交 → **ROOTED** + 获得积分,然后进行彻底的销毁。错误/旧的 flag 会失败;暴力破解受到限制(HTTP 429);WS 升级需要有效的 token + origin;引擎内置了单元测试。 ## 架构 ``` ┌─────────────────────────────────────────────┐ browser ──HTTPS/WSS──▶│ Caddy (TLS, security headers, routing) │ └───────────────┬───────────────┬─────────────┘ │ / │ /api/* /ws/* ┌─────▼─────┐ ┌──────▼───────┐ ┌────────┐ │ web │ │ engine (Go) │──▶│ Redis │ │ Next.js │ │ chi + WS │ │sessions│ └───────────┘ └──────┬───────┘ │ flags │ │ Docker SDK └────────┘ ▼ ┌──────────────────────────────────────────┐ │ per-session isolated bridge networks │ │ kalkan-sess- (internal, no egress) │ │ ┌──────────┐ ┌────────────────┐ │ │ │ target │◀──────▶│ attacker shell │ │ │ │ (lab) │ │ (PTY ↔ browser)│ │ │ └──────────┘ └────────────────┘ │ └──────────────────────────────────────────┘ ``` 平台服务(Caddy、web、engine、Redis)通过 docker-compose 运行。**实验环境 容器由 engine 动态启动,绝不通过 compose 启动。** ## 技术栈 - **Frontend** (`web/`):Next.js 14 (App Router) · TypeScript (strict) · Tailwind v3 · Zustand · xterm.js · 原生 WebSocket。 - **Engine** (`engine/`):Go 1.22+ · chi · Docker Engine SDK · coder/websocket · golang-jwt v5 · go-redis(后备:内存数据库)。架构分层为 `core`(端口/模型) + 叶子包(store/flag/auth/ratelimit/lab/vpn) + 集成层(orchestrator/ws/ session/api)。 - **Infra**:Docker + docker-compose(仅限平台) · Caddy(TLS + 反向代理) · WireGuard。 ## 仓库布局 ``` web/ Next.js frontend (ported from the design — visual source of truth) engine/ Go orchestration API + WebSocket internal/core domain model + port interfaces (the contract) internal/{store,flag,auth,ratelimit,lab,vpn} leaf implementations internal/{orchestrator,ws,session,api} Docker / WS / lifecycle / HTTP labs/ Vulnerable target machines — one folder per machine (folder == codename) _template/ copy-paste-ready lab: Dockerfile + metadata.json + flag-inject entrypoint AVCI/ demo lab — a "network tools" panel with a command-injection RCE gateway/ WireGuard server bootstrap + per-session peer manager (Phase 5) deploy/ docker-compose.yml, Caddyfile, attacker image, .env.example Makefile make dev / dev-engine / attacker-image / build / lint / up / down ``` ## 快速开始 ### 本地开发 `make dev` 启动 Web 应用;`make dev-engine` 运行 engine(内存存储, 实验环境使用真实的 Docker)。它们通过 `web/.env.development` 进行跨域通信。 ``` make install # web deps make attacker-image # build kalkan/attacker:latest once (needs Docker) # terminal 1 — engine 在 :8080 上(需要 Docker 访问权限;内存存储) make dev-engine # terminal 2 — web 在 :3000 上 make dev ``` 打开 http://localhost:3000 并使用预置的操作员登录: | 字段 | 值 | | -------- | ----------- | | Operatör | `n0xferatu` | | Anahtar | `kalkan` | ### 完整平台(docker-compose) ``` cp deploy/.env.example deploy/.env # then edit secrets (JWT, domain, …) make attacker-image make up # caddy + web + engine + redis make logs ; make down ``` ## 质量 ``` make lint # web eslint + tsc --noEmit, engine go vet + gofmt make test # engine unit tests ``` 单元测试覆盖了安全关键的不变量:存储记录的往返过程 (针对 Redis `json:"-"` flag/密码哈希错误的回归防护)、flag 格式 + 恒定时间验证、JWT 的签发/验证(包括 alg-confusion + 过期拒绝)、 速率限制器、原子化的首次解题计分以及实验环境注册表。 ## 独创之处 - **基于会话的动态 flag** — write-up 攻略毫无用处;每个会话的 flag 都不同。 - **真正的浏览器内攻击 shell** — 直接连接到目标网络中攻击者盒子的 PTY; 客户端零设置(WireGuard 是“自带 Kali”的替代方案)。 - **任务简报** — 每台机器一个用于展示任务背景的简报面板。 - **实时动态** — 全局的“谁在线”状态 + 基于 WS 的实时 rooting 滚动播报。 - **行动后报告** — ROOTED 横幅会报告获取 root 的时间 + 获得的积分。 ## 工作原理(循环流程) 1. `POST /api/labs/AVCI/start` → engine 生成 `Kalkan{<32 hex>}`,构建 实验环境镜像,创建一个**内部**(无出口)网络,启动经过强化的 目标(flag 通过 `KALKAN_FLAG` 注入)+ 攻击者盒子,并通过 `GET /ws/sessions/:id` 流式传输带有样式的预置日志。 2. 操作员从**浏览器终端**(直接连接到攻击者容器的真实 PTY,已处于目标网络中)或他们自己的 Kali 通过 WireGuard `.conf` 发起攻击。在 AVCI 上的示例:`host=127.0.0.1; cat /root/root.txt`。 3. `POST /api/sessions/:id/flag` **仅在服务端**通过恒定时间比较进行验证。正确 → 状态变为 `rooted`,获得积分,通过 WS 广播 → UI 触发 ROOTED 庆祝动画。 ## 安全模型 这是一个黑客攻击平台,因此它本身不能被黑客攻击。 - **目标实验容器**:仅有内部网络且**无出口**(已验证 `internal=true`),512 MiB / 1 CPU / 256-pid 限制,`--cap-drop ALL` + 仅保留所需的那一个 cap(目标为 `NET_BIND_SERVICE`,攻击者为 `NET_RAW`),`no-new-privileges` (可切换),tmpfs `/tmp`。防范主机 DoS 和从盒子内部进行的数据渗漏。 - **Flags**:基于会话的 `Kalkan{<32 hex>}`(crypto/rand),注入到容器中, **仅在服务端存储**(`json:"-"` — 永远不会序列化到客户端),使用 `crypto/subtle` 恒定时间比较进行验证。共享/旧的/互联网上的 flag 永远无法通过验证。 - **防作弊 / 防滥用**:在 flag 提交(基于会话 AND 基于 IP)和登录(基于 IP)上应用令牌桶速率限制 → 暴力破解时返回 HTTP 429。 - **AuthZ**:带过期的 JWT (HS256);每个会话路由都会检查所有权(404/403); WebSockets 通过 `?token=` 进行身份验证,并强制执行 Origin 白名单。 - **传输层**:Caddy 终止 TLS;WS over WSS;HSTS, X-Frame-Options, nosniff, Referrer-Policy, 以及 CSP 集中在 `deploy/Caddyfile` 中设置。密钥通过环境变量传递 (附带 `deploy/.env.example`;`.env` 被 gitignored)。 ### 信任假设 — Docker socket Engine 直接与 **Docker daemon 通信**(Engine SDK)以构建镜像并 创建网络 + 容器。对 Docker socket 的访问权限等同于主机上的 root 权限,因此: - **在您控制的专用、隔离的 VM/VPS 上运行 Kalkan** — 而不是共享/生产主机。 - socket 仅挂载到 engine 中(见 `deploy/docker-compose.yml`),永远不会 通过网络暴露。实验容器永远不会获得 socket,也永远没有出口。 ## API | 方法 | 路径 | 备注 | | ------ | ----------------------------- | -------------------------------------- | | POST | `/api/auth/login` | → `{token, user}`(受速率限制) | | GET | `/api/me` | 当前操作员 | | GET | `/api/labs` | 目录(rooted 数量 + 每位用户解题数) | | POST | `/api/labs/{codename}/start` | 预置会话 | | GET | `/api/sessions/{id}` | 会话状态(仅限所有者) | | POST | `/api/sessions/{id}/stop`·`/restart`·`/extend` | 生命周期 | | POST | `/api/sessions/{id}/flag` | 验证 flag(受速率限制) | | GET | `/api/sessions/{id}/vpn` | WireGuard `.conf` | | GET | `/api/leaderboard` | 排名靠前的操作员 | | WS | `/ws/sessions/{id}` | 预置日志 + 状态 + rooted | | WS | `/ws/sessions/{id}/terminal` | 攻击者 PTY | ## 添加实验环境 ``` cp -r labs/_template labs/ # folder name MUST equal the codename # 编辑 labs//metadata.json + Dockerfile,然后重启 engine ``` 有关文件夹约定和基于会话的 flag 注入机制,请参阅 [`labs/README.md`](labs/README.md)。您提供/选择易受攻击的应用程序(自定义,或者是 已有的程序,如 DVWA / OWASP Juice Shop);Kalkan 负责对其进行编排。`labs/AVCI` 是一个完整且可用的示例。 ## 设计来源 前端是最终设计(`Kalkan Siber Poligon.html`)的忠实移植。 手工编写的设计系统(`web/src/styles/`)是**视觉上的唯一事实来源**, 被逐字移植;Tailwind 配置了匹配的 token 以供编写新代码使用。UI 有意**没有**被重新设计。
标签:Docker, EVTX分析, Go, OPA, Ruby工具, 安全防御评估, 搜索引擎查询, 日志审计, 网络安全, 请求拦截, 隐私保护, 靶场