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:
1 parent
c35b23a37f
commit
c6fd9ec268
1317 files changed
+306586
-128
No files matched your search
@@ -0,0 +1,32 @@
|
||||
FROM ubuntu:24.04
|
||||
|
||||
ARG PASSWORD
|
||||
|
||||
ENV DEBIAN_FRONTEND noninteractive
|
||||
|
||||
RUN echo root:${PASSWORD} | chpasswd
|
||||
COPY apt-insecure.conf /etc/apt/apt.conf.d/99gemastik-insecure
|
||||
RUN apt-get -o Acquire::AllowInsecureRepositories=true update && apt-get install -y openssh-server xinetd cmake gcc curl
|
||||
RUN echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config
|
||||
RUN echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
|
||||
RUN service ssh start
|
||||
|
||||
RUN useradd -m ctf
|
||||
|
||||
WORKDIR /ctf
|
||||
|
||||
RUN echo "Connection blocked" > /etc/banner_fail
|
||||
COPY ctf.xinetd /etc/xinetd.d/ctf
|
||||
COPY ./src/main.c ./
|
||||
COPY ./run.sh ./
|
||||
COPY ./start.sh ./
|
||||
|
||||
RUN gcc /ctf/main.c -o /ctf/main
|
||||
|
||||
RUN touch /flag.txt
|
||||
RUN chmod -R 755 /ctf
|
||||
RUN chmod +x /ctf/start.sh
|
||||
|
||||
CMD ./start.sh
|
||||
|
||||
EXPOSE 8000
|
||||
@@ -0,0 +1,3 @@
|
||||
Acquire::AllowInsecureRepositories "true";
|
||||
Acquire::AllowDowngradeToInsecureRepositories "true";
|
||||
Apt::Get::AllowUnauthenticated "true";
|
||||
@@ -0,0 +1,16 @@
|
||||
service ctf
|
||||
{
|
||||
disable = no
|
||||
socket_type = stream
|
||||
protocol = tcp
|
||||
wait = no
|
||||
user = root
|
||||
type = UNLISTED
|
||||
port = 8000
|
||||
bind = 0.0.0.0
|
||||
server = /bin/sh
|
||||
server_args = /ctf/run.sh
|
||||
banner_fail = /etc/banner_fail
|
||||
# safety options
|
||||
rlimit_cpu = 1 # the maximum number of CPU seconds that the service may use
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
services:
|
||||
bit-canvas:
|
||||
container_name: bit-canvas_container
|
||||
hostname: bit-canvas
|
||||
restart: always
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
- PASSWORD=$PASSWORD_20000
|
||||
volumes:
|
||||
- ../receiver/flags/bit-canvas.txt:/flag.txt:ro
|
||||
- ../utils/bashrc:/root/.bashrc:ro
|
||||
- ../utils/preexec.sh:/root/.preexec.sh:ro
|
||||
ports:
|
||||
- "20000:8000"
|
||||
- "20022:22"
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
@@ -0,0 +1 @@
|
||||
su ctf -c "timeout 60s /ctf/main"
|
||||
@@ -0,0 +1,112 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
int main() {
|
||||
setbuf(stdout, NULL);
|
||||
|
||||
int choice = 0;
|
||||
int debug = 0;
|
||||
int size = 16;
|
||||
int canvas[16] = {0};
|
||||
|
||||
puts("bit-canvas @ gemastik-xvii");
|
||||
puts("1. draw");
|
||||
puts("2. clear");
|
||||
puts("3. resize");
|
||||
puts("4. admin");
|
||||
puts("5. exit");
|
||||
|
||||
while (1) {
|
||||
printf("choice? ");
|
||||
scanf("%d", &choice);
|
||||
switch (choice) {
|
||||
case 1:
|
||||
int n = 0;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
printf("how many bits? ");
|
||||
scanf("%d", &n);
|
||||
|
||||
if (n > (size * size * 2)) {
|
||||
puts("too many bits");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
printf("where x y? ");
|
||||
scanf("%d %d", &x, &y);
|
||||
bool prev = 0;
|
||||
bool next = 0;
|
||||
prev = canvas[x] >> y & 1;
|
||||
next = prev ^ 1;
|
||||
canvas[x] ^= 1 << y;
|
||||
if (debug) printf("[DEBUG] x: %d, y: %d, prev: %d, next: %d\n", x, y, prev, next);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
for (int i = 0; i < size; i++) {
|
||||
for (int j = 0; j < size * 2; j++) {
|
||||
canvas[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
printf("size? ");
|
||||
scanf("%d", &size);
|
||||
|
||||
break;
|
||||
|
||||
case 4:
|
||||
|
||||
FILE *f = fopen("/flag.txt", "r");
|
||||
|
||||
if (f == NULL) {
|
||||
puts("flag not found");
|
||||
return 1;
|
||||
}
|
||||
|
||||
char flag[43];
|
||||
char buffer[43];
|
||||
|
||||
fgets(flag, sizeof(flag), f);
|
||||
fclose(f);
|
||||
|
||||
printf("password? ");
|
||||
scanf("%s", buffer);
|
||||
|
||||
if (!strcmp(buffer, flag)) {
|
||||
debug = 1;
|
||||
puts("debug mode enabled");
|
||||
} else {
|
||||
puts("invalid password");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 5:
|
||||
puts("bye");
|
||||
return 0;
|
||||
|
||||
default:
|
||||
printf("invalid choice %d\n", choice);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
for (int j = 0; j < size * 2; j++) {
|
||||
printf("%d", canvas[i] >> j & 1);
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
/usr/sbin/sshd -D &
|
||||
/usr/sbin/xinetd -dontfork
|
||||
Reference in new issue
Block a user