Skip to content

Repository files navigation

BlueForge

🛡️ BlueForge

Defensive Hardening Competition Platform — defend the box, not just capture the flag.

Point a class of Ubuntu VMs at a scoring server, let participants patch real vulnerabilities under a clock, and watch the leaderboard update live as each fix lands — automatically, no manual refresh, no spreadsheet grading. Free and open source, self-hosted on Vercel + Supabase.

License: MIT Platform Python Next.js Supabase Build LinkedIn

BlueForge

⬇️ Quickstart · ✨ Features · ⚙️ How it works · 📖 Technical Design · 🧯 Troubleshooting · ⚠️ Disclaimer


🧩 The Problem

Most "cybersecurity competition" tooling is either offense-only (CTF flags, attack ranges) or a pile of manual work for organizers: someone has to walk around with a checklist, SSH into every VM, and grade hardening steps by hand. Scores land minutes or hours after the fact, and participants get no live feedback on what they've actually fixed.

BlueForge is a defensive (blue-team / system-hardening) competition platform, closer to CyberPatriot than to a red-team CTF. Participants receive a deliberately-vulnerable Ubuntu VM and a time limit; every genuine fix — SSH hardened, firewall enabled, rogue accounts removed, backdoors cleaned up — is detected automatically by a lightweight agent and reflected on a public leaderboard within seconds, no grader required.

✨ Key Features

  • 🎯 Four difficulty tiers, 50 checks total — Easy (6) · Medium (30) · Hard (all 50, zero hints — a full dress-rehearsal tier) · FITCOM (all 50, sized for the real ~4h event), picked per session by the organizer. Checks run No. 1 → 50 in genuine easiest-to-hardest order, not just a random or insertion-order list — both the kiosk and the admin panel display that exact number next to every question.
  • 💡 Hints that guide & instruct (30% hint policy) — 15 of the 50 checks carry a guiding hint_basic (never a direct command/answer), distributed from Easy to Expert difficulty bands, while the remaining 70% stay hintless to encourage independent analysis.
  • 🧠 Black-Box State Verification — The agent inspects Linux system end-states (check.py), NOT terminal command history or specific CLI tools. Participants have 100% freedom to use any command (sed, chmod, nano, vim, GUI tools, or custom scripts). Any valid method that achieves the security objective earns points automatically without debate or misperception.
  • ⚖️ Fair & evidence-backed anti-cheat — a Baseline & Evidence system snapshots each VM at registration/START/STOP, so fixing a check before START doesn't earn points (closes the "pre-fix" loophole). Pre-fix checks are visually marked with a red checkmark () + "Pre-fix" badge across the Admin Panel, Leaderboard, and Participant Kiosk UI.
  • 🚫 Disqualify with instant alerts & visual badges — clicking DQ freezes a participant's status: the agent stops scoring, an instant popup alert modal + persistent banner appears on the participant's VM kiosk, and the public Leaderboard displays a prominent red badge (🚨 DIDISKUALIFIKASI) with strikethrough score.
  • Truly live scoring — leaderboard polls + Supabase Realtime, admin console auto-refreshes participant status, and the agent's clock-skew correction means scores keep flowing even when a cloned VM's system clock is wrong (see docs/REVIEW-AND-CONCEPT-v2.md §2.1) — no more waiting on a manual VMware/Ubuntu clock refresh.
  • 🧩 Modular checks — add a new hardening check by dropping a manifest.yaml + check.py into agent/checks/; the scoring engine never needs to change (plugin-style).
  • 🖥️ Zero-setup, crash-resilient participant experience — the agent ships as a kiosk companion app (pywebview, with a browser-kiosk fallback) that autostarts on VM boot: participants see registration, live score, and remaining time without touching a terminal. Because participants hold full sudo on their own VM for the whole round, a crash or sudo reboot is expected, not exceptional — the agent persists its session locally and resumes automatically, and the server treats a matching re-registration as a resume rather than a rejection, so nobody gets locked out of their own progress (disqualified participants are still correctly blocked from this path).
  • 🔒 Signed, replay-resistant networking — HMAC-signed agent↔server traffic with a nonce store that rejects replayed requests, exponential backoff, and store-and-forward queuing so a flaky network during a competition never silently drops a score.
  • 🛠️ Hardened organizer console — brute-force-limited admin login (rate-limited, durably logged), a one-click CSV export of final standings, and a full audit trail (event_logs) of every disqualify, requalify, and removal.
  • 🆓 100% free stack — Vercel (web) + Supabase (Postgres/Realtime/Auth) + a pure-Python agent. No paid services required to run a competition.

🖼️ Screenshots

Live demo — a participant's fix lands, the kiosk score updates instantly, and the public leaderboard catches up moments later — no manual refresh anywhere.

BlueForge — live scoring demo

Leaderboard — live rank, score, and countdown, no refresh needed.

BlueForge — leaderboard

Detailed score checklist is available by clicking a participant on the public leaderboard:

BlueForge — leaderboard score detail

Admin console — create sessions, start/pause/stop, manage participants, auto-refreshing.

BlueForge — admin dashboard BlueForge — create session

Participant kiosk — a companion window (not fullscreen-lock), so participants can still use the terminal to work while registering and tracking their score live.

BlueForge — kiosk companion window BlueForge — kiosk registration BlueForge — kiosk dashboard checklist

💻 System Requirements

Organizer (web) Participant (per VM)
Hosting Free Vercel + Supabase project
OS Ubuntu (20.04–26.04), provisioned via image/build/provision.sh
Runtime Node.js 20+ (dev/build only — Vercel builds in the cloud) Python 3.10+, root access (reads /etc/shadow etc.)
Network Public HTTPS endpoint (Vercel) Outbound HTTPS to that endpoint — agent only polls out, so it works fine behind NAT

📦 Download VM Image

Pre-built VMware image — import and run, no manual provisioning needed.

File Link Notes
🖥️ BlueForge VM (VMware .ova Archive) ⬇️ Download via Google Drive 🔐 RAR Password: blueforge
🔧 VMware Workstation Player vmware.com/products/workstation-player Free for non-commercial use

Import the VM:

  1. Download & extract the .rar archive using password blueforge.
  2. Open VMware → File → Open → select the extracted .ova file.
  3. Import → start the VM.
  4. Boot → BlueForge kiosk launches automatically. Fill in name + session code from your organizer.

Organizer only: after import, run sudo bash ~/BlueForge/image/build/provision.sh once to plant all 50 intentional vulnerabilities before distributing the VM to participants.


🚀 Quickstart

1. Database (Supabase)

  1. Create a free project at supabase.com.
  2. In SQL Editor, run db/schema.sql, then db/seed/difficulties.sql (brand-new project — this alone gives you all 4 tiers, including FITCOM). Upgrading an existing database from before the FITCOM preset existed? Run the relevant file(s) in db/migrations/ first, then re-run db/seed/difficulties.sql (it's UPSERT-based, safe to run again anytime).
  3. Note your Project URL, anon key, and service_role key (Settings → API).

2. Web portal (Next.js)

cd web
cp .env.example .env.local      # fill in Supabase creds + AGENT_HMAC_SECRET
npm install
npm run dev                     # http://localhost:3000

Deploy to Vercel: import the repo → set root directory to web/ → fill in the environment variables.

3. Agent (inside each participant's Ubuntu VM)

cd agent
cp config.example.yaml config.yaml   # set portal_url to your deployed web URL
pip install -r requirements.txt
sudo python3 main.py                 # open http://localhost:9090 to register

Or launch the kiosk companion app instead of the bare agent: python3 kiosk.py (see docs/kiosk-setup.md for autostart on VM boot).

4. Run a competition

  1. On /admin: create a session, pick a difficulty (Easy/Medium/Hard/FITCOM), get a session code.
  2. Participants register at localhost:9090 using that code.
  3. Organizer clicks START → every agent begins scoring simultaneously → live scores on /.
  4. STOP freezes scores → export results.

🧭 First time self-hosting this end-to-end (repo → Supabase → Vercel → VM)? See the detailed beginner walkthrough: docs/DEPLOYMENT-GUIDE.md.

🎛️ What Each Piece Does

Component What it does
agent/ Python agent — runs checks, computes score, signs & sends results, serves the local kiosk UI
web/app/api/v1/* Signed agent-facing API — register, state, score, heartbeat, snapshot, clock sync
web/app/page.tsx Public live leaderboard
web/app/admin/page.tsx Organizer console — sessions, participants, start/pause/stop, disqualify
db/ Postgres schema + seed (difficulties, checks) + leaderboard view
db/migrations/ Incremental SQL migrations for databases created before a schema change (e.g. adding the fitcom preset)
image/build/provision.sh Plants all 50 intentional vulnerabilities into a base Ubuntu VM (idempotent — safe to re-run)

⚙️ How it Works

[ participant VM: blueforge-agent ] --HTTPS (polling, signed)--> [ Next.js /v1 API ]
                                                                          |
                                                                   [ Supabase: Postgres + Realtime ]
                                                                          |
                                                        [ Web: live Leaderboard + Admin console ]

The agent sits behind NAT and only polls out — the server never needs to reach into a participant's VM. Every scoring cycle: sync clock with the server (no manual clock fixing needed) → fetch competition state → run the active checks → compute the score (pure function, eligible = failed at START) → sign and send. Full design in docs/TECHNICAL-DESIGN.md.

🗺️ Roadmap

  • v0.2 — 15 checks across 3 real difficulty tiers, kiosk companion app, admin auto-refresh, agent clock-skew fix.
  • v0.4 — 30 checks total (+15 new, including root_home_perm), a dedicated FITCOM preset (all 30, sized for a ~2.5h event) with checks in genuine easiest-to-hardest order, guiding-only hints (never a ready-made fix command) on ~30% of checks, randomly distributed, instant DQ alert popups + leaderboard badges, red checkmark pre-fix indicators across all UIs, nonce anti-replay, admin login rate limiting, CSV export, and an agent that survives a participant's VM crashing or rebooting mid-round without losing their session.
  • v0.5 (current)50 checks total (+20 new: kernel/sysctl hardening, sudoers secure_path, planted SSH keys, hidden SUID backdoors, disguised listeners, privileged group membership). Tiers re-mapped: Medium now runs the old 30-check FITCOM set (No. 1–30), Hard and FITCOM both run the full No. 1–50 superset (identical content — Hard has zero hints for dress-rehearsal practice, FITCOM keeps the ~30% guiding-hint policy and a 4h duration for the real event). image/build/provision.sh plants all 20 new vulnerabilities; verified in tests/test_new_checks_sandbox.py.
  • Next up — richer plugin API for community-contributed checks, an evidence viewer UI, Windows participant VM support (agent port), and a Go rewrite of the agent for a smaller footprint.
  • v1.0 — production hardening: multi-organizer orgs, PDF export, a fuller admin audit UI on top of the event_logs trail that already exists.

See docs/V0.2-PLAN.md, CHANGELOG.md, and the full TDD roadmap (§29) for details.

🤝 Contributing & Security

Issues and PRs welcome — see CONTRIBUTING.md. Add a new check by subclassing the run(ctx) -> {"passed": bool, "evidence": {...}} contract in agent/checks/<code>/check.py; the engine needs no other change.

Found a vulnerability in the platform itself (not one of the intentionally planted training vulnerabilities)? Report it via SECURITY.md — please don't open a public issue.

🧯 Troubleshooting (Organizer / Participant VM)

Quick reference for the two operations organizers run most often on a participant VM. Full step-by-step (Bahasa Indonesia) lives in docs/DEPLOYMENT-GUIDE.md.

First run on a fresh VM clone:

cd ~/BlueForge
git pull
sudo bash image/build/provision.sh   # plants all 50 intentional vulnerabilities

provision.sh clears ~/.bash_history (root & the login user) as its very last step, so a cloned/exported VM doesn't leak the organizer's setup commands to participants — no separate manual history-clearing step needed anymore. If you keep typing commands in that same terminal after provision.sh finishes and before exporting the VM, run history -c once more right before export — bash can otherwise re-write the still-running session's history back to the file on a normal shell exit.

Pulling a code update onto an already-installed VM — the kiosk/agent that actually runs at boot is a separate copy installed to /opt/blueforge-agent/ by install-kiosk.sh, not the git checkout itself. git pull alone does not update what's running — you must resync:

cd ~/BlueForge
git pull
sudo bash agent/kiosk/install-kiosk.sh   # resyncs code into /opt + restarts the service
sudo systemctl restart blueforge-agent

Kiosk window accidentally closed by a participant: kiosk.py now auto-reopens the window on its own within ~2 seconds — no action needed. If the window is ever truly stuck, double-click the "Restart BlueForge" shortcut on the Desktop (no terminal required), or run bash /opt/blueforge-agent/kiosk/restart-kiosk.sh.

Common diagnostic commands:

systemctl status blueforge-agent dhc-telnetd dhc-ftpd dhc-listener   # are the services alive?
ps aux | grep -E "kiosk.py|main.py"            # is the kiosk/agent actually running?
journalctl --user -b | grep -i -E "kiosk|webview|gtk"  # kiosk autostart logs this boot
diff ~/BlueForge/agent/kiosk.py /opt/blueforge-agent/kiosk.py  # in sync?

⚠️ Disclaimer

This platform intentionally plants security vulnerabilities into VMs for training purposes. Isolated/air-gapped competition networks only — see DISCLAIMER.md before deploying.

📄 License

MIT © 2026 Abil Khosim.


👤 Developed by Abil KhosimCybersecurity Specialist

LinkedIn

BlueForge is an original project by Abil Khosim, an independent security tool by Abil Khosim (NoxNull). Released under the MIT License — please keep this attribution when reusing or redistributing.

Stop collecting flags. Start patching real vulnerabilities. 🛡️

About

⚒️ BlueForge — Defensive Hardening Competition Platform with automated hardening verification, live scoring, and real-time leaderboards.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages