ctf-similar-search · git:20261024.904fd35 · 2026-10-24 · sha256 4d64a97efffbb318

ctf-similar-search git:20261024.904fd35A

Immutable. This exact content never changes and is served at /api/v1/blob/4d64a97efffbb318.

---
name: ctf-similar-search
description: Searches for similar CTF challenge writeups using Tavily API for search and content extraction. Use when the user requests finding related challenges, when solve-challenge has failed multiple times and needs reference solutions, or when first identifying a challenge type and seeking examples.
license: MIT
compatibility: Requires filesystem-based agent (Claude Code or similar) with bash and Python 3 with requests and tavily packages.
allowed-tools: Bash Read Write Glob Grep Skill
metadata:
  user-invocable: "true"
  argument-hint: "<challenge-name-or-clues>"
---

# CTF Similar Challenge Search

Search for similar CTF challenge writeups using Tavily API.

## Prerequisites

```bash
pip install requests tavily
```

Set your Tavily API key (from https://tavily.com) before running:

```bash
export TAVILY_API_KEY='tvly-...'
```

## API Overview

This skill provides two interfaces:

| Interface | Purpose | Command |
|-----------|---------|---------|
| **Tavily Search** | Search for writeups and articles | `./scripts/search.sh search <keyword>` |
| **Tavily Extract** | Extract content from URLs | `./scripts/search.sh extract <url1> [url2] ...` |

## Search Workflow

### Step 1: Search with Keywords

Choose keywords based on available information:

#### Scenario 1: Known Competition + Challenge Name
```bash
# Format: [Competition Name] [Challenge Name] — max 3 words
./scripts/search.sh search "DASCTF URL Storage"
./scripts/search.sh search "HGAME baby web"
./scripts/search.sh search "BUUCTF pwn1"
```

#### Scenario 2: Challenge Name Only (no competition info)
```bash
# Use challenge name directly — max 3 words
./scripts/search.sh search "URL Storage"
./scripts/search.sh search "baby overflow"
./scripts/search.sh search "crypto-rsa"
```

#### Scenario 3: Unique Identifiers (code snippets, strings)
```bash
# Use unique, non-trivial strings from the challenge — NO word limit
./scripts/search.sh search "def encrypt_flag(key): return base64"
./scripts/search.sh search "CUSTOM_MAGIC_BYTES"
./scripts/search.sh search "ERROR: invalid padding in AES block"
```

### ⚠️ Critical: 3-Word Limit for Non-Code Queries

**All keyword searches that are NOT code snippets or unique identifier strings MUST NOT exceed 3 words.** This constraint ensures precise, focused queries that return relevant CTF writeup results instead of broad, diluted searches.

| Search Type | Word Limit | Examples |
|-------------|-----------|----------|
| Competition + Challenge name | ≤ 3 words | `"DASCTF URL Storage"`, `"HGAME baby web"` |
| Challenge name only | ≤ 3 words | `"URL Storage"`, `"baby overflow"` |
| Code snippets / strings | **No limit** | `"def encrypt_flag(key): return base64"` |
| Error messages / identifiers | **No limit** | `"CUSTOM_MAGIC_BYTES"`, `"ERROR: invalid padding in AES block"` |

**For competition + challenge name searches**, drop filler words (year numbers, "CTF", "competition", "writeup", "solution") and keep only the 3 most distinctive words:

- ❌ `"HGAME 2024 baby web challenge"` (5 words)
- ✅ `"HGAME baby web"` (3 words)
- ❌ `"DASCTF 2023 URL Storage writeup"` (5 words)
- ✅ `"DASCTF URL Storage"` (3 words)
- ❌ `"PlaidCTF 2025 zero day exploit solution"` (6 words)
- ✅ `"PlaidCTF zero day"` (3 words)

**For code/string searches**, use the entire unique snippet — these are exempt from the word limit:

- ✅ `"def xor_encrypt(data, key):"` (code — exempt)
- ✅ `"ERROR: invalid padding in AES block"` (error string — exempt)
- ✅ `"CUSTOM_MAGIC_BYTES"` (identifier — exempt)

### Keyword Rules

| ✅ Good Keywords | ❌ Bad Keywords |
|------------------|-----------------|
| Competition + Challenge name (≤3 words) | Single vulnerability type (SSRF, XSS) |
| Challenge name (≤3 words) | Generic terms (web, pwn, crypto) |
| Unique code snippets (no word limit) | Full sentences |
| Specific error messages (no word limit) | Articles (a, the, in) |
| Library/framework names | Generic strings (flag{}, etc.) |
| Custom function names | Tool names alone |

**Why avoid these?**
- "SSRF" → returns generic vulnerability explanations, not CTF writeups
- "flag{" → returns millions of unrelated results
- "URL Storage DASCTF" → returns specific CTF challenges

**Why the 3-word limit?**
- Forces precision: only the most distinctive keywords survive
- Filters noise: filler words like "challenge", "writeup", "solution" dilute results
- Improves API efficiency: shorter, focused queries consume fewer credits

**Key principle:** Use keywords that uniquely identify THIS challenge, not the general technique or common patterns. Keep non-code queries to 3 words or fewer.

### Step 2: Review Search Results

The search returns:
- **Answer**: AI-generated summary if available
- **Results**: List of URLs with titles and content previews
- **Credits**: API usage information

### Step 3: Extract Content (Optional)

If a search result looks promising, extract its full content:

```bash
# Single URL
./scripts/search.sh extract "https://example.com/writeup"

# Multiple URLs
./scripts/search.sh extract "https://url1.com" "https://url2.com"
```

### Step 4: Analyze and Pivot

Based on extracted content:
- Identify common techniques used in similar challenges
- Determine if the approach is applicable
- Pivot to category-specific skill if needed

## When to Pivot

- If the challenge is already well-categorized, use the specific `ctf-*` skill
- If you need OSINT techniques, use `ctf-osint`
- If you need to generate a writeup after solving, use `ctf-writeup`

## Quick Start

```bash
# Scenario 1: Competition + Challenge name (≤3 words)
./scripts/search.sh search "DASCTF URL Storage"

# Scenario 2: Challenge name only (≤3 words)
./scripts/search.sh search "URL Storage"

# Scenario 3: Unique identifier from challenge (no word limit)
./scripts/search.sh search "def xor_encrypt(data, key):"
./scripts/search.sh search "ERROR: invalid padding"

# Extract content from promising results
./scripts/search.sh extract "https://ctftime.org/writeup/12345"
```

## Tips

1. **Be specific**: Use competition name + challenge name when available
2. **Use unique strings**: Code snippets, error messages, unique identifiers
3. **Avoid generic terms**: Don't search "SSRF CTF writeup" - too broad
4. **Review first**: Check search results before extracting
5. **Extract selectively**: Only extract URLs that look relevant
6. **Respect the 3-word limit**: For non-code queries, strip filler words and keep only the 3 most distinctive keywords

$ARGUMENTS