SaarCTF 2024 Scoring Formula
Scoring formula for SaarCTF 2024 organized by saarsec.
Summary
The total score of each team is calculated from offense
, defense
and sla
components of every team for each of their services and rounds played.
The checker returns one of three results for each service:
up
, recovering
and down
. A service is considered recovering
if SLA
checks both suceeded and failed for one round (each) in the
recovery period.
Additionally, the game server tracks the status of the vulnbox' VPN
connection as, assigning either online
or offline
status accordingly.
The following python pseudo-code captures the team score calculation:
def score(rnd, team):
attack = 0
captures = [f for f in flags_captured_by(team) if flag_owner(f) != "NOP"]
for flag in captures:
attack += 1 + len(captures_of(flag)) ** -0.5 \
+ scoreboard_pos(flag_owner(flag), flag_round(flag)) ** -0.5
sla = 0
defense = 0
for r in range(rnd+1):
online = [t for t in teams if vpn_status(r, t) == 'online']
for service in services:
if service_status(r, team, service) == 'up':
for flag in flags_in(r, team, service):
defense -= (len(captures_of(flag)) / len(online)) ** 0.3 \
* len(online) ** 0.5
sla += len(online) ** 0.5
flags_per_round = sum(service.flagstores for service in services)
attack /= flags_per_round
defense /= flags_per_round
return attack + defense + sla
def scores():
return {rnd: {team: score(rnd, team} for team in teams} for rnd in rounds}
The final worth of a flag is only calculated once its validity is over. That means, everyone that submits a flag while it is still valid receives the same amount of points.
Review
- Only small differences to the FaustCTF 2024 scoring formula, inherits most of the same strengths (simple, easy to implement) and weaknesses (score recalculation).
- SLA is scaled using the number of online teams, which allows manipulation by registering fake teams ahead of time and connecting / disconnecting from the VPN depending on your own service status.
- Attack and defense points are scaled by the number of flagstores, but SLA is not scaled by the number of services. For consistent scoring, SLA should be normalized such that SLA weight does not depend on the number services deployed.
- Defense points scale with SLA, such that perfect SLA will always be worth
atleast as much as the defense points lost. However, since the attacker
still gains points when in the worst-case
sla + defense == 0
, this formula violates Tenet 4.