-
Notifications
You must be signed in to change notification settings - Fork 22
Writing a checker
Checker is an app that checks whether the team's task is running normally, puts flags and then checks them after a few rounds.
Actions and arguments are passed to checker as command-line arguments, the first one is always command type, the second is team host.
Checker should terminate with one of the five return codes:
-
101:
OK
code, everything works -
102:
CORRUPT
, service's working correctly, but didn't return flags from previous rounds (returned byGET
only) -
103:
MUMBLE
, service's not working correctly -
104:
DOWN
, could not connect normally -
110:
CHECKER_ERROR
, unexpected error in checker
All other return codes are considered to be CHECKER_ERROR
.
In case of unsuccessful invocation stdout
output will be shown on scoreboard, stderr
output is considered to
be the debug info and is stored in database. Also, in case of CHECKER_ERROR
celery
container prints warning
to console with detailed logs.
Checker must implement three main actions:
-
CHECK
: checks that team's service is running normally. Visits some pages, checks registration, login, etc...
Example invocation: /checkers/task/check.py check 127.0.0.1
-
PUT
: puts a flag to the team's service.
Example invocation: /checkers/task/check.py put 127.0.0.1 <flag_id> <flag> <vuln_number>
If the checker returns flag_id
(see checker config), it should write some data
which helps to access flag later (username, password, etc) to stdout
(that data will be the flag_id
passed to GET
action). Otherwise, it ought to use flag_id
as some "seed" to generate such data (on the next invocation flag_id
will be the same if checker_type
is set to hackerdom_nfr
).
PUT
is run even if CHECK
failed
-
GET
: fetches one random old flag from lastflag_lifetime
rounds.
Example invocation: /checkers/task/check.py get 127.0.0.1 <flag_id> <flag> <vuln_number>
This action should check if the flag can be acquired correctly.
GET
is not run if CHECK
(or previous GETs
if gets > 1
) fail.
A simple example of checker can be found here.
Be aware that to test task locally, LAN IP (not 127.0.0.1
) needs to be specified for the team.
See this link to read more about
writing checkers for Hackerdom checksystem. Vulns' frequencies (e.g. put 1 flag for the first vuln for each
3 flags of the second) are not supported (and won't be), but can be easily emulated with task place count and checker.
For example, for the above configuration (1:3) specify 4 places for the task, and then in checker PUT
flag to the
first vuln if the supplied vuln is 1 and to the second vuln otherwise (vuln is 2, 3 or 4):
# How to store 3 times more flags for the second vuln
if int(vuln) == 1: # first vuln
pass
elif int(vuln) in (2, 3, 4): # second vuln
pass
If checker is using local files, it should access them by the relative to its directory path, as checkers are run using
absolute paths inside Docker. For example, the following is incorrect: open('local_file.txt')
as in Docker it'll try
to open /local_file.txt
instead of /checkers/task/local_file.txt
. Correct usage would be
from pathlib import Path
BASE_DIR = Path(__file__).absolute().resolve().parent
local_path = BASE_DIR / 'local_file.txt'
As checkers run in celery
container, open docker_config/celery/Dockerfile.fast
(or docker_config/celery/Dockerfile if you're not using the fast build)
and install all necessary packages to the image. Any modification can be made in CUSTOMIZE
block.
With enough confidence, even the base image of celery container could be changed
(python3.7
needs to be installed anyway).