wfuzz は Xavier Mendez (@xmendez) を中心に開発された Python 製の Web ファジングツール。今でこそ Go 製の ffuf が定番だが、その 設計思想の土台を作った「元祖」が wfuzz だ。やることは ffuf と同じく HTTP リクエストの一部を辞書で総当たりして「存在するもの」を炙り出すこと。リクエスト内に置いた FUZZ という目印を ペイロード (ワードリストや数値レンジ) の各要素で順に置き換え、返ってきたレスポンスの違いから「隠れたディレクトリ・ファイル・パラメータ・サブドメイン」を発見する。Python ゆえ ffuf より低速だが、ペイロード・エンコーダ・イテレータ・フィルタ式言語を組み合わせる柔軟性は今も学ぶ価値が大きい。
wfuzz とは — FUZZ キーワードとペイロード #
wfuzz を理解する鍵は 2 つ、FUZZ キーワードとペイロード (-z)。リクエストのどこにこの文字列を置いても、wfuzz はそこをペイロードの 1 要素ずつで置き換えてリクエストを送る。置く場所によって「何を探すか」が変わる。
FUZZ を置く場所 |
何を探すことになるか |
|---|---|
URL パス末尾 (/FUZZ) |
ディレクトリ / ファイル探索 |
クエリ / ボディの値 (?id=FUZZ) |
パラメータ値の総当たり |
クエリのキー (?FUZZ=x) |
隠しパラメータ名の発見 |
Host ヘッダ (Host: FUZZ.target) |
vhost / サブドメイン列挙 |
複数の位置を同時に総当たりしたいときは、2 個目以降を FUZ2Z / FUZ3Z … と書き、-z を並べた順に対応させる。wfuzz 自体は「当たり/外れ」を文脈で理解しているわけではなく、レスポンスの違いを頼りに人間が当たりを判定する — だからこそ後述の「show/hide フィルタ」が生命線になる。
「FUZZ を任意位置に置いて辞書で置換する」という発想は wfuzz が先で、ffuf はそれを Go で高速に再実装したもの。だから両者は概念がよく似ている一方、オプション体系は別物。例えばステータスコードで絞るのは ffuf が -mc / -fc、wfuzz が --sc / --hc。混同しやすいので本稿では wfuzz の流儀を明確に区別する。
法的・倫理的な注意 #
wfuzz は短時間に数百〜数万のリクエストを送る。これは技術的には DoS に近い負荷であり、対象によっては明確な攻撃と見なされる。許可なく他人のサーバへ wfuzz を撃つことは、日本の不正アクセス禁止法や業務妨害に問われ得る違法行為になりうる。
- 自分が所有・管理しているサーバ / アプリ — ローカルの検証環境、自分が契約している VPS、隔離した学習用ラボ
- 書面で明示的に許可された対象 — ペネトレーションテスト契約や脆弱性診断契約で、スコープ (対象ホスト・期間・レート制限) が文書化されているもの
- 正規の学習プラットフォーム — Hack The Box、TryHackMe、PortSwigger Web Security Academy など、運営がファジングを許可している環境
辞書を高速に投げるツールほど「軽い気持ちで他所に撃つ」ことが致命傷になる。レート制御 (-s / -t) を設定せず本番サービスへ撃てば、相手が落ちて損害賠償・刑事責任という最悪の結末もあり得る。対象と許可を必ず先に確認すること。
ペイロード (-z) — wfuzz の心臓部 #
ffuf がワードリスト一本 (-w) を中心に据えるのに対し、wfuzz は 「どんな素材を流し込むか」をペイロード型 (-z) で選ぶのが特徴。書式は -z 型,パラメータ。
| 主なペイロード型 | 書き方 | 用途 |
|---|---|---|
file |
-z file,wordlist.txt |
ワードリストの各行を流す (最も基本) |
range |
-z range,1-100 |
連番を流す (ID 総当たり等) |
list |
-z list,admin-login-backup |
ハイフン区切りの即席リスト |
hex_range |
-z hex_range,0-ff |
16 進レンジ |
-w wordlist.txt は -z file,wordlist.txt の短縮形。ffuf と同じ感覚で -w を使ってもよい。
$ wfuzz -z file,/usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt https://target/FUZZ
# -z file,LIST ペイロードに file 型でワードリストを指定
# 末尾の URL の FUZZ が各行で置換される
# (-w LIST と書いても同じ)複数の -z を並べると FUZZ / FUZ2Z … に順番で対応する。組み合わせ方は イテレータ (-m) で選ぶ — Burp Suite Intruder の攻撃モードに相当する。
| イテレータ (`-m`) | 挙動 | 典型用途 |
|---|---|---|
product (既定) | 全ペイロードの総組み合わせ (直積) | ユーザ名 × パスワードの全パターン |
zip | 各リストを同じ位置で並行に消費 | 対になった user/pass ペアの検証 |
chain | 複数リストを1 本に連結して順に消費 | 複数辞書をまとめて 1 ポジションに投入 |
$ wfuzz -z file,users.txt -z file,pass.txt -m product \
-d "username=FUZZ&password=FUZ2Z" https://target/login
# FUZZ = users.txt、FUZ2Z = pass.txt
# -m product で全組み合わせ(-m zip なら同じ行番号同士のペア)show/hide フィルタ — 偽陽性をいかに消すか #
wfuzz を「ただ撃つだけ」だと、結果が 偽陽性 (false positive) の海に沈む。多くのサーバは存在しないパスにも 200 でカスタム 404 ページ (soft-404) を返したり、全リクエストに同じ応答を返したりするからだ。ここを制御するのが show 系 (表示するものを限定) と hide 系 (除外するもの)。wfuzz を使いこなせるかどうかは、ほぼこの絞り込みにかかっている。
⚠️ ここが ffuf との最大の違い。ffuf はマッチャ
-m*/ フィルタ-f*だが、wfuzz は show--s*/ hide--h*。-mcは wfuzz には無い (それは ffuf の構文)。wfuzz でステータスコードを絞るなら--sc/--hcを使う。
| 観点 | show (これだけ表示) | hide (これを除外) |
|---|---|---|
| ステータスコード | --sc 200,301,403 |
--hc 404,400 |
| 文字数 (chars) | --sh 1234 |
--hh 0 |
| 単語数 (words) | --sw 56 |
--hw 0 |
| 行数 (lines) | --sl 10 |
--hl 10 |
| 本文の正規表現 | --ss "regex" |
--hs "regex" |
たとえば HTTP 200 のものだけを見たいなら --sc 200、逆に 404 を消したいなら --hc 404。h は chars (バイト数)、w は words、l は lines に対応する点に注意 (ffuf の -ms は size だが wfuzz は文字数 --sh/--hh)。
$ wfuzz -w wordlist.txt --hh 0 https://target/FUZZ
# --hh 0 本文 0 文字(空応答)を非表示にする
# --hc 404 404 を消す / --sc 200 200 だけ表示
# --hw 56 外れが常に 56 words なら、それを丸ごと除外存在しないパス (例: /zzz-not-exist-123) に手で 1 回アクセスし、その ステータス・文字数・単語数を確認する。外れが「200 / 1234 chars / 56 words」で一定なら、--hh 1234 や --hw 56 で丸ごと除外すれば、残ったものが当たり候補になる。文字数・単語数フィルタはステータスコードより強力なことが多い。
外れの応答が候補ごとに微妙にブレて固定値で弾けないとき、wfuzz は 強力なフィルタ式言語 (--filter) で論理条件を書ける。これは ffuf には無い wfuzz ならではの武器だ。フィールドは c (code) / l (lines) / w (words) / h (chars) で、and / or / = / != / > / < / =~ (正規表現) を組み合わせる。
$ wfuzz -w wordlist.txt --filter "c=200 and h>100" https://target/FUZZ
# ステータス 200 かつ 本文 100 文字超 のものだけ残す
# --filter "c=200 and l!=5" 200 だが行数 5 の外れは除く
# --filter "w=12 or w=34" 語数 12 か 34 のものを拾う実戦モード — 探索 / パラメータ / 総当たり #
FUZZ をどこに置くかでモードが切り替わる。代表的な 3 つ。
パラメータ名 / 値の発見 #
URL のクエリ部に FUZZ を置けば、アプリが受け付ける 隠しパラメータ名や有効な値を探せる (例: LFI を誘発する file、デバッグ用 debug など)。
$ wfuzz -w params.txt --hh 0 "https://target/page?FUZZ=test"
# 反応のあった(本文長が変わった)パラメータ名だけが残るPOST データ / ログイン総当たり #
-d でボディに FUZZ を置けば、ログインフォームのパスワード総当たりができる (メソッドは -d 指定で自動的に POST)。失敗レスポンスを --hc / --hh で弾き、成功だけを残す。
$ wfuzz -w passwords.txt \
-d "username=admin&password=FUZZ" \
--hc 200 https://target/login
# ログイン失敗が 200 で返るなら、それを隠せば成功 (302 等) が残る数値レンジで ID を総当たり #
-z range を使えば辞書ファイル無しで連番を流せる。IDOR (アクセス制御の不備) の検証などに向く。
$ wfuzz -z range,1-500 --sc 200 "https://target/user?id=FUZZ"
# 1〜500 を id に流し、200 が返る有効な id だけ表示エンコーダ・出力・運用 Tips #
ペイロードを送信前に変換したいときは、-z の第 3 フィールドにエンコーダを書く (例: -z file,words.txt,urlencode)。利用可能なエンコーダは wfuzz -e encoders で一覧できる。
| エンコーダ例 | 効果 |
|---|---|
urlencode |
URL エンコード (記号を含む値を安全に送る) |
base64 |
Base64 化 |
md5 / sha1 |
ハッシュ化した値を送る |
none |
無変換 (既定) |
撃ち方の調整に使う主要オプション。とくに レート制御は、対象を落とさないため・検知を避けるため・そして礼儀として重要。
| オプション | 効果 |
|---|---|
-t 10 |
同時接続数 (既定 10)。下げると低速・低負荷になる |
-s 0.1 |
各リクエスト間の遅延 (秒)。本番診断では必須級 |
-H "..." / -b "..." |
ヘッダ / Cookie 付与 (認証後ページの探索) |
-p 127.0.0.1:8080:HTTP |
プロキシ経由 (Burp に流して観察・記録) |
-R 2 |
当たったディレクトリを深さ 2 まで再帰探索 |
-L / --follow |
リダイレクト (3xx) を追従する |
--basic user:pass |
Basic 認証 (--ntlm / --digest も可) |
-f out.json,json |
結果をファイル出力 (printer は -e printers で一覧) |
-o html |
標準出力の整形 (raw / html / json など) |
wfuzz のスキャンはアクセスログに 大量の 404/403 が短時間に並ぶ、User-Agent が既定のままなら Wfuzz/x.x という文字列が残る、といった形で容易に検知できる。WAF やレート制限、404 の監視で大半は弾ける。攻撃側がこれを避けるには -s での低速化や -H "User-Agent: ..." での偽装を使うが、正規の診断では痕跡を残すこと自体は問題ではない — むしろ許可されたスコープ内で行うことが前提。
類似ツールとの位置づけ — いつ wfuzz を選ぶか #
Web コンテンツ探索ツールは複数あり、wfuzz は **「Python ゆえの柔軟さ + フィルタ式言語 + エンコーダ/イテレータ」**を特徴とする。一方で速度では Go 製ツールに劣る。
| ツール | 言語 | 特徴 |
|---|---|---|
wfuzz | Python | 元祖。柔軟 (ペイロード型・エンコーダ・`--filter` 式) だが低速。現在は活発なメンテが止まっている |
ffuf | Go | 高速。FUZZ を任意位置に置ける汎用ファザー。wfuzz の思想を高速に再実装した後継的存在 |
gobuster | Go | 高速。dir/dns/vhost などモード別のシンプルな設計 |
feroxbuster | Rust | 高速 + 再帰探索が強力。自動再帰で深く掘る用途に向く |
| 絞り込み | wfuzz | ffuf |
|---|---|---|
| ステータスで表示 | `--sc 200` | `-mc 200` |
| ステータスで除外 | `--hc 404` | `-fc 404` |
| サイズ/文字数で除外 | `--hh 0` | `-fs 0` |
| 式言語での複合条件 | `--filter "c=200 and h>0"` | 非対応 |
大量辞書を高速に投げる現場作業は ffuf / feroxbuster が快適。一方 wfuzz は エンコーダでペイロードを加工したい、--filter 式で複雑な当たり条件を一発で書きたい、複数ペイロードをイテレータで自在に組み合わせたいといった「凝った 1 発」に強い。まず ffuf の -mc / -fc と wfuzz の --sc / --hc を取り違えないこと — これが両刀使いの第一歩になる。