SuperAPI AI Directory

ctf-flag-verification

General & other

View repository

Updated 10-16 09:35

About this skill

CTF Flag Verification Methodology

Core Principles

LLMs cannot reliably count hex characters or concatenate long strings. All flag extraction, concatenation, and verification must be done with programs (Python), never manually concatenated.

Mandatory Verification Process

1.1 When extracting flags, prioritize programmatic methods

SQL injection (EXTRACTVALUE/UPDATEXML segmented extraction):

  • ❌ Do not manually copy each segment and then concatenate them in your reasoning
  • ✅ Write a Python script to automatically send requests, automatically segment, and automatically concatenate (refer to the Python template in sql-injection-methodology)
  • ✅ Prefer UNION SELECT (no truncation limit, retrieve the complete flag in one go)

Command execution (RCE / command injection):

  • ⚠️ cat /flag.txt Output may contain a trailing newline → use flag.strip() to remove
  • ⚠️ Command output may be HTML-encoded (&lt; → <) → use Python html.unescape() to decode
  • ⚠️ If the echo is truncated, switch to base64 /flag.txt and then decode

File reading (LFI / arbitrary file read):

  • ⚠️ PHP file_get_contents May return base64 → decode first
  • ⚠️ When reading via php://filter:php://filter/convert.base64-encode/resource=flag → must base64 decode
  • ⚠️ Paths are case-sensitive:/flag.txt ≠ /Flag.txt ≠ /FLAG.txt

Web page parsing:

  • Flag may be in HTML comments <!-- flag{...} --> middle
  • Flag may be in HTML attribute data-flag="flag{...}" middle
  • Flag may be in JavaScript variable var flag = "flag{...}" middle
  • Use Python re.search(r'flag\{[a-fA-F0-9_-]+\}', html_text) to extract

1.2 Length verification

If you learned the expected length of the flag through SQL LENGTH() or another method, verify it with Python:

flag = "flag{...extracted...}"
expected_length = 70  # 从 LENGTH() 获得
assert len(flag) == expected_length, f"MISMATCH! {len(flag)} != {expected_length}"

1.3 Format verification

import re
flag = "flag{...}"
assert re.match(r'^flag\{[a-fA-F0-9_-]+\}$', flag), f"Invalid format: {flag}"
assert flag.endswith('}'), "Missing } — flag 可能被截断"

1.4 Handling verification failure

  1. Length mismatch → re-extract. For EXTRACTVALUE, switch to a Python automated script or UNION SELECT
  2. Incorrect format → check HTML encoding, base64 encoding, trailing whitespace
  3. Multiple failures → switch extraction methods (EXTRACTVALUE → UNION → blind injection → sqlmap --dump)

1.5 Common error patterns

Error Cause Solution
Flag is missing 1-2 characters EXTRACTVALUE 32-character truncation + manual concatenation Python automated extraction script
Flag has 1-2 extra characters SUBSTRING starting positions overlap Check SUBSTRING parameters
Flag has incorrect characters in the middle LLM misreads hex characters Python re.search extraction
Flag contains HTML entities &amp; not decoded html.unescape()
Flag has newlines/spaces Command output contains whitespace .strip()
Flag format is incorrect Extracted incorrect data Reconfirm table name/file path

1.6 Character-level verification issues

  • When characters are missing in the middle of the Flag, check the area at positions 29-32; there may be an offset error causing missing characters
  • HTML entity restoration:&lt; becomes <,&amp; becomes &, the webpage display differs from the source code and needs to be decoded and restored
  • Example:flag{a3b<c5d&e7f} — after rendering it differs from the source code; only after decoding is it the correct flag