$npx -y skills add ljagiello/ctf-skills --skill ctf-writeupGenerates a single standardized submission-style CTF writeup for competition handoff and organizer review. Use after solving a CTF challenge to document the solution steps, tools used, and lessons learned in a structured format.
| 1 | # CTF Write-up Generator |
| 2 | |
| 3 | Generate a standardized submission-style CTF writeup for a solved challenge. |
| 4 | |
| 5 | Default behavior: |
| 6 | |
| 7 | - During an active competition, optimize for speed, clarity, and reproducibility |
| 8 | - Keep writeups short enough that a teammate or organizer can validate the solve quickly |
| 9 | - Always produce a `submission`-style writeup |
| 10 | - Prefer one complete solve script from challenge data to final flag |
| 11 | |
| 12 | ## Workflow |
| 13 | |
| 14 | ### Step 1: Gather Information |
| 15 | |
| 16 | Collect the following from the current session, challenge files, and user input: |
| 17 | |
| 18 | 1. **Challenge metadata** — name, CTF event, category, difficulty, points, flag format |
| 19 | 2. **Solution artifacts** — exploit scripts, payloads, screenshots, command output |
| 20 | 3. **Timeline** — key steps taken, dead ends, pivots |
| 21 | |
| 22 | ```bash |
| 23 | # Scan for exploit scripts and artifacts |
| 24 | find . -name '*.py' -o -name '*.sh' -o -name 'exploit*' -o -name 'solve*' | head -20 |
| 25 | # Check for flags in output files |
| 26 | grep -rniE '(flag|ctf|eno|htb|pico)\{' . 2>/dev/null |
| 27 | ``` |
| 28 | |
| 29 | ### Step 2: Generate Write-up |
| 30 | |
| 31 | Write the writeup file as `writeup.md` (or `writeup-<challenge-name>.md`) using the submission template below. |
| 32 | |
| 33 | --- |
| 34 | |
| 35 | ## Templates |
| 36 | |
| 37 | ### Submission Format |
| 38 | |
| 39 | ```markdown |
| 40 | --- |
| 41 | title: "<Challenge Name>" |
| 42 | ctf: "<CTF Event Name>" |
| 43 | date: YYYY-MM-DD |
| 44 | category: web|pwn|crypto|reverse|forensics|osint|malware|misc |
| 45 | difficulty: easy|medium|hard |
| 46 | points: <number> |
| 47 | flag_format: "flag{...}" |
| 48 | author: "<your name or team>" |
| 49 | --- |
| 50 | |
| 51 | # <Challenge Name> |
| 52 | |
| 53 | ## Summary |
| 54 | |
| 55 | <1-2 sentences: what the challenge was and the core technique. Keep it direct.> |
| 56 | |
| 57 | ## Solution |
| 58 | |
| 59 | ### Step 1: <Action> |
| 60 | |
| 61 | <Explain the key observation in 3-8 short lines. Keep it direct.> |
| 62 | |
| 63 | \`\`\`python |
| 64 | <one complete solving script from provided challenge data to printing the final flag> |
| 65 | \`\`\` |
| 66 | |
| 67 | ### Step 2: <Action> (optional) |
| 68 | |
| 69 | <Only add this when a second short step genuinely helps readability, such as separating the core observation from final verification.> |
| 70 | |
| 71 | ### Step 3: <Action> (optional) |
| 72 | |
| 73 | <Use only if the challenge really needs it. Keep the total number of steps small.> |
| 74 | |
| 75 | ## Flag |
| 76 | |
| 77 | \`\`\` |
| 78 | flag{example_flag_here} |
| 79 | \`\`\` |
| 80 | ``` |
| 81 | |
| 82 | Guidance: |
| 83 | |
| 84 | - Prefer 1-3 short steps total |
| 85 | - Keep code to the smallest complete solving script |
| 86 | - Do not split "recover secret", "derive key", and "decrypt flag" into separate partial snippets |
| 87 | - The script should start from the challenge data and end by printing the flag |
| 88 | - Avoid long background sections |
| 89 | - Avoid dead ends unless they explain a key pivot |
| 90 | - Avoid multiple alternative solves; pick one clean path |
| 91 | - Redact the flag only if the user explicitly asks for redaction |
| 92 | |
| 93 | --- |
| 94 | |
| 95 | ## Best Practices Checklist |
| 96 | |
| 97 | Before finalizing the writeup, verify: |
| 98 | |
| 99 | - [ ] **Metadata complete** — title, CTF, date, category, difficulty, points, author all filled |
| 100 | - [ ] **Flag handling matches request** — keep the real flag unless the user asked for redaction |
| 101 | - [ ] **Reproducible steps** — a reader can follow your writeup and reproduce the solution |
| 102 | - [ ] **Code is runnable** — exploit scripts include all imports, correct variable names, and comments |
| 103 | - [ ] **No sensitive data** — no real credentials, API keys, or private infrastructure details |
| 104 | - [ ] **Length stays concise** — the writeup is short enough for fast review |
| 105 | - [ ] **Tools and versions noted** — mention specific tool versions if behavior depends on them |
| 106 | - [ ] **Proper attribution** — credit teammates, referenced writeups, or tools that were essential |
| 107 | - [ ] **Grammar and formatting** — consistent heading levels, code blocks have language tags |
| 108 | |
| 109 | ## Quality Guidelines |
| 110 | |
| 111 | **DO:** |
| 112 | - Explain just enough for fast verification |
| 113 | - Include one complete solving path, not multiple alternative routes |
| 114 | - Include one complete script that goes all the way to the final flag |
| 115 | - Show actual output (truncated if very long) to prove the approach worked |
| 116 | - Tag code blocks with language (`python`, `bash`, `sql`, etc.) |
| 117 | - Keep the main path front-loaded so a reader can validate it quickly |
| 118 | |
| 119 | **DON'T:** |
| 120 | - Copy-paste raw terminal dumps without explanation |
| 121 | - Paste several partial snippets that force the reader to reconstruct the final solve |
| 122 | - Leave placeholder text in the final writeup |
| 123 | - Include irrelevant tangents that don't contribute to the solution |
| 124 | - Assume the reader knows the specific challenge setup |
| 125 | |
| 126 | ## Challenge |
| 127 | |
| 128 | $ARGUMENTS |