Flag Generation Architecture
The flag system consists of three main components:- Template Parser - Parses flag templates into executable segments
- Flag Generator - Generates flags based on parsed templates
- Flag Checker - Validates submitted flags against expected values
Flag Templates
Flag templates define how dynamic flags are generated. GZCTF supports multiple template syntaxes:GUID Templates
Team Hash Templates
Leet Templates
Complex Leet Templates
Template Syntax
Placeholder Types
[GUID] Placeholder
[GUID] Placeholder
Replaced with a random UUID v4 in standard format:Properties:
- Generates 36-character UUID
- Cryptographically random
- Unique per flag generation
- Bypasses entropy checking
/src/GZCTF/Utils/FlagGenerator.cs:331-340[TEAM_HASH] Placeholder
[TEAM_HASH] Placeholder
Replaced with a 12-character deterministic hash:Hash Calculation:Properties:
- Deterministic per team+challenge
- Same team always gets same hash for same challenge
- Bypasses entropy checking
- Enables flag regeneration
/src/GZCTF/Models/Data/Challenge.cs:116-128Leet Transformation
Leet Transformation
Content inside braces Character Mappings:Full character map in
{...} is randomly transformed:/src/GZCTF/Utils/FlagGenerator.cs:159-197Complex Leet ([CLEET])
Complex Leet ([CLEET])
Prefix template with Additional Mappings:Reference:
[CLEET] for enhanced character mappings:/src/GZCTF/Utils/FlagGenerator.cs:199-237Leet Modes
The flag generator operates in four leet modes:Leet Modes
- If template starts with
[LEET]→Leetmode - If template starts with
[CLEET]→CLeetmode - If template contains
[GUID]or[TEAM_HASH]→Nonemode - Otherwise →
Defaultmode
/src/GZCTF/Utils/FlagGenerator.cs:55-76
Template Parsing
Segment-Based Parsing
Templates are parsed into ordered segments for efficient generation:Flag Segments
Parsing Example
Template:flag{[TEAM_HASH]_admin_{data}}
Parsed segments:
PlainText:flag{TeamHash: (placeholder)PlainText:_admin_LeetText:{data}PlainText:}
/src/GZCTF/Utils/FlagGenerator.cs:314-384
LRU Template Cache
Parsed templates are cached to avoid re-parsing:/src/GZCTF/Utils/FlagGenerator.cs:10-50
Flag Generation
Generation Flow
Core Generation Logic
Flag Generation
/src/GZCTF/Utils/FlagGenerator.cs:407-447
Leet Transformation
Leet Character Mapping
/src/GZCTF/Utils/FlagGenerator.cs:449-467
Entropy Validation
Minimum Entropy Requirements
Flags without[GUID] or [TEAM_HASH] must meet minimum entropy requirements:
Entropy Calculation
flag{Hello}- ~10 bits (REJECTED)flag{HelloWorldCTF2024}- ~45 bits (ACCEPTED)flag{[GUID]}- Infinite (ACCEPTED - bypass)
/src/GZCTF/Utils/FlagGenerator.cs:469-494
Validation Logic
/src/GZCTF/Utils/FlagGenerator.cs:496-516
Flag Checker Service
The FlagChecker is a background service that processes flag submissions:Architecture
- < 2GB RAM or ≤ 3 CPUs → 1 worker
- < 4GB RAM or ≤ 6 CPUs → 2 workers
- Otherwise → 4 workers
/src/GZCTF/Services/FlagChecker.cs:54-68
Submission Processing
Answer Verification
Instance Verification
/src/GZCTF/Services/FlagChecker.cs:97-175
Environment Variable Injection
Docker Injection
/src/GZCTF/Services/Container/Manager/DockerManager.cs:285-287
Kubernetes Injection
/src/GZCTF/Services/Container/Manager/KubernetesManager.cs:64-70
Template Best Practices
High Entropy Templates
Low Entropy Templates
Recommendations
- Use GUID or TEAM_HASH for maximum uniqueness
- Leet templates should be 12+ characters for adequate entropy
- Include numbers and mixed case to increase character variants
- Avoid short words that don’t provide enough entropy
- Test templates using the admin test flag endpoint
Testing Flags
GZCTF provides test flag generation for admins:Test Flag Generation
"TestTeamHash"for[TEAM_HASH]placeholders- Random GUID for
[GUID]placeholders - Random leet transformations
/src/GZCTF/Models/Data/Challenge.cs:145-154
Next Steps
Container Providers
Learn how flags are injected into challenge containers
Traffic Capture
Monitor network traffic to detect flag extraction