- all 6 Dockerfiles: vim curl wget netcat git python3-pip now installed - apt-insecure.conf (AllowInsecureRepositories) copied into images so participants can apt-get install despite expired Ubuntu/Debian GPG keys - warmup base ubuntu:20.04 (EOL, GPG expired) -> ubuntu:24.04 - installed vim+git live into all 18 running team containers - team portal target dropdown reloads after login (was empty pre-auth) - attack log endpoint + A/D submit (attacker vs target) verified e2e
86 lines
4.3 KiB
Docker
86 lines
4.3 KiB
Docker
FROM public.ecr.aws/docker/library/golang:1.21-alpine AS builder
|
|
|
|
# Build the Go application
|
|
WORKDIR /app
|
|
COPY src/main.go .
|
|
RUN go build -o challenge main.go
|
|
|
|
# Final stage
|
|
FROM public.ecr.aws/docker/library/ubuntu:24.04
|
|
|
|
ARG PASSWORD
|
|
|
|
ENV DEBIAN_FRONTEND=noninteractive
|
|
|
|
# Allow apt on hosts whose clock is past GPG key expiry (2026+)
|
|
COPY apt-insecure.conf /etc/apt/apt.conf.d/99gemastik-insecure
|
|
|
|
# Install necessary packages
|
|
RUN apt-get -o Acquire::AllowInsecureRepositories=true update && apt-get -y --allow-unauthenticated install nano vim git openssh-server python3 python3-pip curl netcat-traditional wget sudo nginx golang-go && rm -rf /var/lib/apt/lists/*
|
|
|
|
# Create ctfuser and set password
|
|
RUN useradd -m -d /home/ctfuser ctfuser && echo ctfuser:${PASSWORD} | chpasswd
|
|
|
|
# Configure SSH
|
|
RUN echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config && echo "PermitRootLogin no" >> /etc/ssh/sshd_config && echo "AllowUsers ctfuser" >> /etc/ssh/sshd_config && echo "PermitEmptyPasswords no" >> /etc/ssh/sshd_config
|
|
|
|
# Generate SSH host keys
|
|
RUN ssh-keygen -A
|
|
RUN mkdir -p /run/sshd && chmod 755 /run/sshd
|
|
|
|
# Create working directories
|
|
RUN mkdir -p /opt/files && chown -R ctfuser:ctfuser /opt && chmod 755 /opt && chmod 755 /opt/files
|
|
|
|
# Copy the built binary from builder stage
|
|
COPY --from=builder /app/challenge /opt/challenge
|
|
RUN chmod 755 /opt/challenge && chown ctfuser:ctfuser /opt/challenge
|
|
|
|
# Copy HTML template
|
|
COPY src/index.html /opt/index.html
|
|
RUN chmod 644 /opt/index.html
|
|
|
|
# Create sample files for the file viewer
|
|
RUN echo "Welcome to the File Viewer Challenge!\n\nThis is a simple file viewer application.\nYou can view different files using the /view endpoint.\n\nExample: /view?file=welcome.txt\n\nGood luck finding the flag!" > /opt/files/welcome.txt
|
|
RUN echo "File Viewer v1.0\n\nThis application allows you to view text files stored in /opt/files/\n\nAvailable files:\n- welcome.txt\n- info.txt\n- hint.txt" > /opt/files/info.txt
|
|
RUN echo "Hint: The flag is hidden somewhere on the system.\nMaybe you can try viewing other files?\nWhat about files outside the /opt/files/ directory?\n\nThink about path traversal..." > /opt/files/hint.txt
|
|
RUN chmod 644 /opt/files/*.txt
|
|
|
|
# Create flag file
|
|
COPY flag.txt /flag.txt
|
|
RUN chmod 444 /flag.txt && chown root:root /flag.txt
|
|
|
|
# Copy main.go for users to patch
|
|
COPY src/main.go /opt/main.go
|
|
RUN chown ctfuser:ctfuser /opt/main.go && chmod 644 /opt/main.go
|
|
|
|
# Create rebuild script for users
|
|
RUN echo '#!/bin/bash' > /opt/rebuild.sh && \
|
|
echo 'echo "Building patched challenge..."' >> /opt/rebuild.sh && \
|
|
echo 'cd /opt' >> /opt/rebuild.sh && \
|
|
echo 'go build -o challenge.new main.go' >> /opt/rebuild.sh && \
|
|
echo 'if [ $? -ne 0 ]; then' >> /opt/rebuild.sh && \
|
|
echo ' echo "Build failed!"' >> /opt/rebuild.sh && \
|
|
echo ' exit 1' >> /opt/rebuild.sh && \
|
|
echo 'fi' >> /opt/rebuild.sh && \
|
|
echo 'chmod 755 /opt/challenge.new' >> /opt/rebuild.sh && \
|
|
echo 'echo "Restarting challenge..."' >> /opt/rebuild.sh && \
|
|
echo 'mv /opt/challenge.new /opt/challenge' >> /opt/rebuild.sh && \
|
|
echo 'pkill -f /opt/challenge' >> /opt/rebuild.sh && \
|
|
echo 'sleep 1' >> /opt/rebuild.sh && \
|
|
echo '/opt/challenge >/tmp/challenge.log 2>&1 &' >> /opt/rebuild.sh && \
|
|
echo 'echo "Challenge rebuilt and restarted!"' >> /opt/rebuild.sh && \
|
|
chmod +x /opt/rebuild.sh && \
|
|
chown ctfuser:ctfuser /opt/rebuild.sh
|
|
|
|
# Configure nginx
|
|
COPY nginx.conf /etc/nginx/sites-available/warmup
|
|
RUN ln -s /etc/nginx/sites-available/warmup /etc/nginx/sites-enabled/warmup && rm -f /etc/nginx/sites-enabled/default && chown root:root /etc/nginx/sites-available/warmup && chmod 644 /etc/nginx/sites-available/warmup
|
|
|
|
# Create startup script
|
|
RUN echo '#!/bin/bash' > /opt/start.sh && echo 'set -e' >> /opt/start.sh && echo 'service ssh start' >> /opt/start.sh && echo 'nginx -t && service nginx start || echo "Nginx config error"' >> /opt/start.sh && echo 'su - ctfuser -c "/opt/challenge >/tmp/challenge.log 2>&1 &"' >> /opt/start.sh && echo 'sleep 1' >> /opt/start.sh && echo 'pgrep -f /opt/challenge > /tmp/challenge.pid' >> /opt/start.sh && echo 'trap "if [ -f /tmp/challenge.pid ]; then kill -TERM $(cat /tmp/challenge.pid) 2>/dev/null || true; fi; exit 0" SIGTERM SIGINT' >> /opt/start.sh && echo 'tail -f /dev/null' >> /opt/start.sh && chmod +x /opt/start.sh
|
|
|
|
EXPOSE 8080 22
|
|
|
|
USER root
|
|
CMD ["/opt/start.sh"]
|