Skip to content

Game Overview

Each team is given root access to a cloud-hosted Linux-based virtual machine that exposes vulnerable services to other teams over a private virtual network.

Over the course of every round, lasting 60 seconds, so-called checkers store text snippets called flags in the services on each team's vulnbox and test their functionality to make sure they are working as intended. Extracting these flags from other teams' services and submitting them to a central flag submission each round to earn ATK-points is the game's primary goal.

Flag stores

A checker may store multiple unique flags each round in distinct areas of a service, so-called flag stores, and there may be more than one intended vulnerability to reach each one.

To incentivize teams to keep their services available to other teams to exploit, a series of checks is performed each round against every service of every team by the organizers' checkers. Checkers retrieve flags from flag stores of the previous 4 rounds in addition to the current round. Conversely, flags award points when submitted no more than 4 rounds after the round they were deployed in.

Attack info

Checkers may provide hints for successfully stored flags to help guide exploits as attack info. In some cases, this info is crucial to exploiting the vulnerability at all. It can be retrieved via the scoreboard at /api/attack.json. Please use the ecsc2026ad Python package, which provides client-side caching and may also be used to query the scoreboard.

The tests performed by checkers define the so-called Service-Level Agreement (SLA); the functionality required for a team to earn SLA-points each round.

Checker hold

The last 5 seconds of every round are a quiet period during which no checker tasks are running. Use this window to cleanly restart your services without a check hitting a service mid-restart and costing you SLA-points.

Each round, a team also receives DEF-points for every service if they were able to defend against an attack. The amount of points earned is highest when the service is unexploited, and decreases with the amount of other teams exploiting it.

These points combine to calculate the team score using the scoring formula.

Flag Format

Each flag is matched by the regular expression /^ECSC\{[A-Za-z0-9-_]{32}\}$/

Each flag consists of a prefix and suffix that wrap a base64-encoded1 payload with the following format:

  • 2 bytes: round id
  • 2 bytes: team id
  • 2 bytes: service id
  • 2 bytes: flagstore id
  • 16 bytes: SHA256-HMAC (of previous 8 bytes, truncated)

Flag Submission

Players can submit stolen flags by sending them line-delimited in a plain TCP connection to 10.60.249.2 on port 31337. This must be done via the game network, since the source IP is used to determine the submitting team.

For each line, in the order that they are received, the flag submission will return one of the following results on a new line:

  • [OK]: The flag is valid and was accepted
  • [ERR] Own flag: The flag is from the submitting team
  • [ERR] NOP flag: NOP team flags are not counted
  • [ERR] Expired: The flag is not valid anymore
  • [ERR] Wrong length: The flag has the wrong length
  • [ERR] Invalid source IP: The submitting IP cannot be attributed to a team
  • [ERR] Already submitted: The flag has already been submitted by this team
  • [ERR] Invalid flag (format): The flag does not match the flag format
  • [ERR] Invalid flag (service): The flag references an unknown service
  • [ERR] Invalid flag (team): The flag references an unknown team
  • [ERR] Invalid flag (hmac): The signature of the flag is incorrect
  • [ERR] Internal error (database): A backend error occurred

  1. This payload is encoded using the base64url charset ↩