-
Notifications
You must be signed in to change notification settings - Fork 86
Challenge Author Docs
A service is a program that, from a high-level point of view, has a stated benign purpose (e.g., it implements a web forum), and contains some flags: secrets that are not supposed to be revealed to unauthorized users during normal operation (e.g., private messages in the web forum).
The goal of the opponent teams is to steal a flag from the service, and submit it to the organizers. Services are written with a variety of deliberately incorporated vulnerabilities, so that stealing flags is impossible unless the attacking team is able to exploit one of these vulnerabilities.
Generally speaking, a service listens on a given port, so that external programs can interact with it and invoke certain functions. These functionalities should cover at least the following high-level categories:
- a
setflag
functionality that allows one to set the currently active flag; - a
getflag
functionality that allows the benign and authorized retrieval of a flag; - some additional benign functionality that represents the normal behavior of the service.
A new flag is periodically set and retrieved by the scoring infrastructure so that, at any point in time, each service has one and only one active flag, identified by a unique flag_id
. The scriptbot sets and retrieves a flag by using setflag
and getflag
. These functionalities should blend with benign service interactions and not stick out in an obvious way. For example, they can be used for benign interactions by simply setting or retrieving inactive or incorrect flags.
In particular:
- The
setflag
script takes as an input a string representing a valid flag, and is in charge of installing it into the service and returning the correspondingflag_id
, and asecret token
. - The
getflag
script takes as input theflag_id
and its associatedsecret_token
, and retrieves the corresponding flag, so that the scoring infrastructure can determine whether the service is properly functioning or not. Note that thegetflag
script can retrieve the flag associated with a givenflag_id
because it has access to its associatedsecret_token
, and not by exploiting a vulnerability.
Consider the following sample scenario. There are 2 teams (A and B) playing with 2 challenges, named service1 and service2.
As one can see from these tables, the flag_id, its associated flag, and the secret token are DIFFERENT for each service currently running in the game. Moreover, these parameters are also DIFFERENT across different teams.
Team A
service_name | flag_id | secret_token | flag | port |
---|---|---|---|---|
service1 | flag_id_string_1 | secret_token_string_1 | flag_string_1 | 10001 |
service2 | flag_id_string_2 | secret_token_string_2 | flag_string_1 | 10002 |
Team B
service_name | flag_id | secret_token | flag | port |
---|---|---|---|---|
service1 | flag_id_string_3 | secret_token_string_3 | flag_string_3 | 10001 |
service2 | flag_id_string_4 | secret_token_string_4 | flag_string_4 | 10002 |
If the scriptbot needs to verify the currently installed flags on the teams' machines, it uses the get_flag.py
scripts in this way:
# SCRIPTBOT
> python get_flag.py team_A_IP 10001 flag_id_string_1 secret_token_string_1
"flag_string_1"
> python get_flag.py team_A_IP 10002 flag_id_string_2 secret_token_string_2
"flag_string_2"
> python get_flag.py team_B_IP 10001 flag_id_string_3 secret_token_string_3
"flag_string_3"
> python get_flag.py team_B_IP 10002 flag_id_string_4 secret_token_string_4
"flag_string_4"
If Team A wants to attack Team B, and has an exploit ready to be launched against the service1 it just needs to connect to the team_B_IP on port 10001 to get the currently installed flag:
# TEAM A
> python exploit.py team_B_IP 10001
"flag_string_3" # THIS IS THE FLAG
Team A is eventually going to submit the extracted flag ("flag_string_3") to our infrastructure using the team interface API. The message sent to our system will say that Team A extracted "flag_string_3" for service1 and the correspondent flag_id is "flag_id_string_3". Our system will assign points once the flag is received, and its validity verified.
When the game ticks, the Scriptbot changes all the flags installed on all the services. The Scriptbot will do that using the setflag.py script.
# SCRIPTBOT
> python set_flag.py team_A_IP 10001 flag_string_5
(flag_id_string_5, secret_token_string_5) # RETURNS THE NEW FLAG_ID and the SECRET_TOKEN
Note that, the Scriptbot is going to change the flags at an unpredictable time during this new tick. The next tables show that, when the game ticks, all the previous presented parameters change across all the teams, for each challenge.
Team A
service_name | flag_id | secret_token | flag |
---|---|---|---|
service1 | flag_id_string_5 | secret_token_string_5 | flag_string_5 |
service2 | flag_id_string_6 | secret_token_string_6 | flag_string_6 |
If the Scriptbot needs to verify the currently installed flags on the teams' machines, it is going to use the get_flag.py
scripts in this way:
# SCRIPTBOT
> python get_flag.py team_A_IP 10001 flag_id_string_5 secret_token_string_5
"flag_string_5"
> python get_flag.py team_A_IP 10002 flag_id_string_6 secret_token_string_6
"flag_string_6"
> python get_flag.py team_B_IP 10001 flag_id_string_7 secret_token_string_7
"flag_string_7"
> python get_flag.py team_B_IP 10002 flag_id_string_8 secret_token_string_8
"flag_string_8"
Team B
service_name | flag_id | secret_token | flag |
---|---|---|---|
service1 | flag_id_string_7 | secret_token_string_7 | flag_string_7 |
service2 | flag_id_string_8 | secret_token_string_8 | flag_string_8 |
IMPORTANT RECAP:
- flag_id is PUBLIC, every team can query the infrastructure to retrieve the current active flag_id of a specific service that belongs to a specific team.
- secret_token is a SECRET that only the Scriptbot uses to implement the getflag functionality.
- flag is a SECRET that a team is supposed to steal from other teams by exploiting a vulnerability in the service.
Finally, The benign
script exercises other service-specific benign functionality, so that the setflag
and getflag
scripts do not stick out in any obvious way, and to ensure that the service is fully operational and has not been tampered with (e.g., because of a careless patching process).
The exploit
script is used to demonstrate one possible working exploit against the service.
Of course, the teams will develop additional exploits during the competition, but one must be included with the service submission.
Conceptually, an exploit script needs to steal the flag associated with a given flag_id
, without knowing the associated secret_token.
Note that the flag_id
specifies which of the many flags of the service the script must retrieve.
For this reason, the only input the exploit script takes is the flag_id
, and it must return the flag.