Skip to content

Dynamic Flags #34

@Blckbrry-Pi

Description

@Blckbrry-Pi

This one will require a lot of reworking, so it's very far into the future.

The basic idea of this are individual flags for each team1 to discourage/ban/monitor flag sharing.

Optimally, there will be some sort of algorithm so that we won't need to store the individual flags for every single team. This is one possible idea:

To generate the target for the team:

  1. Setup environment variable DYNAMIC_FLAG_GEN_KEY.
    Needs to be kept secret, because otherwise the teams could derive their hash themselves.
  2. To generate the ending hash:
    a. Create string const string = `${inner.length}${inner}+${teamId}+${dynamicFlagGenKey}`;
    b. Hash the string and get a hex digest
    I. This probably is good enough with SHA or MD5, as long as the flag gen key is long enough.
    As far as I'm aware, those are only meaningfully weak against preimage attacks. (LMK IF I'M WRONG THOUGH PLEASE.)
    Increasing the time for generating/verifying the flags will probably not be a good idea for large numbers of teams.
    c. Take the first 10 characters of the digest.
    I. This gives us about 1 billion unique hashes, which should be more than sufficient without making the flags too much longer.
    II. In the future, it may make sense to allow the challenge author to control the length of the hash, with some lower bound for safety.
  3. The flag is then const flag = `<flagPrefix>{${inner}-${hashChars}}`;

To verify a flag submission for the team:

  1. Get the inner part of the flag and strip the ending hash:
    a. Strip <flagPrefix>{ from the beginning and } from the end
    b. Strip the - and the hash from the end, and return do something with it if it doesn't match2.
  2. Generate the target for the team using the specified flag
  3. Compare the submission and the generated target flag, preferably in some constant-time way.
  4. As a result of this2, it may make sense just to add some couple randomized milliseconds of delay before returning the result?

This is just 1 idea for the algorithm.

Propose other ones, discuss the pros/cons of individual pre-stored flags, etc.

For Webhook:

This one will take a bit of work.
It's currently being rewritten in rust, so I'll just put some highlights:

  • Require(?)/import DYNAMIC_FLAG_GEN_KEY
  • Implement whatever algorithm is decided on.
    • If flags are being pregenerated/prestored, figure out how to store them in the SQL, along with how to recieve them.
  • Set up verifications for solve submissions, and maybe record them in the solve_attempts and solve_successes tables.

For Deploy:

  • Require(?)/import DYNAMIC_FLAG_GEN_KEY
  • Implement whatever algorithm is decided on.
    • If flags are being pregenerated/prestored, figure out how to generate them, along with how to send them to the webhook server.
  • Set up docker to generate any important configurations needed to generate the flag.
    • This one will have a lot more things that may need to be done, so see the relevant thing that I will eventually post in the comments.

For Frontend:

It's likely that not much will need to be done.
The frontend doesn't store flags at all, and just echos what the webhook server returns in terms of flag correctness.

Footnotes

  1. This may be slightly infeasible for certain challenges.
    With on-demand instances, it may be easier though? Not sure

  2. Well now we have timing attack problems. Great. 2

Metadata

Metadata

Assignees

No one assigned

    Labels

    ChallengesAnything related directly to challenges (i.e. how they're displayed, their deployment, etc.)Far FutureFeature SuggestionGeneral feature ideas that should be implemented/incorporated with the existing platform.InfrastructureSomething that would increase the reliability or ease of deployment of the CTF's challenges.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions