Athena Wiki

CTF Flag Formats

getting startedbeginner

A reference for common CTF flag formats, how to recognize them, and what to do when a flag is tricky.

ctfflagformatsubmitrecognition

CTF Flag Formats

Flag formats are standardized string patterns (typically prefix{content} or key=value) that define the exact submission format for a CTF challenge to ensure consistent validation and scoring. How it works: Organizers define custom prefixes (for example CTF{...} or flag{...}), case sensitivity rules, and special characters; scoreboards perform exact string matching to validate submissions; wrong casing or formatting causes rejection despite correct answer. Why it matters: Prevents ambiguous submissions and ensures consistent scoring; custom formats reduce confusion across events; requires careful reading of competition rules to avoid wasting flags on formatting errors.

Read the rules first

Organizers sometimes use a custom prefix or require specific casing. Copy flags exactly as found - a single character mismatch means rejection.

Common Flag Formats

FormatExampleNotes
flag{...}flag{th1s_1s_a_fl4g}Generic and widely used
CTF{...}CTF{you_found_it}Common event prefix
prefix{...}prefix{easy_flag_1234}Example custom prefix - organizers often pick a unique prefix
event{...}event{d0wn_und3r}Event-specific prefix pattern
id{...}id{spl1t_flag}Event or team-specific prefix
token{...}token{gr34t_ch4ll}Example token-style prefix
bctf{...}bctf{nice_work}Various / legacy formats

Decoding Hidden Flags

Indicators: string ends with = or ==, only uses A–Z a–z 0–9 + / =

Identify

ZmxhZ3t5b3VfZm91bmRfaXR9

All base64-legal characters, length divisible by 4 (with padding).

Decode

import base64
print(base64.b64decode("ZmxhZ3t5b3VfZm91bmRfaXR9").decode())
# → flag{you_found_it}

Or in CyberChef: From Base64 operation.

Watch for multi-layer encoding

# Base64 of Base64
s = "Wm14aFp6dDViM1ZmWm05MWJrUmZhWFE5"
print(base64.b64decode(base64.b64decode(s)).decode())

Flag-Format-First Strategy

When you can identify a flag format early, treat it as a practical tool - not noise. Use the known pattern to guide decoding, cracking, reversing, and submission checks.

Quick checklist

  • Identify: confirm prefix/structure (e.g., flag{...}, CTF{...}, key=value).
  • Normalize: remove surrounding whitespace, convert escapes, and ensure correct encoding (UTF-8). Use repr() to reveal hidden characters.
  • Crib: use the known prefix as a crib in crypto/XOR attacks or brute-force masks.
  • Validate: run a small local submission check if possible (exact match required).

Step-by-step workflow

  1. Confirm format
  • Look for obvious prefixes and braces. If you suspect an alternate prefix, try repr(flag_candidate) to inspect invisible characters before submitting.
  1. Normalize the candidate before any decoding or submission
  • Strip whitespace: flag = flag_candidate.strip()
  • Normalize Unicode: import unicodedata; flag = unicodedata.normalize('NFC', flag)
  • Remove common display-only characters: flag = flag.replace('\u200b', '')
  1. Use the format as a crib in crypto/XOR scenarios
  • If ciphertext likely contains the flag at the start, XOR the first bytes with the known prefix to recover a key fragment:
ct = bytes.fromhex("2a0e1b2d4e...")
prefix = b"flag{"
key_fragment = bytes(a ^ b for a, b in zip(ct, prefix))
  • Extend or repeat the recovered key fragment to decrypt the remainder if the cipher is a repeating XOR.
  1. Apply targeted brute-force masks for hash-style challenges
  • If flags follow flag{word} use mask-based attacks rather than blind brute force (e.g., mask length, character classes).
  1. Reversing and memory inspection
  • Break on string-comparison functions (strcmp, memcmp) to inspect the argument that contains the flag.
  1. Multi-flag challenges and forensic artifacts
  • Search recovered file systems for common filenames (flag.txt, flag1.txt) and scan file contents for the flag prefix: grep -R "flag{" -n ./extracted/.

Quick submission checklist (before clicking submit)

  • repr(flag) to find invisibles
  • flag.strip() to remove leading/trailing whitespace
  • Ensure correct case and braces
  • If submission fails, try flag.encode('utf-8') vs raw bytes if the scoreboard expects a specific encoding

Tools & quick commands

  • Reveal invisibles: python -c "print(repr(open('candidate.txt').read()))"
  • Check for flag in files: grep -R "flag{\|CTF{" -n ./extracted/
  • Simple XOR crib: small Python snippet above

Why this helps

Using the flag format narrows the search space, accelerates key recovery in crypto problems, guides brute-force masks, and prevents wasted submissions. It turns a formatting rule into a practical solving aid.

Troubleshooting Flag Submission

MessageMeaning
Invalid flagWrong format, wrong casing, or hidden characters
Already submittedA teammate submitted this challenge already
WrongIncorrect flag - keep digging

Before resubmitting

Run repr(flag) in Python to expose hidden Unicode or invisible characters. Strip whitespace with flag.strip(). Try alternate casing (flag.upper(), flag.lower()). Confirm you decoded every layer - base64 inside hex inside ROT13 is common.


Last updated on

On this page