Content Discovery Workflows

FFUF Automation Guide

FFUF surfaces what subdomain enumeration and crawlers miss — hidden directories, backup files, admin panels, API endpoints, and virtual hosts that exist on a server but never appear in links or sitemaps. This guide covers how to automate FFUF across multiple targets, chain its output into Nuclei for vulnerability validation, and build content discovery pipelines that run continuously without manual intervention.

Updated May 2026 13 min read Bug Bounty · Fuzzing · Content Discovery

Why FFUF Content Discovery Matters

Subdomain enumeration gives you the hosts. Live host probing confirms they're running web services. But neither tells you what's actually on those hosts. FFUF fills that gap — it brute-forces paths, parameters, and virtual host headers to surface the content that's present but not linked.

The highest-value targets in any bug bounty scope aren't the main application endpoints you can see. They're the /admin panels that weren't removed, the .env files left in web roots, the /api/v1/internal endpoints that were never deprecated, and the backup archives that someone uploaded once and forgot. FFUF finds all of them.

🔍

Hidden Admin Panels

/admin, /dashboard, /manage, /console — control plane endpoints that weren't removed from production servers.

🔍

Backup & Config Files

.env, .git, config.php.bak, database.yml — sensitive files left in web roots during deploys or migrations.

🔍

Unlisted API Endpoints

/api/v1/, /api/internal/, /graphql, /rest/ — API surfaces that weren't documented or deprecated properly.

🔍

Virtual Hosts

Internal applications running on the same IP as the main site, accessible only via the correct Host header.

Essential FFUF Flags for Automation

Most FFUF guides show the basic -u URL/FUZZ -w wordlist.txt pattern and stop there. Automation requires understanding the filtering and output flags that make FFUF usable at scale — especially across dozens of targets where manual review of every response is impossible.

Flag Purpose Automation Use
-ac Auto-calibration — automatically detects and filters baseline response sizes Essential for multi-host automation. Eliminates manual -fs/-fw tuning per host.
-mc Match HTTP status codes (e.g. 200,301,403) Use 200,201,204,301,302,307,401,403 to capture both accessible and restricted paths.
-fc Filter HTTP status codes Use -fc 404 to suppress not-found responses when -ac isn't sufficient.
-fs Filter by response size (bytes) Run a baseline request first, then filter that exact size to remove identical error pages.
-fw Filter by word count in response More reliable than -fs on sites where error page sizes vary slightly.
-rate Max requests per second Set 50-100 for most targets. Reduce to 20-30 on private programs or WAF-protected hosts.
-t Concurrent threads 40-50 is safe for most targets. Higher = faster but more detection risk.
-o / -of Output file and format (json, csv, md) Always use -o with -of json for pipeline integration with jq and Nuclei.
-H Custom header Used for vhost fuzzing: -H 'Host: FUZZ.target.com' and for auth bypass testing.
-recursion Recursive fuzzing on discovered directories Use with -recursion-depth 2 for deeper discovery. Increases runtime significantly.
Always Use -ac First

Auto-calibration (-ac) is the single most important flag for automation. Without it, every target requires a manual baseline request to determine what to filter. With it, FFUF automatically sends calibration requests at startup and sets the right filters. Always start with -ac and only add explicit filters if calibration isn't sufficient.

Real FFUF Automation Workflows

These are production-grade FFUF patterns used in real bug bounty pipelines. Each builds on the previous — start with the one-liner for quick sweeps, use the full script for targets you're actively hunting.

One-liner: Fast directory sweep

The minimum viable content discovery run. Auto-calibration handles false positive filtering automatically. Output goes to JSON for downstream processing.

bashone-liner
ffuf \
  -u https://target.com/FUZZ \
  -w /opt/homebrew/share/seclists/Discovery/Web-Content/raft-medium-directories.txt \
  -ac \
  -mc 200,201,204,301,302,307,401,403 \
  -t 50 \
  -rate 100 \
  -o dirs.json \
  -of json \
  -s

Backup and sensitive file detection

Specifically targets files that developers accidentally leave in web roots. High signal-to-noise ratio — a 200 response on any of these is almost always a real finding worth reporting.

bashbackup file detection
# Target: .env, .git, .bak, config files, archives
ffuf \
  -u https://target.com/FUZZ \
  -w /opt/homebrew/share/seclists/Discovery/Web-Content/raft-medium-files.txt \
  -mc 200,204 \
  -ac \
  -t 40 \
  -rate 60 \
  -o backups.json \
  -of json \
  -s

# Extract findings immediately
jq -r '.results[] | [.status, .length, .url] | @tsv' backups.json

Virtual host fuzzing

Discovers internal applications running on the same IP as the main site. Particularly effective on corporate scopes where internal tooling (Jenkins, Grafana, internal APIs) runs on the same server but requires a specific Host header. Requires knowing the baseline response size first.

bashvhost fuzzing
# Step 1: Get baseline size for a non-existent vhost
curl -s -o /dev/null -w "%{size_download}" \
  -H "Host: nonexistent12345.target.com" \
  https://target.com
# → note the size, use as -fs value below

# Step 2: Fuzz virtual hosts, filter baseline size
ffuf \
  -u https://target.com \
  -H "Host: FUZZ.target.com" \
  -w /opt/homebrew/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
  -fs 1234 \
  -mc 200,301,302,401,403 \
  -t 40 \
  -rate 80 \
  -o vhosts.json \
  -of json \
  -s

Parameter fuzzing

Discovers hidden GET parameters on known endpoints. Useful after directory fuzzing — once you've found an interesting path, parameter fuzzing can reveal additional functionality, internal flags, or debug modes that weren't documented.

bashparameter fuzzing
# Fuzz GET parameters on a discovered endpoint
ffuf \
  -u "https://target.com/api/endpoint?FUZZ=test" \
  -w /opt/homebrew/share/seclists/Discovery/Web-Content/burp-parameter-names.txt \
  -ac \
  -mc 200,201,204 \
  -t 30 \
  -rate 50 \
  -o params.json \
  -of json \
  -s

# POST parameter fuzzing
ffuf \
  -u "https://target.com/api/endpoint" \
  -X POST \
  -d "FUZZ=test" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -w /opt/homebrew/share/seclists/Discovery/Web-Content/burp-parameter-names.txt \
  -ac \
  -mc 200,201,204 \
  -t 30 \
  -s

Full multi-host FFUF pipeline

The complete automation script — reads a live-hosts.txt from your subdomain recon pipeline, runs directory + backup fuzzing against each host, then chains discovered URLs into Nuclei for vulnerability validation.

bashffuf-pipeline.sh
#!/usr/bin/env bash
# PhantomRed — FFUF Multi-Host Content Discovery Pipeline
# Usage: ./ffuf-pipeline.sh live-hosts.txt
# Requires: ffuf, nuclei, jq, seclists

HOSTS="${1:-live-hosts.txt}"
OUT="./ffuf-results/$(date +%Y%m%d_%H%M%S)"
DIRLIST="/opt/homebrew/share/seclists/Discovery/Web-Content/raft-medium-directories.txt"
FILELIST="/opt/homebrew/share/seclists/Discovery/Web-Content/raft-medium-files.txt"
mkdir -p "$OUT"

echo "[*] FFUF pipeline — $(wc -l < $HOSTS) hosts"

while IFS= read -r HOST; do
  SAFE=$(echo "$HOST" | sed 's|https\?://||' | tr '/:' '__')
  mkdir -p "$OUT/$SAFE"
  echo "  → $HOST"

    # Directory fuzzing
  /opt/homebrew/bin/ffuf \
    -u "${HOST}/FUZZ" \
    -w "$DIRLIST" \
    -ac -mc 200,201,204,301,302,307,401,403 \
    -t 50 -rate 100 -timeout 10 \
    -o "$OUT/$SAFE/dirs.json" -of json -s 2>/dev/null || true

    # Backup file detection
  /opt/homebrew/bin/ffuf \
    -u "${HOST}/FUZZ" \
    -w "$FILELIST" \
    -mc 200,204 \
    -t 30 -rate 50 -timeout 10 \
    -o "$OUT/$SAFE/backups.json" -of json -s 2>/dev/null || true

    # Extract all discovered URLs
  /opt/homebrew/bin/jq -r '.results[].url' \
    "$OUT/$SAFE/dirs.json" "$OUT/$SAFE/backups.json" \
    2>/dev/null \
    >> "$OUT/all-discovered-urls.txt" || true

done < "$HOSTS"

# STAGE 2 — Nuclei validation on discovered endpoints
if [[ -s "$OUT/all-discovered-urls.txt" ]]; then
  sort -u "$OUT/all-discovered-urls.txt" -o "$OUT/all-discovered-urls.txt"
  echo "[*] Discovered URLs: $(wc -l < $OUT/all-discovered-urls.txt)"
  echo "[*] Running Nuclei on discovered endpoints..."

  /opt/homebrew/bin/nuclei \
    -l "$OUT/all-discovered-urls.txt" \
    -t vulnerabilities/,exposures/ \
    -severity medium,high,critical \
    -rl 30 \
    -timeout 10 \
    -silent \
    -json \
    -o "$OUT/nuclei-on-ffuf.json" || true
fi

echo "[✓] Done. Results: $OUT/"
FFUF + Nuclei Chain

FFUF discovers endpoints. Nuclei validates whether those endpoints are actually vulnerable. Running Nuclei only on FFUF-discovered URLs (rather than the full host list) dramatically reduces scan noise — you're validating real endpoints, not guessing at paths.

Wordlist Selection for FFUF Automation

The wordlist determines what FFUF finds. Using the wrong wordlist for the wrong target type is the most common reason hunters miss high-value findings. These are the SecLists wordlists that produce the highest signal-to-noise ratio for each use case.

DIR

Directory fuzzing

raft-medium-directories.txt — 30k entries, covers most common paths. Start here on every target before moving to larger lists.

FILE

Backup & file detection

raft-medium-files.txt — targets .env, .bak, .sql, config files. High value, low false positive rate.

API

API endpoint discovery

common-api-endpoints-mazen160.txt — REST and GraphQL endpoint patterns. Use on hosts with detected API frameworks.

PRM

Parameter fuzzing

burp-parameter-names.txt — 6k common parameter names. Run on interesting endpoints discovered during directory fuzzing.

VHT

Virtual host fuzzing

subdomains-top1million-5000.txt — use as Host header wordlist. Discovers internal apps on shared IPs.

BIG

Deep discovery

directory-list-2.3-big.txt — 1.2M entries for thorough coverage. Use only on high-value targets with rate limiting.

Install SecLists

All wordlists above are from SecLists. Install via Homebrew: brew install seclists — installs to /opt/homebrew/share/seclists/. On Linux: apt install seclists or clone from github.com/danielmiessler/SecLists.

Common FFUF Automation Mistakes

!

Not using -ac and getting flooded with false positives

Without auto-calibration, FFUF returns every path that matches your -mc status codes — including generic error pages that return 200. Fix: always start with -ac. If results are still noisy, manually check the baseline response size and add -fs [size].

!

Running the same wordlist on every target type

A wordlist optimized for PHP applications will miss most findings on a Node.js API. Match the wordlist to the detected technology stack. Use httpx -tech-detect output from your recon pipeline to choose the right list — API endpoints for detected frameworks, CMS-specific paths for WordPress/Drupal targets.

!

No rate limiting on multi-host scans

Default FFUF concurrency hits targets aggressively. On a list of 50 hosts with no -rate flag, you're sending thousands of requests per second across the program scope. This triggers WAF blocks and program bans. Fix: set -rate 100 as a maximum and reduce to 30-50 on sensitive targets.

!

Ignoring 403 responses

Many hunters filter out 403s entirely. This misses a significant finding category — a 403 on /admin or /internal/api confirms the path exists and is access-controlled. That's worth testing for auth bypass. Always include 403 in your -mc and triage separately.

!

Not chaining FFUF output into Nuclei

FFUF discovers endpoints — it doesn't validate vulnerability. Most hunters stop at "found /admin" and manually test. The higher-leverage approach: extract all discovered URLs with jq and run them through Nuclei's vulnerabilities/ templates automatically. This turns content discovery into a vulnerability discovery pipeline.

How PhantomRed Automates FFUF Workflows

PhantomRed runs FFUF as part of its autonomous offensive security pipeline. After subdomain enumeration and live host probing, the platform automatically selects wordlists based on detected technology stacks — API endpoint lists for detected API frameworks, CMS-specific wordlists for WordPress or Drupal targets, generic directory lists for unknown stacks.

FFUF-discovered endpoints are automatically fed into the Nuclei scan pipeline for vulnerability validation. You see findings organized by endpoint — not raw FFUF output — with severity scoring applied across the full discovery-to-validation chain. See the Recon Workflow Generator to build custom FFUF pipelines for specific target profiles.

01

Live host input

FFUF receives the validated live-hosts.txt output from the subdomain recon pipeline — only confirmed web services, no dead hosts.

httpx output
02

Tech-stack-aware wordlist selection

Technology fingerprints from httpx -tech-detect inform which wordlists run against each host. API hosts get API endpoint lists. CMS hosts get CMS-specific paths.

auto wordlist routing
03

Directory + backup + vhost fuzzing

All three FFUF modes run per host with auto-calibration and rate limiting applied automatically per target.

ffuf
04

Nuclei validation on discovered endpoints

All discovered URLs are automatically fed into Nuclei for vulnerability template matching. No manual jq extraction required.

nuclei
05

Risk-scored findings dashboard

Findings are deduplicated, severity-scored, and surfaced in your dashboard organized by endpoint — not by tool output order.

phantomred engine

Benefits of Automated FFUF Workflows

Frequently Asked Questions

FFUF is used in bug bounty for content discovery — finding hidden directories, backup files, admin panels, API endpoints, and configuration files that aren't linked from the application surface. It's also used for virtual host enumeration, parameter fuzzing, and validating endpoints discovered during subdomain recon.
Automate FFUF across multiple hosts by reading a live-hosts.txt file line by line and running FFUF against each host with consistent flags. Use -o for JSON output per host, -ac for automatic calibration, and -rate to avoid WAF blocks. Store results in per-host subdirectories for clean organization.
For directory fuzzing, raft-medium-directories.txt from SecLists is the best starting point — it covers the most common paths with minimal noise. For backup files, use raft-medium-files.txt. For API endpoints, use common-api-endpoints-mazen160.txt. Install all via: brew install seclists.
FFUF virtual host fuzzing sends requests with a modified Host header containing each wordlist entry as a subdomain. If the server returns a different response for a specific Host value, that virtual host exists. Get the baseline response size first with a non-existent hostname, then filter that size with -fs [size] to surface real vhosts only.
Start with -ac (auto-calibration) which automatically detects and filters baseline response sizes. For additional filtering use -fc to filter status codes, -fs to filter by response size, and -fw to filter by word count. Running a manual baseline request first helps identify the correct filter values for a specific target.
Extract discovered URLs from FFUF's JSON output using jq: jq -r '.results[].url' ffuf-output.json > endpoints.txt, then feed them into Nuclei: nuclei -l endpoints.txt -t vulnerabilities/ -severity medium,high,critical. This validates FFUF-discovered endpoints for actual exploitable vulnerabilities rather than just confirming their existence.

Automate FFUF Content Discovery with PhantomRed

Run directory fuzzing, vhost discovery, and vulnerability validation autonomously across your entire target scope — no manual pipeline wiring required.