From 10a30e340e593e95f2a0112aab7c507526897c34 Mon Sep 17 00:00:00 2001 From: Dan Guido Date: Wed, 11 Feb 2026 18:49:54 -0500 Subject: [PATCH] Add ffuf-web-fuzzing plugin for authorized penetration testing Import and restructure jthack/ffuf_claude_skill as a curated plugin. Provides expert guidance for ffuf web fuzzing: directory discovery, subdomain enumeration, authenticated fuzzing with raw requests, auto-calibration, wordlist selection, and result analysis. Restructured from the original: - Rewrote SKILL.md with behavioral guidance over reference dumps - Added Rationalizations to Reject, Prerequisites, agent workflow for authenticated fuzzing, authorization confirmation gate - Split references into wordlists.md and request-templates.md - Removed Python helper script (Claude does this natively) - Deduplicated request templates, trimmed out-of-scope wordlists - Added MIT LICENSE matching upstream Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude-plugin/marketplace.json | 10 + README.md | 6 + .../.claude-plugin/plugin.json | 9 + plugins/ffuf-web-fuzzing/LICENSE | 21 +++ plugins/ffuf-web-fuzzing/README.md | 59 ++++++ .../skills/ffuf-web-fuzzing/SKILL.md | 172 ++++++++++++++++++ .../references/request-templates.md | 128 +++++++++++++ .../ffuf-web-fuzzing/references/wordlists.md | 69 +++++++ 8 files changed, 474 insertions(+) create mode 100644 plugins/ffuf-web-fuzzing/.claude-plugin/plugin.json create mode 100644 plugins/ffuf-web-fuzzing/LICENSE create mode 100644 plugins/ffuf-web-fuzzing/README.md create mode 100644 plugins/ffuf-web-fuzzing/skills/ffuf-web-fuzzing/SKILL.md create mode 100644 plugins/ffuf-web-fuzzing/skills/ffuf-web-fuzzing/references/request-templates.md create mode 100644 plugins/ffuf-web-fuzzing/skills/ffuf-web-fuzzing/references/wordlists.md diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index fb0aab5..de2bd58 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -40,6 +40,16 @@ "url": "https://github.com/OthmanAdi" }, "source": "./plugins/planning-with-files" + }, + { + "name": "ffuf-web-fuzzing", + "version": "1.0.0", + "description": "Expert guidance for ffuf web fuzzing during authorized penetration testing, including authenticated fuzzing, auto-calibration, and result analysis", + "author": { + "name": "jthack", + "url": "https://github.com/jthack" + }, + "source": "./plugins/ffuf-web-fuzzing" } ] } diff --git a/README.md b/README.md index 933292c..8bd87ba 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,12 @@ Once merged, the skill is available to all Trail of Bits employees and anyone el |--------|-------------| | [humanizer](plugins/humanizer/) | Identifies and removes AI writing patterns to make text sound natural | +### Security + +| Plugin | Description | +|--------|-------------| +| [ffuf-web-fuzzing](plugins/ffuf-web-fuzzing/) | Expert guidance for ffuf web fuzzing during authorized penetration testing | + ### Development | Plugin | Description | diff --git a/plugins/ffuf-web-fuzzing/.claude-plugin/plugin.json b/plugins/ffuf-web-fuzzing/.claude-plugin/plugin.json new file mode 100644 index 0000000..61d0ea5 --- /dev/null +++ b/plugins/ffuf-web-fuzzing/.claude-plugin/plugin.json @@ -0,0 +1,9 @@ +{ + "name": "ffuf-web-fuzzing", + "version": "1.0.0", + "description": "Expert guidance for ffuf web fuzzing during authorized penetration testing, including authenticated fuzzing, auto-calibration, and result analysis", + "author": { + "name": "jthack", + "url": "https://github.com/jthack" + } +} diff --git a/plugins/ffuf-web-fuzzing/LICENSE b/plugins/ffuf-web-fuzzing/LICENSE new file mode 100644 index 0000000..bd5e50f --- /dev/null +++ b/plugins/ffuf-web-fuzzing/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) jthack + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/plugins/ffuf-web-fuzzing/README.md b/plugins/ffuf-web-fuzzing/README.md new file mode 100644 index 0000000..2aabe3f --- /dev/null +++ b/plugins/ffuf-web-fuzzing/README.md @@ -0,0 +1,59 @@ +# FFUF Web Fuzzing + +Expert guidance for ffuf web fuzzing during authorized penetration testing. + +## Installation + +``` +/plugin install trailofbits/skills-curated/plugins/ffuf-web-fuzzing +``` + +## Prerequisites + +[ffuf](https://github.com/ffuf/ffuf) must be installed: + +```bash +brew install ffuf # macOS +go install github.com/ffuf/ffuf/v2@latest # Go +``` + +## Usage + +The skill activates when you're working on web fuzzing tasks. Ask Claude to: + +- Fuzz directories and files on a target +- Enumerate subdomains +- Discover API endpoints +- Build authenticated fuzzing campaigns with raw requests +- Analyze ffuf JSON output for anomalies + +## Example + +``` +> Fuzz the /api endpoint on staging.example.com for hidden paths + +Claude runs: + ffuf -w /opt/SecLists/Discovery/Web-Content/api/api-endpoints.txt \ + -u https://staging.example.com/api/FUZZ \ + -ac -c -v -o results.json + +Then analyzes the results, highlighting anomalous status codes, +size outliers, and interesting endpoint names. +``` + +## What It Covers + +- **Core fuzzing** -- directory/file discovery, subdomain enumeration, parameter fuzzing +- **Authenticated fuzzing** -- raw request templates for JWT, OAuth, cookies, API keys +- **Auto-calibration** -- why `-ac` is mandatory and how it works +- **Result analysis** -- guidance for identifying anomalies in JSON output +- **Wordlist selection** -- which SecLists wordlist for which scenario +- **Rate limiting** -- appropriate settings for production vs. staging vs. lab + +## Safety + +This skill is for authorized security testing only. It includes rate limiting guidance and encourages responsible testing practices. Only use against systems you own or have explicit written permission to test. + +## Credits + +Original skill by [jthack/ffuf_claude_skill](https://github.com/jthack/ffuf_claude_skill). Restructured for the Trail of Bits curated skills marketplace. diff --git a/plugins/ffuf-web-fuzzing/skills/ffuf-web-fuzzing/SKILL.md b/plugins/ffuf-web-fuzzing/skills/ffuf-web-fuzzing/SKILL.md new file mode 100644 index 0000000..584a8be --- /dev/null +++ b/plugins/ffuf-web-fuzzing/skills/ffuf-web-fuzzing/SKILL.md @@ -0,0 +1,172 @@ +--- +name: ffuf-web-fuzzing +description: | + Expert guidance for ffuf web fuzzing during authorized penetration testing. Covers directory discovery, subdomain enumeration, parameter fuzzing, authenticated fuzzing with raw requests, auto-calibration, and result analysis. Use when running ffuf scans, analyzing ffuf output, or building fuzzing strategies for web targets. +allowed-tools: + - Bash + - Read + - Write + - Edit + - Grep + - Glob +--- + +# FFUF Web Fuzzing + +Guidance for using ffuf (Fuzz Faster U Fool) effectively during authorized penetration testing. + +## Prerequisites + +ffuf must be installed: `brew install ffuf` (macOS) or `go install github.com/ffuf/ffuf/v2@latest` + +## When to Use + +- Running directory, file, or subdomain discovery against web targets +- Fuzzing API endpoints, parameters, or POST data +- Authenticated fuzzing with raw HTTP requests +- Analyzing ffuf JSON output for anomalies and interesting findings +- Building fuzzing strategies (wordlist selection, filtering, rate limiting) +- IDOR testing with authenticated sessions + +## When NOT to Use + +- Target system is not in scope or authorization is unclear +- Passive reconnaissance is more appropriate (use OSINT tools instead) +- The target is a production system and rate limiting hasn't been configured +- You need a full vulnerability scanner (use Burp Suite, Nuclei, etc.) +- Testing for logic flaws that require multi-step interaction + +## Rationalizations to Reject + +- "Auto-calibration is optional" -- `-ac` is mandatory. Without it, results are buried in false positives and analysis is wasted effort. +- "More threads = faster results" -- Hammering a target with `-t 200` triggers WAFs, gets you blocked, and may crash staging environments. Start with `-t 10 -rate 2` for production targets. +- "I'll filter later" -- Set up filtering before the scan. Running a 220k wordlist without filters and then trying to grep through the noise is backwards. +- "The default wordlist is fine" -- Wordlist selection is the most important decision. A generic wordlist misses technology-specific paths. See [references/wordlists.md](references/wordlists.md). +- "Raw requests are too much work" -- For authenticated fuzzing, `--request req.txt` is simpler and more reliable than chaining `-H` and `-b` flags. Capture once, fuzz many times. + +## Critical Rules + +1. **Always use `-ac`** (auto-calibration) unless you have a specific, documented reason not to +2. **Always save output** with `-o results.json` for later analysis +3. **Rate limit production targets** with `-rate` and `-t` flags +4. **Use `--request` for auth** -- raw request files beat command-line header chains +5. **Confirm authorization first** -- before running any scan, verify the user has written permission for the target. Ask if unclear. + +## Core Concepts + +### The FUZZ Keyword + +```bash +# In URL path +ffuf -w wordlist.txt -u https://target.com/FUZZ -ac + +# In headers +ffuf -w wordlist.txt -u https://target.com -H "Host: FUZZ.target.com" -ac + +# In POST body +ffuf -w wordlist.txt -X POST -d "user=admin&pass=FUZZ" -u https://target.com/login -ac + +# Multiple positions with custom keywords +ffuf -w endpoints.txt:EP -w ids.txt:ID -u https://target.com/EP/ID -mode pitchfork -ac +``` + +### Auto-Calibration + +`-ac` automatically detects and filters repetitive false-positive responses. It adapts to the target's specific behavior and removes noise from dynamic content. + +```bash +ffuf -w wordlist.txt -u https://target.com/FUZZ -ac # Standard +ffuf -w wordlist.txt -u https://target.com/FUZZ -ach # Per-host (multi-host scans) +ffuf -w wordlist.txt -u https://target.com/FUZZ -acc "404" # Custom calibration string +``` + +## Common Patterns + +### Directory Discovery + +```bash +ffuf -w /opt/SecLists/Discovery/Web-Content/raft-large-directories.txt \ + -u https://target.com/FUZZ -e .php,.html,.txt,.bak \ + -ac -c -v -o results.json +``` + +### Subdomain Enumeration + +```bash +ffuf -w /opt/SecLists/Discovery/DNS/subdomains-top1million-5000.txt \ + -u https://FUZZ.target.com -ac -c -v -o results.json +``` + +### API Endpoint Discovery + +```bash +ffuf -w /opt/SecLists/Discovery/Web-Content/api/api-endpoints.txt \ + -u https://api.target.com/v1/FUZZ \ + -H "Authorization: Bearer YOUR_TOKEN_HERE" -mc 200,201 -ac -c +``` + +### Authenticated Fuzzing with Raw Requests + +Capture a full authenticated request, save to `req.txt`, insert `FUZZ`: + +```http +POST /api/v1/users/FUZZ HTTP/1.1 +Host: target.com +Authorization: Bearer YOUR_TOKEN_HERE +Cookie: session=YOUR_SESSION_ID +Content-Type: application/json + +{"action":"view","id":"1"} +``` + +```bash +ffuf --request req.txt -w wordlist.txt -ac -o results.json +``` + +See [references/request-templates.md](references/request-templates.md) for pre-built templates covering bearer tokens, session cookies, API keys, and GraphQL. + +### Authenticated Fuzzing: Agent Workflow + +Authenticated fuzzing requires real credentials that the agent cannot obtain independently. When the user asks for authenticated fuzzing: + +1. Ask the user to provide ONE of: + - A raw HTTP request file (`req.txt`) with auth headers already included + - A curl command from browser DevTools (convert it to `req.txt` format) + - Individual credentials (Bearer token, session cookie, API key) +2. If given a curl command, convert it to raw HTTP request format and write to `req.txt` +3. If given individual credentials, use a template from [references/request-templates.md](references/request-templates.md) and substitute real values +4. Never fabricate or guess authentication tokens + +### IDOR Testing + +```bash +ffuf --request req.txt -w <(seq 1 10000) -ac -mc 200 -o idor_results.json +``` + +## Rate Limiting + +| Environment | Flags | Notes | +|-------------|-------|-------| +| Production (stealth) | `-rate 2 -t 10` | Avoid WAF triggers | +| Production (normal) | `-rate 10 -t 20` | Balanced | +| Staging/Dev | `-rate 50 -t 40` | Faster | +| Local/Lab | No limit, `-t 100` | Maximum speed | + +## Analyzing Results + +Save output as JSON (`-o results.json`), then read the file and focus on: + +- **Anomalous status codes** -- anything other than the baseline 404/403 +- **Size outliers** -- responses significantly larger or smaller than average +- **Interesting keywords** in URLs -- admin, api, backup, config, .git, .env +- **Timing anomalies** -- slow responses may indicate SQL injection or heavy processing +- **Follow-up targets** -- interesting findings warrant deeper fuzzing + +Use `-fs` to filter by response size and `-fc` to filter by status code when auto-calibration isn't sufficient. Run `ffuf -h` for the full list of match/filter flags. + +## References + +- [Wordlist selection guide](references/wordlists.md) -- recommended SecLists by scenario +- [Authenticated request templates](references/request-templates.md) -- pre-built req.txt for bearer tokens, cookies, API keys +- [ffuf official docs](https://github.com/ffuf/ffuf/wiki) +- [SecLists](https://github.com/danielmiessler/SecLists) diff --git a/plugins/ffuf-web-fuzzing/skills/ffuf-web-fuzzing/references/request-templates.md b/plugins/ffuf-web-fuzzing/skills/ffuf-web-fuzzing/references/request-templates.md new file mode 100644 index 0000000..486b9d1 --- /dev/null +++ b/plugins/ffuf-web-fuzzing/skills/ffuf-web-fuzzing/references/request-templates.md @@ -0,0 +1,128 @@ +# Authenticated Request Templates + +Pre-built `req.txt` templates for common authenticated fuzzing scenarios. Save the template, replace placeholders with real values, insert `FUZZ` where needed. + +## Bearer Token (JWT / OAuth) + +```http +GET /api/v1/users/FUZZ HTTP/1.1 +Host: api.target.com +Authorization: Bearer YOUR_TOKEN_HERE +Accept: application/json +Content-Type: application/json +``` + +```bash +ffuf --request req.txt -w wordlist.txt -ac -mc 200,201 -o results.json +``` + +## Session Cookie + CSRF Token + +```http +POST /api/account/update HTTP/1.1 +Host: app.target.com +Cookie: sessionid=YOUR_SESSION_ID; csrftoken=YOUR_CSRF_TOKEN +X-CSRF-Token: YOUR_CSRF_TOKEN +Content-Type: application/x-www-form-urlencoded + +field=FUZZ&action=update +``` + +```bash +ffuf --request req.txt -w payloads.txt -ac -fc 403 -o results.json +``` + +## API Key Header + +```http +GET /v2/data/FUZZ HTTP/1.1 +Host: api.target.com +X-API-Key: YOUR_API_KEY_HERE +Accept: application/json +``` + +```bash +ffuf --request req.txt -w endpoints.txt -ac -mc 200 -o results.json +``` + +## POST JSON with Auth + +```http +POST /api/v1/query HTTP/1.1 +Host: api.target.com +Authorization: Bearer YOUR_TOKEN_HERE +Content-Type: application/json +Accept: application/json + +{"query":"FUZZ","limit":100,"offset":0} +``` + +```bash +ffuf --request req.txt -w sqli-payloads.txt -ac -fr "error" -o results.json +``` + +## Multiple FUZZ Points (Custom Keywords) + +```http +GET /api/v1/users/USER_ID/documents/DOC_ID HTTP/1.1 +Host: api.target.com +Authorization: Bearer YOUR_TOKEN_HERE +Accept: application/json +``` + +```bash +ffuf --request req.txt \ + -w user_ids.txt:USER_ID \ + -w doc_ids.txt:DOC_ID \ + -mode pitchfork \ + -ac -mc 200 \ + -o idor_results.json +``` + +## GraphQL Query + +```http +POST /graphql HTTP/1.1 +Host: api.target.com +Authorization: Bearer YOUR_TOKEN_HERE +Content-Type: application/json +Accept: application/json + +{"query":"query { user(id: \"FUZZ\") { id username email role } }","variables":{}} +``` + +```bash +ffuf --request req.txt -w user-ids.txt -ac -mc 200 -mr '"email"' -o results.json +``` + +## How to Capture Your Own Request + +### From Burp Suite +1. Intercept the authenticated request +2. Right-click > "Copy to file" > save as `req.txt` +3. Replace the fuzz target with `FUZZ` + +### From Browser DevTools +1. Open DevTools (F12) > Network tab +2. Perform the authenticated action +3. Right-click the request > Copy > Copy as cURL +4. Convert to raw HTTP format, insert `FUZZ` + +### From a curl command +```bash +# If you have: +curl 'https://api.target.com/users/123' -H 'Authorization: Bearer TOKEN' + +# Convert to: +GET /users/FUZZ HTTP/1.1 +Host: api.target.com +Authorization: Bearer TOKEN +``` + +## Tips + +- ffuf adjusts `Content-Length` automatically +- Use custom keywords (`USER_ID`, `DOC_ID`) with `-w wordlist.txt:KEYWORD` for multiple fuzz points +- Test your `req.txt` with a single-value wordlist first to verify it works +- Have a token refresh strategy ready for short-lived tokens +- Default protocol is HTTPS; use `-request-proto http` for HTTP-only targets diff --git a/plugins/ffuf-web-fuzzing/skills/ffuf-web-fuzzing/references/wordlists.md b/plugins/ffuf-web-fuzzing/skills/ffuf-web-fuzzing/references/wordlists.md new file mode 100644 index 0000000..21dbe00 --- /dev/null +++ b/plugins/ffuf-web-fuzzing/skills/ffuf-web-fuzzing/references/wordlists.md @@ -0,0 +1,69 @@ +# Wordlist Selection Guide + +Choose wordlists based on the target stack and engagement scope. All paths are relative to your SecLists installation directory. + +## By Scenario + +### Directory and File Discovery + +| Scope | Wordlist | Entries | When to use | +|-------|----------|---------|-------------| +| Quick scan | `Discovery/Web-Content/common.txt` | ~4.6k | Initial recon, time-limited engagements | +| Standard | `Discovery/Web-Content/directory-list-2.3-medium.txt` | ~220k | Default for most engagements | +| Thorough | `Discovery/Web-Content/directory-list-2.3-big.txt` | ~1.2M | High-value targets, long engagements | +| Raft (dirs) | `Discovery/Web-Content/raft-large-directories.txt` | - | Alternative to directory-list, good coverage | +| Raft (files) | `Discovery/Web-Content/raft-large-files.txt` | - | Focused on file discovery | + +### API Testing + +| Wordlist | When to use | +|----------|-------------| +| `Discovery/Web-Content/api/api-endpoints.txt` | REST API endpoint discovery | +| `Discovery/Web-Content/common-api-endpoints-mazen160.txt` | Broader API path fuzzing | +| `Discovery/Web-Content/swagger-parameters.txt` | Finding Swagger/OpenAPI docs | + +### Subdomain Discovery + +| Wordlist | Entries | When to use | +|----------|---------|-------------| +| `Discovery/DNS/subdomains-top1million-5000.txt` | 5k | Quick subdomain check | +| `Discovery/DNS/subdomains-top1million-20000.txt` | 20k | Standard engagement | +| `Discovery/DNS/subdomains-top1million-110000.txt` | 110k | Thorough enumeration | +| `Discovery/DNS/namelist.txt` | - | Combined/alternative list | + +### Parameter Names + +| Wordlist | When to use | +|----------|-------------| +| `Discovery/Web-Content/burp-parameter-names.txt` | GET/POST parameter discovery | +| `Discovery/Web-Content/raft-large-words.txt` | Broader parameter fuzzing | + +### Backup and Config Files + +| Wordlist | When to use | +|----------|-------------| +| `Discovery/Web-Content/backup-files-only.txt` | Finding .bak, .old, .save files | +| `Discovery/Web-Content/Common-DB-Backups.txt` | Database dump discovery | + +### Technology-Specific + +| Wordlist | Stack | +|----------|-------| +| `Discovery/Web-Content/PHP.fuzz.txt` | PHP applications | +| `Discovery/Web-Content/IIS.fuzz.txt` | ASP/ASP.NET on IIS | +| `Discovery/Web-Content/Apache.fuzz.txt` | Apache web servers | +| `Discovery/Web-Content/git-head-potential-file-exposure.txt` | Git repo exposure | + +## File Extensions by Technology + +Add with `-e` flag. Match extensions to the target stack. + +| Stack | Extensions | +|-------|-----------| +| PHP | `.php .php3 .php4 .php5 .phtml .phps` | +| ASP/ASP.NET | `.asp .aspx .ashx .asmx .axd` | +| JSP/Java | `.jsp .jspx .jsw .jsv .jspf` | +| Python | `.py .pyc .pyo` | +| Ruby | `.rb .rhtml` | +| Node.js | `.js .json` | +| Backup/Interesting | `.bak .backup .old .save .tmp .swp .git .env .config .conf .log .sql .db .sqlite` |