FUZZING DEMO TARGET. This is not a real product. Every finding on this host is planted for a talk demo.
Vaultline

How to play

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.

The challenges

#ChallengeGoalFlags in play
C1Content discoveryFind the paths that exist but are not linked from anywhere.-w, -mc, -fw, -ac
C2The interesting non-200Two planted paths do not answer 200. One of them a default run will not even consider.-mc all, -fc
C3RecursionThe wordlist holds names, not paths, so C1 found you 13 things and none of them nested. Descending finds more.-recursion, -recursion-depth
C4Virtual hostsThree hostnames under ffuf.io.fi serve different content from this same address. Find all three.-H "Host: FUZZ.ffuf.io.fi", -fw
C5API versionsThere is more than one version of the API, and only one of them is alive.-w, -mc all
C6Parameter discoveryOne endpoint returns more data when you pass the right query parameter. Find the parameter.-u '.../FUZZ=1', -fw
C7The credential chainOne of the files you found in C1 contains a key. Something else on this host wants that key.-H, -mc
C8Complex requestsFuzz 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
C9The login you cannot replayGet into the admin account. A plain password fuzz returns 403 forever, however long you run it.-preflight, -preflight-var, -preflight-mode
C10Numeric enumerationDocument 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

Hints

Getting started

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

C9, spelled out

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.

Requirements

-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.