mcpField
C
ctf-flag-verification

ctf-flag-verification

github.com/wgpsecSecurity1.8k49 installsUpdated 4d ago
Repository

About ctf-flag-verification

A CTF flag extraction and verification methodology for participants. It emphasizes using Python to assemble, decode, and validate flags rather than relying on error-prone manual handling of long strings.

Key features

  1. 01Programmatic flag extraction and assembly
  2. 02Handling HTML and Base64 encoding
  3. 03Length and format checks
  4. 04Changing extraction methods after failures
  5. 05Diagnosing truncation and character offsets

Use cases

  1. 01Verifying flags extracted through SQL injection
  2. 02Checking command-execution or file-read output
  3. 03Parsing flags from HTML pages
  4. 04Investigating flag length or format mismatches

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/wgpsec/aboutsecurity --skill ctf-flag-verification

After installing, type/ctf-flag-verificationin Claude Code to confirm it loaded.

Bundled filesevals/evals.jsonevals/recall.json

Details

From the project README

CTF Flag 验证方法论

核心原则

LLM 无法可靠地数 hex 字符或拼接长字符串。 所有 flag 的提取、拼接、验证必须用程序(Python)完成,绝不手动拼接。

强制验证流程

1.1 提取 flag 时优先使用程序化方法

SQL 注入(EXTRACTVALUE/UPDATEXML 分段提取):

  • ❌ 不要手动复制各段然后在思考中拼接
  • ✅ 写 Python 脚本自动发请求、自动分段、自动拼接(参考 sql-injection-methodology 中的 Python 模板)
  • ✅ 优先用 UNION SELECT(无截断限制,一次拿完整 flag)

命令执行(RCE / 命令注入):

  • ⚠️ cat /flag.txt 输出可能含 trailing newline → 用 flag.strip() 去除
  • ⚠️ 命令输出可能被 HTML 编码(&lt; → <)→ 用 Python html.unescape() 解码
  • ⚠️ 如果回显被截断,改用 base64 /flag.txt 再解码

文件读取(LFI / 任意文件读取):

  • ⚠️ PHP file_get_contents 可能返回 base64 → 先解码
  • ⚠️ 通过 php://filter 读取时:php://filter/convert.base64-encode/resource=flag → 必须 base64 解码
  • ⚠️ 路径大小写敏感:/flag.txt ≠ /Flag.txt ≠ /FLAG.txt

Web 页面解析:

  • Flag 可能在 HTML 注释 <!-- flag{...} --> 中
  • Flag 可能在 HTML 属性 data-flag="flag{...}" 中
  • Flag 可能在 JavaScript 变量 var flag = "flag{...}" 中
  • 用 Python re.search(r'flag\{[a-fA-F0-9_-]+\}', html_text) 提取
1.2 长度验证

如果你通过 SQL LENGTH() 或其他方式获知了 flag 的预期长度,用 Python 验证:

flag = "flag{...extracted...}"
expected_length = 70  # 从 LENGTH() 获得
assert len(flag) == expected_length, f"MISMATCH! {len(flag)} != {expected_length}"
1.3 格式验证
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 验证失败的处理
  1. 长度不匹配 → 重新提取。EXTRACTVALUE 改用 Python 自动脚本或 UNION SELECT
  2. 格式不对 → 检查 HTML 编码、base64 编码、trailing whitespace
  3. 多次失败 → 切换提取方法(EXTRACTVALUE → UNION → 盲注 → sqlmap --dump)
1.5 常见错误模式
错误原因解决
Flag 少 1-2 字符EXTRACTVALUE 32 字符截断 + 手动拼接Python 自动提取脚本
Flag 多 1-2 字符SUBSTRING 起始位置重叠检查 SUBSTRING 参数
Flag 中间有错字符LLM 误读 hex 字符Python re.search 提取
Flag 含 HTML 实体&amp; 未解码html.unescape()
Flag 有换行/空格命令输出含 whitespace.strip()
Flag 格式不对提取了错误数据重新确认表名/文件路径
1.6 字符级验证问题
  • Flag 中间丢失字符时,检查位置 29-32 区域,可能存在偏移错误导致遗漏字符
  • HTML 实体还原:&lt; 变成 <,&amp; 变成 &,网页显示与源码不同,需解码还原
  • 示例:flag{a3b<c5d&e7f} — 渲染后不同于源码,解码后才是正确 flag

Comments

Markdown supported