feat: challenge registry-driven platform + XVI/XVII imports + admin toggle + domain rename

- Rename repo/domain: attack-defense-platform / attackdefense.imrnes.team (all refs replaced)
- challenge_registry.json: single source of truth (28 challs across gemastik18/xvi/xvii)
- teams.py: registry-driven CHALLENGES, set_challenge_enabled, sync_challenge_runtime
  (apply enable/disable to live teams: build/up or stop/remove + receiver restart)
- compose_gen.py: render per-team compose from canonical per-challenge templates
  (image reuse, per-team ports 30xxx, flag mounts, passwords)
- gen_canonical_composes.py: canonical docker-compose.yml for all services
- import_new_challenges.py: import XVI/XVII services + EOL base image fixes
  (debian:buster→bookworm, node:14→20, python:3.7-slim→3.11)
- receiver: xvi package (10 checkers) + xvii package (12 generic checkers),
  Challenge base reads PASSWORD_<team_port> from env; gen_receiver_main.py
  generates per-team main.py from registry
- main.py: /api/challenges returns full registry; PATCH /api/challenges/<name>
  toggles enabled + applies to live teams
- index.html: 🏗️ Challenge Manager tab (toggle per challenge, grouped by set)
- SLA bonus now dynamic (all enabled challenges, not hardcoded 6)
This commit is contained in:
MythEclipse
2026-09-25 14:04:33 +08:00
parent c35b23a37f
commit c6fd9ec268
1317 changed files with 306586 additions and 128 deletions
+329
View File
@@ -0,0 +1,329 @@
{
"sets": {
"gemastik18": {
"label": "GEMASTIK XVIII",
"repo": "github.com/rayhanhanaputra/gemastik18-final",
"note": "Game aktif saat ini"
},
"xvi": {
"label": "GEMASTIK XVI",
"repo": "github.com/vidner/gemastik-xvi-final",
"note": "Distributed \u2014 toggle untuk aktifkan"
},
"xvii": {
"label": "GEMASTIK XVII",
"repo": "github.com/vidner/gemastik-xvii-final",
"note": "Distributed \u2014 toggle untuk aktifkan"
}
},
"challenges": [
{
"name": "blogpost",
"set": "gemastik18",
"category": "web",
"desc": "Flask blog with exiftool + SSTI",
"chall_offset": 0,
"ssh_offset": 22,
"enabled": true,
"service_dir": "blogpost",
"org_port": 10000
},
{
"name": "carbeat",
"set": "gemastik18",
"category": "pwn",
"desc": "Binary exploitation menu",
"chall_offset": 1,
"ssh_offset": 23,
"enabled": true,
"service_dir": "carbeat",
"org_port": 11000
},
{
"name": "cdn",
"set": "gemastik18",
"category": "web",
"desc": "CDN/image proxy SSTI",
"chall_offset": 2,
"ssh_offset": 24,
"enabled": true,
"service_dir": "cdn",
"org_port": 12000
},
{
"name": "phew",
"set": "gemastik18",
"category": "crypto",
"desc": "Paillier crypto oracle",
"chall_offset": 3,
"ssh_offset": 25,
"enabled": true,
"service_dir": "phew",
"org_port": 13000
},
{
"name": "sheesh",
"set": "gemastik18",
"category": "crypto",
"desc": "AES padding oracle",
"chall_offset": 4,
"ssh_offset": 26,
"enabled": true,
"service_dir": "sheesh",
"org_port": 14000
},
{
"name": "warmup",
"set": "gemastik18",
"category": "warmup",
"desc": "Go file viewer (path traversal)",
"chall_offset": 5,
"ssh_offset": 27,
"enabled": true,
"service_dir": "warmup",
"org_port": 15000
},
{
"name": "art",
"set": "xvi",
"category": "web",
"desc": "Ruby ASCII art renderer",
"chall_offset": 10,
"ssh_offset": 110,
"enabled": false,
"service_dir": "art",
"org_port": 10000
},
{
"name": "xl",
"set": "xvi",
"category": "web",
"desc": "Node XL spreadsheets app",
"chall_offset": 11,
"ssh_offset": 111,
"enabled": false,
"service_dir": "xl",
"org_port": 11000
},
{
"name": "gemas-notes",
"set": "xvi",
"category": "web",
"desc": "Note service + MySQL + validation (multi-container)",
"chall_offset": 12,
"ssh_offset": 112,
"enabled": false,
"service_dir": "gemas-notes",
"org_port": 12000
},
{
"name": "pasta",
"set": "xvi",
"category": "web",
"desc": "Pasta pastebin (FTP-ish? web)",
"chall_offset": 13,
"ssh_offset": 113,
"enabled": false,
"service_dir": "pasta",
"org_port": 13000
},
{
"name": "burvesigner",
"set": "xvi",
"category": "crypto",
"desc": "Burve-style signature oracle",
"chall_offset": 14,
"ssh_offset": 114,
"enabled": false,
"service_dir": "burvesigner",
"org_port": 14000
},
{
"name": "hirnfick",
"set": "xvi",
"category": "pwn",
"desc": "Brainfuck-ish binary",
"chall_offset": 15,
"ssh_offset": 115,
"enabled": false,
"service_dir": "hirnfick",
"org_port": 15000
},
{
"name": "gemas-fetcher",
"set": "xvi",
"category": "web",
"desc": "URL fetcher + MongoDB (multi-container)",
"chall_offset": 16,
"ssh_offset": 116,
"enabled": false,
"service_dir": "gemas-fetcher",
"org_port": 16000
},
{
"name": "s3",
"set": "xvi",
"category": "web",
"desc": "S3-ish service",
"chall_offset": 20,
"ssh_offset": 120,
"enabled": false,
"service_dir": "s3",
"org_port": 20000
},
{
"name": "crawlback",
"set": "xvi",
"category": "web",
"desc": "PHP crawlback SSRF",
"chall_offset": 21,
"ssh_offset": 121,
"enabled": false,
"service_dir": "crawlback",
"org_port": 21000
},
{
"name": "back-to-basic",
"set": "xvi",
"category": "warmup",
"desc": "Warmup binary (warmup)",
"chall_offset": 22,
"ssh_offset": 122,
"enabled": false,
"service_dir": "back-to-basic",
"org_port": 22000
},
{
"name": "anti-alchemy",
"set": "xvii",
"category": "web",
"desc": "Alchemy flask app (web)",
"chall_offset": 30,
"ssh_offset": 130,
"enabled": false,
"service_dir": "anti-alchemy",
"org_port": 11000
},
{
"name": "asmr",
"set": "xvii",
"category": "pwn",
"desc": "ASMR pwn (ubuntu 24.04)",
"chall_offset": 31,
"ssh_offset": 131,
"enabled": false,
"service_dir": "asmr",
"org_port": 15000
},
{
"name": "bit-canvas",
"set": "xvii",
"category": "pwn",
"desc": "C xinetd pwn",
"chall_offset": 32,
"ssh_offset": 132,
"enabled": false,
"service_dir": "bit-canvas",
"org_port": 20000
},
{
"name": "fjb",
"set": "xvii",
"category": "web-pwn",
"desc": "Node web+pwn",
"chall_offset": 33,
"ssh_offset": 133,
"enabled": false,
"service_dir": "fjb",
"org_port": 17000
},
{
"name": "gift-card",
"set": "xvii",
"category": "crypto",
"desc": "Crypto gift card",
"chall_offset": 34,
"ssh_offset": 134,
"enabled": false,
"service_dir": "gift-card",
"org_port": 21000
},
{
"name": "gift-voucher",
"set": "xvii",
"category": "crypto",
"desc": "Crypto gift voucher",
"chall_offset": 35,
"ssh_offset": 135,
"enabled": false,
"service_dir": "gift-voucher",
"org_port": 16000
},
{
"name": "gleam-drive",
"set": "xvii",
"category": "web-crypto",
"desc": "Gleam drive web-crypto",
"chall_offset": 36,
"ssh_offset": 136,
"enabled": false,
"service_dir": "gleam-drive",
"org_port": 12000
},
{
"name": "go-green",
"set": "xvii",
"category": "rev",
"desc": "Go reverse engineering (xinetd)",
"chall_offset": 37,
"ssh_offset": 137,
"enabled": false,
"service_dir": "go-green",
"org_port": 20000
},
{
"name": "kode-viewer",
"set": "xvii",
"category": "web",
"desc": "Node kode viewer + redis (multi-container)",
"chall_offset": 38,
"ssh_offset": 138,
"enabled": false,
"service_dir": "kode-viewer",
"org_port": 10000
},
{
"name": "more-less",
"set": "xvii",
"category": "web",
"desc": "Python more/less web",
"chall_offset": 39,
"ssh_offset": 139,
"enabled": false,
"service_dir": "more-less",
"org_port": 22000
},
{
"name": "tempest-poc",
"set": "xvii",
"category": "web",
"desc": "Tempest POC (backend + frontend)",
"chall_offset": 40,
"ssh_offset": 140,
"enabled": false,
"service_dir": "tempest-poc",
"org_port": 14080
},
{
"name": "ticketer",
"set": "xvii",
"category": "crypto",
"desc": "Ticketer crypto oracle (socat)",
"chall_offset": 41,
"ssh_offset": 141,
"enabled": false,
"service_dir": "ticketer",
"org_port": 14000
}
]
}