以下の内容はhttps://cysec148.hatenablog.com/entry/2025/08/14/191653より取得しました。


【有料試作版】PortSwigger LAB解説:Inconsistent handling of exceptional input

Hello there, ('ω')ノ

ねらい

このLABは、入力値の取り扱いが処理の場所ごとにバラバラだと、想定外の権限(ここでは管理者パネル)に到達できてしまう、というロジックフローの欠陥を学ぶ演習です。 キモは「メールアドレスの長さ制限」と「確認メールの送信先」と「保存される値」の食い違いを突くこと。


全体像(まずはストーリーを掴む)

  1. Burp のコンテンツ発見で /admin を見つける。
  2. 直接アクセスすると拒否されるが、エラーメッセージから社内ドメイン(dontwannacry.com)ユーザだけ通すルールがあるとわかる。
  3. 新規登録では「社員は会社メールを使って」と表示される。
  4. しかしこのサイトは長すぎるメールを保存するときに255文字で切り捨ててしまう。
  5. 「@dontwannacry.com」の直後でちょうど255文字目になるように工夫し、@dontwannacry.comさらに後ろに自分の受信可能なサブドメインを続ける。
  6. 送信される確認メールはフルのアドレスに届くが、サーバ側に保存されたアドレスは255文字で切れて「@dontwannacry.com」で終わって見える。
  7. その結果、ログイン後は社員判定をパスし、管理パネルに入れる。そこで carlos を削除する。

実践:一手ずつ「なぜそうするか」を添えて

1) Burpでコンテンツ発見 → /admin を特定

  • 操作:Burp でプロキシしつつ LAB を開く → 「Target > Site map」→ 右クリック「Engagement tools > Discover content」→ スキャン開始。
  • なぜ:非リンクの管理用パスはしばしば隠れているため、自動探索で推測困難なエンドポイントを見つけるのが定石。

2) /admin にアクセスしてヒントを読む

  • 操作:ブラウザで /admin に直接アクセス。
  • 観察:アクセス拒否だが、メッセージにDontWannaCry ユーザならOKと示唆あり。
  • なぜ:エラーメッセージは認可条件をこぼしがち。ここではメールドメインで社員判定していると推測できる。

3) 新規登録画面の文言を確認

  • 操作:Sign up(Register)ページへ。
  • 観察:「社員は会社メールを使って」との注記。
  • なぜ:このサイトはドメインベースの身元確認をしている。回避の余地(実装の粗)がないか探る。

4) まずは「超長いメール」で挙動確認(ベースライン作り)

  • 操作:LABバナーのメールクライアントを開き、自分専用ドメイン(例:@abc123.web-security-academy.netabc123)をメモ。 次に登録画面で下記のようなとても長いメールで仮登録: (200文字以上のローカル部)@abc123.web-security-academy.net
  • 期待:確認メールが届くはず。リンクを踏んで登録完了 → 「My account」で保存されたメールが255文字で切られていることを観察。
  • なぜ:ここで保存時に255文字でトランケートされる事実を確定させる。後の長さ合わせ戦術の前提になる。

5) 本命の登録:255文字目を「@dontwannacry.com」の m に合わせる

  • 狙い:アカウントに保存されるアドレスがぴったり「…@dontwannacry.com」で終わるようにしつつ、確認メールは自分が受け取れるようにする。
  • 仕組み:

    • 保存は255文字で切り捨て
    • 社員チェックは保存された値を見て「末尾が dontwannacry.com なら社員」と判断しているはず。
    • そこで、アドレスを とても長いローカル部@dontwannacry.com.abc123.web-security-academy.net のように作る。
    • メールは完全なドメインに送られるため受信可能。一方、保存時は255文字で切れて「…@dontwannacry.com」になり、社員扱いになる。

長さの具体計算(オフバイワン対策)

  • 255文字目が dontwannacry.com の最後の文字 m になるようにする。
  • 文字数:dontwannacry.com は 16 文字(dontwannacry 12 + .com 4)。
  • 255文字の内訳: ローカル部(L文字) + @(1文字) + dontwannacry.com(16文字) = 255 よって L = 255 - 1 - 16 = 238
  • つまり、ローカル部を238文字にすれば、255文字目が m になる。
  • その後ろに .abc123.web-security-academy.net を続ければ、送信先は自分のメールクライアントになる。

実用例(生成ワンライナー)

  • ブラウザのコンソール等で以下を作ってコピペすると早い:
  'a'.repeat(238) + '@dontwannacry.com.' + 'abc123.web-security-academy.net'

上の abc123 は自分のメールIDに置き換える。

6) 確認メールのリンクを踏んでログイン → 社員扱いを確認

  • 操作:メールクライアントで確認メールを受信 → リンクでアクティベート → ログイン → 「My account」で保存アドレスが「…@dontwannacry.com」になっているのを確認。
  • なぜ:これで社員ドメイン※に見えるアカウントが完成。 ※実際の受信は自分のサブドメインで行われたが、アプリの保存値は切り捨てで社内ドメインになっている。

7) 管理パネルに入り、carlos を削除

  • 操作:/admin へ → 削除ボタンから carlos を削除。
  • なぜ:LABの達成条件(管理パネルへアクセスし、対象ユーザ削除)を満たす。

なぜこの攻撃が成立するのか(思考の軸)

  • 不整合な正規化: 確認メール送信は「入力そのまま」、アカウント保存は「255文字で切る」。同じ「メールアドレス」という概念を別々の規則で扱っている。
  • 境界値の悪用: 255というカラム長の上限を境に、アプリが見ている値の末尾を狙って意味のある断面(@dontwannacry.comで終わる)を作る。
  • ドメインによる権限付与の危うさ: メールドメイン=社員とみなす手法は、表記ゆれや切り捨てに弱い。今回はサブドメイン併用によりメール受信と「見かけの社員化」を同時に満たせた。

つまずきポイントと対処

  • 1文字ズレ(オフバイワン):ローカル部238文字を厳守。237や239だと末尾がズレ、保存後に @dontwannacry.co で止まったり、余計なドットが残ったりする。
  • 自分のメールIDの確認漏れ:メールが来ないと認証が完了しない。LABバナーのメールクライアントで自分の YOUR-EMAIL-ID を必ずチェック。
  • 文字種:ローカル部は英小文字の繰り返しなど単純な構成にする(UIやサーバのバリデーションで拒否されにくい)。

実務目線の防御策(開発・運用)

  • 単一の正規化ルート:送信・保存・認可判定が同じ関数・同じルールで正規化された結果だけを扱う。
  • 長さと形式の厳格バリデーション:過度に長いメールはサーバ側で拒否。許容長・形式は仕様で一本化。
  • メールドメインでの特権付与禁止:社員判定をドメイン依存にしない(IdP連携、招待制+二段階確認など)。
  • 検証済み値の固定化:メール変更時は再検証必須。権限判定は「検証済みの値」に限定。
  • 観測可能なヒントの抑制:エラーメッセージで認可条件を明かさない

まとめ

このLABは、入力値の「保存時の切り捨て」「送信時のそのまま利用」の不整合を突き、境界値(255文字)見かけ上の社内メールを作るのがポイントでした。 手順としては、/admin の存在と認可条件を把握 → 255文字境界の実験 → @dontwannacry.comが255文字目で終わるようにローカル部238文字で調整 → サブドメインを後ろに足して確認メールを受け取る → 社員判定で管理パネル到達 → carlos 削除、という流れです。

この考え方を自分のプロダクトに照らすなら、「同じデータを複数の箇所で別ルール処理していないか」「境界長で意味が変わる断面がないか」を点検するのが近道になります。

Best regards, (^^ゞ




以上の内容はhttps://cysec148.hatenablog.com/entry/2025/08/14/191653より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14