Ten challenges. Bring ffuf.
This host is a fuzzing target. Nothing here is real and nothing here is fragile, so point ffuf at it and see what falls out. There are ten things to find, and between them they cover most of what the tool does: wordlists and where the keyword goes, matching against filtering, calibration, recursion, virtual hosts, parameters, raw requests, reading a wordlist off stdin, and requests that have to be built from a previous response.
Answers are meant to be shared. Everyone is solving the same range with the same solutions, so tell the person next to you what you worked out, and ask them when you are stuck.
| # | Challenge | Goal | Flags in play |
|---|---|---|---|
| C1 | Content discovery | Find the paths that exist but are not linked from anywhere. | -w, -mc, -fw, -ac |
| C2 | The interesting non-200 | Two planted paths do not answer 200. One of them a default run will not even consider. | -mc all, -fc |
| C3 | Recursion | The wordlist holds names, not paths, so C1 found you 13 things and none of them nested. Descending finds more. | -recursion, -recursion-depth |
| C4 | Virtual hosts | Three hostnames under ffuf.io.fi serve different content from this same address. Find all three. | -H "Host: FUZZ.ffuf.io.fi", -fw |
| C5 | API versions | There is more than one version of the API, and only one of them is alive. | -w, -mc all |
| C6 | Parameter discovery | One endpoint returns more data when you pass the right query parameter. Find the parameter. | -u '.../FUZZ=1', -fw |
| C7 | The credential chain | One of the files you found in C1 contains a key. Something else on this host wants that key. | -H, -mc |
| C8 | Complex requests | Fuzz the body of a POST that needs a header and a JSON payload. Four queries return documents, the rest return nothing. | -request, -request-proto, -fr |
| C9 | The login you cannot replay | Get into the admin account. A plain password fuzz returns 403 forever, however long you run it. | -preflight, -preflight-var, -preflight-mode |
| C10 | Numeric enumeration | Document ids under /enumerate/ are sequential. Six are readable, three exist but are not, and four thousand are nothing. Find all nine. | -w -, -fs, -ac -acc, -mc 403 |
curl -O https://ffuf.io.fi/wordlists/content.txt curl -O https://ffuf.io.fi/wordlists/passwords.txt ffuf -w content.txt -u https://ffuf.io.fi/FUZZ
Every other challenge is one flag and a filter. This one needs four flags working together,
so here is the shape of it rather than leaving you to assemble it from the hint. The password is
one of the 2000 entries in passwords.txt, the username is
admin, and a successful sign-in answers 302 with the flag in the
X-Flag response header.
The form carries a CSRF token that is valid for exactly one request, so replaying a stale one returns 403 forever. Fetch a fresh one before every attempt.
cat > login.raw <<'EOF' GET /login HTTP/1.1 Host: ffuf.io.fi Accept: text/html EOF ffuf -w passwords.txt -u https://ffuf.io.fi/login -X POST \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "csrf_token=CSRFTOKEN&username=admin&password=FUZZ" \ -preflight login.raw \ -preflight-var 'CSRFTOKEN:name="csrf_token" value="([a-f0-9]+)"' \ -preflight-mode per-request \ -mc 302
Note per-request: the token is single use, so
per-thread would reuse a spent one and put the 403s straight back.
-preflight shipped in ffuf v2.3.0. Older builds do not have the
flag at all: ffuf -h | grep -c preflight should not print 0.