Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions challenges/mock-track-apache-php/track.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ flags:
value: 5
description: Free flag in source of index.php
return_string: '[mock-track-apache-php] 1/1 Good job! Track completed.'
cfss: "CFSS:0.3/TS:B/E:M/HSFC:N=4-7"
tags:
discourse: mock_track_apache_php_flag_1
services:
Expand Down
3 changes: 2 additions & 1 deletion challenges/mock-track-files-only/track.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ contacts:
- user_support
flags:
- flag: FLAG-32c335e18b6c0eb6ddbd6366ade11069
value: 5
value: 7
description: Free flag in downloadable content
return_string: '[mock-track-files-only] 1/1 Good job! Track completed.'
cfss: "CFSS:0.3/TS:L/E:H/HSFC:Y=7-11"
tags:
discourse: mock_track_files_only_flag_1
services: []
2 changes: 2 additions & 0 deletions challenges/mock-track-python-service/track.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ flags:
value: 2
description: Free flag in source of web application
return_string: '[mock-track-python-service] 1/2 Great!'
cfss: "CFSS:0.3/TS:L/E:L/HSFC:N=1-2"
tags:
discourse: mock_track_python_service_flag_1
- flag: FLAG-20f645f09e6989741a39759209aa047d
value: 10
description: RCE!!
return_string: '[mock-track-python-service] 2/2 Good job! Track completed.'
cfss: "CFSS:0.3/TS:I/E:M/HSFC:Y=7-12"
tags:
discourse: mock_track_python_service_flag_2
services:
Expand Down
5 changes: 5 additions & 0 deletions ctf/schemas/track.yaml.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@
"description": "The text the participants see AFTER they submit the flag. Example: [mytrackname] 1/1 Good job! Track completed.",
"minLength": 1
},
"cfss": {
"type": "string",
"description": "The CFSS string based on https://github.com/res260/cfss",
"pattern": "^CFSS:[0-9]\\.[0-9][0-9]?/TS:[LBIA]/E:[LMH]/HSFC:[NY]=[0-9][0-9]?-[0-9][0-9]?$"
},
"tags": {
"type": "object",
"description": "Askgod tags for this flag. Use tag `discourse: sometriggername` to define triggers for posts in the posts/ directory.",
Expand Down
7 changes: 6 additions & 1 deletion ctf/templates/init/schemas/track.yaml.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@
"description": "The text the participants see AFTER they submit the flag. Example: [mytrackname] 1/1 Good job! Track completed.",
"minLength": 1
},
"cfss": {
"type": "string",
"description": "The CFSS string based on https://github.com/res260/cfss",
"pattern": "^CFSS:[0-9]\\.[0-9][0-9]?/TS:[LBIA]/E:[LMH]/HSFC:[NY]=[0-9][0-9]?-[0-9][0-9]?$"
},
"tags": {
"type": "object",
"description": "Askgod tags for this flag. Use tag `discourse: sometriggername` to define triggers for posts in the posts/ directory.",
Expand Down Expand Up @@ -165,4 +170,4 @@
"services",
"flags"
]
}
}
2 changes: 2 additions & 0 deletions ctf/templates/new/common/track.yaml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ flags:
description: Free flag in source of index.php CHANGE_ME
# The text the participants see AFTER they submit the flag.
return_string: '[{{ data.name }}] 1/1 Good job! Track completed. CHANGE_ME'
# CFSS string based on https://github.com/res260/cfss
cfss: "CFSS:0.3/TS:B/E:M/HSFC:N=4-7"
tags:
# Name of the discourse trigger for this flag. If a discourse post in the posts/ directory has this trigger, it will be posted when this flag is submitted.
# This value can also be used to reference flags in Ansible playbooks. See the "Load Flags" task in deploy.yaml.
Expand Down
64 changes: 60 additions & 4 deletions ctf/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,13 +449,69 @@ def validate(self, track_name: str) -> list[ValidationError]:
return errors


class CFSSStringValidator(Validator):
"""Validate the CFSS string of each flag in the track.yaml."""

CFSS_VALUE_REGEX = re.compile(
r"^CFSS:[0-9]\.[0-9][0-9]?/TS:[LBIA]/E:[LMH]/HSFC:[NY]=([0-9][0-9]?-[0-9][0-9]?)$"
)

def validate(self, track_name: str) -> list[ValidationError]:
errors: list[ValidationError] = []

track_yaml = parse_track_yaml(track_name=track_name)
for flag in track_yaml["flags"]:
if "cfss" not in flag:
errors.append(
ValidationError(
error_name="CFSS string not found",
error_description="CFSS string was not present in the track.yaml.",
track_name=track_name,
details={
"CFSS string": "Not found",
"Flag value": str(flag.get("value")),
},
)
)
continue

cfss: str = flag.get("cfss")
value: int = flag.get("value")

# Should never happen since schemas/track.yaml.json is validated first.
if not (m := self.CFSS_VALUE_REGEX.match(cfss)):
errors.append(
ValidationError(
error_name="CFSS string did not match REGEX",
error_description='CFSS string did not match "^CFSS:[0-9]\\.[0-9][0-9]?/TS:[LBIA]/E:[LMH]/HSFC:[NY]=([0-9][0-9]?-[0-9][0-9]?)$".',
track_name=track_name,
details={"CFSS string": cfss, "Flag value": str(value)},
)
)
continue

low, high = m.group(1).split("-")
if value < int(low) or value > int(high):
errors.append(
ValidationError(
error_name="Flag value not in CFSS range",
error_description="Flag value did not correspond to CFSS string's value.",
track_name=track_name,
details={"CFSS string": cfss, "Flag value": str(value)},
)
)
continue
return errors


validators_list = [
CFSSStringValidator,
DiscourseFileNamesValidator,
DiscoursePostsAskGodTagValidator,
FilesValidator,
FlagsValidator,
FireworksAskGodTagValidator,
DiscoursePostsAskGodTagValidator,
FlagsValidator,
OrphanServicesValidator,
PlaceholderValuesValidator,
DiscourseFileNamesValidator,
ServicesValidator,
OrphanServicesValidator,
]
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ dependencies = [
"typer==0.16.0",
"pydantic"
]
version = "4.0.0"
version = "4.1.0"
classifiers = [
"Programming Language :: Python :: 3",
"Operating System :: OS Independent",
Expand Down