Skip to content

Challenges

There are two main categories of challenges hosted for BearcatCTF. Each requires a different build process and infrastructure footprint for deployment.

For functional reference templates, check the BearcatCTF Challenges repository.


1. Challenge Types (Architecture)

Static Challenges

Challenges that do not require a live server or backend. Players download artifact files locally to extract the flag. - Examples: Reverse engineering binaries, stego images, PCAP files, or audio forensics. - Infra Footprint: Hosted purely as static file downloads via CTFd/S3

Dynamic Challenges

Challenges that require a live backend server for player interaction - Examples: Web exploits, pwn/nc targets, or active cryptography services. - Infra Footprint: Containerized via Dockerfile, deployed to AWS EC2 instances running Docker.


2. File Directory Requirements

Every challenge submission requires a specific set of files based on its type.

File Static Dynamic Description
challenge.yaml Required Required Metadata and deployment configuration for CTF-Tool.
readme.md Required Required Documentation for the internal CTF helpdesk / triage team.
Dockerfile Optional Required Container build specification for AWS deployment.
solve.py Optional Required Python 3 script for automated health check Lambdas.

3. Configuration Files

Below is the detailed specification for each of the files mentioned in the requirements matrix.

challenge.yaml

This file is used to help package the challenge up to be deployed within CTF-Tool. Without this file, your challenge will not get bundled into the rest of the challenges for the import into CTFd. Here is an example of a valid challenge.yaml

version: 1
challenges:
    Challenge Name:
        author: Name # Your first name or alias
        brief: PHP SQL Injection # Brief internal technical summary (not public)
        flag: BCCTF{abc} # Use 'file:flag.txt' to source from a separate file
        case_sensitive: false 
        flag_type: static # Use 'regex' for pattern matching
        message: Hello player! # Public description string OR 'file:message.txt'
        player_files: file1.py, file2.txt # Files available for player download

# --- DYNAMIC CHALLENGE PROPERTIES ONLY ---
        dockerfile: Dockerfile 
        connection_hint: http://{{event.address}}:{{chal.port}}/ # DO NOT EDIT
        privileged: false # Requires explicit approval from Infra Lead

Do not modify the dockerfile, connection_hint, or privileged default values unless instructed. Incorrect values will break pipeline orchestration.

readme.md

Internal documentation explaining the challenge concept, intended solution path, and standard triage steps for the helpdesk. Written in standard Markdown.

Dockerfile (Dynamic Only)

Defines the runtime environment for the AWS EC2 cluster.

You must pin your base image versions. Utilizing :latest will break the deployment pipeline. Use specific tags (e.g., ubuntu:22.04 or alpine:3.23.4).

solve.py (Dynamic Only)

An automated exploit script executed by AWS Lambda health checks to verify the challenge is up and solving correctly.

  • Language: Python 3 only.
  • Dependencies: Stick to standard library packages (socket, urllib, json) or highly standard modules to fit within the Lambda execution boundary.

4. Optional / Content Files

  • flag.txt: Holds the solution flag if reference-linked in challenge.yaml.
  • message.txt: Holds the public-facing challenge description if externalized from the YAML.
  • challenge/ Folder: Recommended directory to consolidate raw source code or asset files if your challenge requires a messy build context.