【ログイン画面の攻撃者目線】何を狙う?どう守る?|CTF思考フレームワーク #01
📖 この記事はシリーズの一部です
「CTF思考フレームワーク」 Webフォーム編 #01 / 公開中 7記事 → シリーズ一覧を見る →
CTFや脆弱性診断で「ログイン画面」を見たとき、攻撃者は何を観察し、どう仮説を立て、どう試すか。今回はその”思考の流れ”を追いかけます🕵️
Web系CTFで一番最初に出会うジャンル。HTTPの基本がわかればOK👌
ログインフォームって、ただの「ID/パスワード入れるだけの場所」に見えますよね。でも攻撃者の目には、認証ロジックの裏側まで透けて見えます。一緒にその見方を覚えましょう✨
👀 観察フェーズ:まず何を見る?

攻撃って、いきなり手を動かすイメージあるけど…実は最初はただ眺めるだけなんだよ。
まずは何も操作せず、画面とリクエストをじっくり観察します。ここで気づく情報量で勝負の8割が決まります🔍
ブラウザの開発者ツール → Network タブを開いて、POST時のリクエスト/レスポンスを丸ごと見るのがおすすめです。F12キーで一発👀

え、見るだけでそんなに情報出てるの…?知らずに使ってたかも💧
🤔 仮説フェーズ:攻撃者ならどう考える?
観察したら、攻撃者の頭の中をシミュレーションしてみましょう。
🔎 仮説①:エラーメッセージで「存在するアカウント」がバレる
ユーザー名が間違っているときと、パスワードが間違っているときで、エラーメッセージや反応が違っていませんか?文言・ステータスコード・レスポンス時間に少しでも差があれば、攻撃者は「存在するアカウントだけ」を絞り込めてしまいます。これがいわゆるユーザー名列挙(User Enumeration)です。
| 入力パターン | 返ってくるメッセージ例 | 攻撃者の解釈 |
|---|---|---|
| 存在するID + 間違いPW | 「パスワードが違います」 | ➡ このIDは存在する 🎯 |
| 存在しないID | 「ユーザーが見つかりません」 | ➡ このIDは存在しない |
| 存在するID + 正しいPW | (応答時間が長い/リダイレクト) | ➡ ログイン成功の差分でも判別可 |

えっ、文言が違うだけで、そんなに情報が漏れるの!?
見た目は親切なメッセージほど、実は攻撃者にとっても親切。文言・コード・時間まで揃えて「同じ応答」にするのが鉄則。揃っていないと、辞書攻撃の前段で標的リストが完成してしまいます。
🔓 仮説②:失敗してもロックされない=総当たりし放題
次に攻撃者が確認するのが、ログイン失敗を繰り返したときの挙動です。10回でも20回でも普通に「パスワードが違います」が返ってくるなら、ブルートフォース攻撃がやり放題。CAPTCHAもレート制限もないログイン画面は、それだけで重大な弱点になります。

うわ、それじゃ自動ツールで延々と試されちゃうじゃん…!
curlやBurp Intruderを使えば、1秒に何十回も試行できます。よくあるパスワード上位1000件を回すだけで、辞書攻撃が成立してしまうケースも珍しくありません。
🍪 仮説③:CookieやJWTから内部実装が透けて見える
ログイン後にセットされるCookieやレスポンスヘッダ、JWTの中身を見ると、サーバ側の実装がかなりの精度で推測できます。JWTのペイロードはBase64URL(標準Base64の派生)で誰でも読めるので、alg=noneのような弱い設定が残っていれば、署名なしで改ざんしたトークンが通ってしまうことも。
※2026年現在、PyJWT・jsonwebtoken等の主要ライブラリはデフォルトでalg=noneを拒否しますが、古い実装や設定ミスで残っているケースが存在します。

特にチェックしたいのは、HttpOnly/Secure/SameSiteフラグの有無、JWTのalg値、セッションIDが推測可能な連番じゃないか、の3点だね。
🔁 仮説④:パスワードリセットは「裏口」になりやすい
ログイン画面を固めても、パスワードリセット機能がゆるいと意味がありません。リセットリンクのトークンが推測可能だったり、有効期限が無期限だったり、メール送信先を任意に書き換えられたり——どれか一つでも穴があれば、そこからアカウント乗っ取りに繋がります。

表玄関を固めても、裏口がガバガバなら意味ないんだね…💦
リセット系の脆弱性は #03 で詳しく扱うので、ここでは「ログイン画面を見るときは必ずリセット導線もセットで観察する」と覚えておいてください。
これら4つを順番にチェックしていくのが、攻撃者の典型的な思考パターン。次は「実際にどう確かめるか」の検証フェーズに進みます。
こんな感じで、観察した事実から「ここ攻めれそう」という仮説を複数立てます💡
🔬 検証フェーズ:実際に試す手順

仮説のままじゃ意味がないから、小さく試して反応を見る。検証は”答え合わせ”の時間だね。
仮説が立ったら、いよいよ検証フェーズです。ただし必ず自分の環境か、許可されたCTF・検証サイトでやってください(最後のお約束で詳しく書きます)。
存在しそうな名前(admin、test、root)と、絶対存在しない名前(asdfqwer1234)を入れてレスポンスを比較。エラーメッセージ・ステータスコード・レスポンス時間に差があれば「列挙可能」のサイン。
同じユーザー名で連続10回ログイン失敗を試す。11回目もエラーが返るだけでロックされない=総当たり可能。curlやBurp Suiteのリピーターで簡単に確認できます。
ユーザー名欄に admin’ — や ‘ OR ‘1’=’1′ — を入れて挙動確認。エラーが出たり、なぜかログインできたら脆弱性あり。
ログイン後のSet-Cookieを見て、HttpOnly・Secure・SameSite属性が付いているか。値がBase64やJWTなら中身を覗いてみる。
POSTで送るログインリクエストを、GETやPUTに変えてみる。意外な挙動が見えることも。

うわ、レスポンス時間の差とか、エラーメッセージの違いでそこまでバレるの!?

そう、守る側はこの”差”を消すのが基本。文言・コード・時間、ぜんぶ揃えるのが鉄則だよ。
⚔️ 攻撃フェーズ:攻撃者ならこう攻める

ここからは実際にやられる側の話。”なぜ通るか”を理解するのがゴールだよ。
検証で「ここ弱いな」と判断したら、いよいよ実際の攻撃手法に移ります。代表的なのはこの3つ。
レート制限がなければ、Hydra・Medusaなどでパスワード総当たり。よくあるパスワードリスト(rockyou.txtなど)を使えば、弱いパスワードは数分で破られます💥
他サイトから漏洩したメール+パスワードのリストを投入。「同じパスワード使い回し」してるユーザーが大量にいるので、成功率はかなり高い。
脆弱なバックエンドだと、admin’ — だけで認証回避できることも。最終的にはこんなフラグを取られます👇

えっ、admin' -- って入れるだけで通っちゃうの…?ホラーじゃん…💧
結果として、こんな“フラグ”を取られちゃうイメージ:
Username: admin' --
Password: anything
→ Logged in as admin
FLAG{sql_injection_in_login_form}もちろん、これらは“理解するため”に書いています。実環境への攻撃は犯罪です🚫
🛡️ 防御フェーズ:どう守る?

やっとお待ちかね、守る側の打ち手。攻撃を見たあとだと、対策がスッと入ってくるよ。
攻撃側を理解したら、守る側の打ち手も見えてきます。3レイヤーで考えるのがコツ🛡️
- エラーメッセージは「IDまたはパスワードが違います」で統一
- パスワードリセットも「メール送信しました」と一律応答(存在判定させない)
- ログイン成功時のレスポンス時間も一定化
- IPアドレス・アカウント単位のレート制限
- パスワードはbcrypt/Argon2でハッシュ化(平文保存厳禁)
- CSRFトークン、HttpOnly・Secure・SameSite=StrictのCookie属性
- プレースホルダ/パラメータ化クエリでSQLi対策
- 漏洩パスワードチェック(Have I Been Pwned API連携など)
- 異常ログイン検知・通知(普段と違う国・端末からのアクセス)
- パスワード変更履歴・最終ログイン時刻のユーザー表示
- WAF導入で既知の攻撃パターンをブロック(※WAFは多層防御の最後の保険。根本対策はパスワードハッシュ化や認証ロジックなど実装側で行う)

なるほど…画面・サーバ・運用の3層で重ねるイメージか。1個壊れても他で守れるってことだね!

その通り。多層防御がセキュリティの基本だよ。1個に頼らず重ねるのがポイント🛡️
🛡️ 今日からできる対策ツール
パスワードの使い回しや手動管理はどんなに気をつけても限界があります。🔑 パスワード管理ツール「ワンパス」なら、複雑なパスワードを安全に保管して「1つのマスターパスワード」だけ覚えられるので、今日から始める防御策としてしっくりきます。
⚠️ よくある落とし穴
- CAPTCHAだけでレート制限したつもりになる(自動化で突破される)
- JavaScriptでクライアント側だけバリデーションする(サーバー側でも必須)
- ログイン失敗ログを残してない(攻撃を検知できない)
🧰 ツール早見表
| ツール | 何ができる | 使いどころ |
|---|---|---|
| Burp Suite | リクエスト改ざん・リプレイ | 観察〜検証フェーズ全般 |
| curl | 素のHTTPリクエスト | ステータスコード・ヘッダー確認 |
| Hydra | ログイン総当たり | 攻撃フェーズ(演習環境のみ) |
| ffuf | ユーザー名列挙 | 差分レスポンス検出 |
| jwt.io | JWTデコード/検証 | Cookie検査 |
🎓 本気で学びたい人へ
Webセキュリティを「趣味」から「仕事」に変えたい方へ。🎓 ササエルはインフラエンジニアに特化したオンラインスクールで、セキュリティ設計の基礎から体系的に学べます。
📚 もっと深く学びたい人へ
体系的に攻撃と防御の両面を学びたいなら『ホワイトハッカー入門 第2版』が分かりやすい入口です📚
🧪 自分で検証してみる
「自分でWordPressサイトを立てて、ログイン画面のセキュリティを実際に試してみたい」なら、まずは安価で高速なConoHa WINGから。初期費用無料で始められます。
⚖️ 大事なお約束
この記事の手法は、必ず自分の環境か、許可されたCTF・脆弱性報奨金プログラム(HackerOne、Bugcrowd等)で試してください。他人のサービスに無断で攻撃を仕掛けるのは不正アクセス禁止法違反、立派な犯罪です。学んだ知識は守る側で活かしましょう🤝
📚 次に読みたい
📰 関連の実例・ニュース解説
この攻撃が実際に使われた事件・対策ガイドはこちら:
CTF・セキュリティ学習ハブページへ



