実際のログインと紛らわしい応答を見分ける

HydraBeginner
オンラインで実践に進む

はじめに

Fieldnote は Northline Print Fair の準備を進めています。出展者はログインして、自分のブース資料を取得します。資料には到着時刻、搬入場所、梱包リストが含まれます。最初の Hydra テストでは、使えるログインが複数見つかったように見えます。しかし、その一部は実際にはエラーページです。あなたの仕事は、本当の認証と紛らわしい応答を見分け、指定された出展者の完全な資料を取得することです。

必要なのは基本的なターミナル入力、パスの理解、タブの切り替えだけです。Hydra とローカルポータルは準備済みです。フォームのフィールド、照合条件、Cookie の扱いは使う前に説明します。Workstation がターミナル、Exhibitor Portal が Web サイトです。これは隔離された 1 つの演習用コンテナの 2 つの入口であり、2 台のホストではありません。アカウントと業務データはすべて合成です。指定の候補だけを使い、明示された練習フォームと指定アカウントだけをテストしてください。サーバー、アカウント、文書を変更してはいけません。

見積もりの 55 分には、読む時間や通常の入力ミスへの対応を含みます。初心者で実測した時間ではありません。成果物は、再利用できるフォーム引数、Hydra の元の結果、認証して取得したブース資料です。文章による報告書は不要です。

本当のログインで開く画面を確認する

このステップでは、動作が分かっているプレビュー用アカウントを開き、そのアカウント自身のブース情報と対応付けます。HTTP リクエストの成功は、サーバーが応答を送ったことを意味します。認証の成功は、サーバーが利用者の身元を確認して受け入れたことを意味します。この 2 つは別の事実です。

Exhibitor Portal タブを開きます。Start at the practice desk、続いて Practice sign-in を選択します。出展者 ID に preview、パスワードに Preview24 を入力し、Sign in を選択してください。結果には Signed in as preview と表示されます。Open your workspace を選択します。ブースは DEMO で、梱包の注意書きには練習用文書であることが示されています。これが通常の業務の流れです。このプレビュー資料は最終課題の成果物ではありません。Sign out、続いてナビゲーションの Practice desk を選択します。

DEMO ブースが表示された既知のプレビューワークスペース

出展者 ID とブースから、これがプレビュー文書だと分かります。ダウンロードボタンがあるだけでは、指定された資料である証明にはなりません。

Workstation に切り替えます。このラボのコマンドは /home/labex/project/login-review で実行します。入口は自動的にこのディレクトリへ移動します。pwd は現在のディレクトリを表示するため、場所を確認できます。

pwd

/home/labex/project/login-review が表示されるはずです。別の場所にいる場合は、cd でディレクトリを変更します。

cd /home/labex/project/login-review

練習用のログインフォームは /practice/login に POST リクエストを送ります。POST では、リクエストの本文に名前付きのフィールドを入れます。ここでは username と password という名前を使い、& で区切ります。curl はブラウザとは独立して、ターミナルからリクエストを送ります。次のコマンドでは、--data がフィールドを指定し、-s が進捗表示を隠し、-o が応答本文を保存し、-w が HTTP ステータスを表示します。一重引用符は空白、&、%{http_code} を curl に渡す内容としてまとめ、シェルが解釈しないようにします。

意図的に誤ったパスワードを 1 回送信します。

curl -s -o wrong.html -w 'HTTP %{http_code}
' --data 'username=preview&password=Wrong24' http://127.0.0.1:8080/practice/login

出力は HTTP 200 です。これはアプリケーションがページを返したという意味であり、パスワードが使えたという意味ではありません。wrong.html にそのページが保存されています。grep はテキストを検索し、-o オプションで一致した文字列だけを表示します。周囲の HTML マークアップを読む必要はありません。

grep -o 'Incorrect password' wrong.html

Incorrect password と表示されるはずです。本当の成功と拒否されたログインが同じ HTTP ステータスを返すことがあります。このレッスンでは、普通のパスワード入力ミスは修正できます。値を直してもう一度送れば十分です。接続エラーはリクエストがサービスに届かなかったことを示します。ログイン結果を解釈する前に、127.0.0.1、ポート 8080、指定パスを確認してください。入力ミスのために VM をリセットする必要はありません。

紛らわしい検出結果を再現する

このステップでは、4 組の小さな練習データに対して、意図的に不適切な分類ルールを実行します。これは誤ったテストの実演であり、信頼できる監査ではありません。

Workstation のまま進めます。cat はファイルを表示します。準備されたリストには、完全な username:password の組が 1 行に 1 組ずつ入っています。

cat practice-pairs.txt
preview:Wrong24
retired:Wrong24
offline:Wrong24
preview:Preview24

retired は利用できないアカウントの合成サンプルです。offline は制御されたサービスエラーのサンプルで、練習用ハンドラーはセッションを作らず HTTP 503 を返します。実際の上流サービス障害や本物の出展者ではありません。最後の組は、動作が分かっているプレビュー用ログインです。この小さな許可済み集合を保ち、任意のユーザー名とパスワードの組み合わせに広げないでください。

Hydra の http-post-form モジュールは、それぞれの組をフォームへ送ります。その引数はコロンで区切った 3 部分、POST パス、フィールド、応答条件からなります。^USER^ と ^PASS^ は Hydra のプレースホルダーです。F= は「このパターンを含む応答を失敗として扱う」という意味です。それ以外の応答は成功に分類される可能性があります。このコマンドは意図的に Incorrect password しか認識せず、ほかの失敗の種類を見落とします。

オプションは、この作業場所の古い復元確認を無視する -I、組にした候補を指定する -C、ポートを指定する -s、ワーカーを 1 つにする -t 1、結果ファイル名を指定する -o、JSON 出力を選ぶ -b json です。最後の引数は引用符で囲まれているので、空白や & が入っていても 1 つの引数のままです。

hydra -I -C practice-pairs.txt -s 8080 -t 1 -o misleading.json -b json 127.0.0.1 http-post-form '/practice/login:username=^USER^&password=^PASS^:F=Incorrect password'

プログラムを書かずに JSON を読むには、Python 組み込みの整形ツール json.tool を使います。python3 -m はインストール済みモジュールを実行します。

python3 -m json.tool misleading.json

results リストを読んでください。動作することが分かっているプレビューの組に加え、利用できないアカウントやサービスエラーの組まで現れることがあります。検出結果は条件による判断であって、認証されたワークスペースを開いた証明ではありません。最上位の success: true は Hydra の実行状態を表し、報告されたパスワードがすべて有効という意味ではありません。この紛らわしいファイルを最終監査結果に使わないでください。

Hydra が構文エラーや接続エラーを報告した場合は、引用符を含む引数全体とポートを上のコマンドと比較し、入力を直して、この限定された練習テストをもう一度実行します。接続の失敗は、パスワードが使えることも、適切な「該当なし」の結果であることも示しません。

既知の応答で条件を調整する

このステップでは、本当の成功を受け入れ、既知の 3 種類の認証成功ではないケースをすべて拒否する再利用可能な条件を保存します。Workstation のまま、まず同じリクエスト形式でほかの応答を調べます。

利用できないアカウントへのリクエストは、意図的に HTTP 200 を返します。

curl -s -o retired.html -w 'HTTP %{http_code}
' --data 'username=retired&password=Wrong24' http://127.0.0.1:8080/practice/login
grep -o 'Sign-in unavailable' retired.html

制御されたサービスエラーのリクエストは、意図的に HTTP 503 を返します。そのページに Incorrect password がなくても、有効なセッションはありません。

curl -s -o offline.html -w 'HTTP %{http_code}
' --data 'username=offline&password=Wrong24' http://127.0.0.1:8080/practice/login
grep -o 'Service unavailable' offline.html

次に、成功すると分かっている応答を取得します。この curl リクエストのセッションは、ブラウザとは別です。

curl -s -o preview.html --data 'username=preview&password=Preview24' http://127.0.0.1:8080/practice/login
grep -o 'Signed in as preview' preview.html

ここでは Signed in as が認証された結果を示します。Welcome は失敗ページにも現れるので、認証の区別には使えません。Hydra の S= は成功を示すパターンを選択します。応答にそれが含まれるときだけ成功と数えます。-U でインストール済みモジュールのヘルプを確認してください。パス、フィールド、条件の構文が説明されています。

hydra -U http-post-form

練習用引数の全体を保存します。cat > calibration.txt はテキストをファイルへ書き込み、> は既存ファイルを置き換えます。ヒアドキュメントは、終端行の EOF まで複数行の入力を渡します。'EOF' を引用符で囲むと、本文がそのままの文字列として保持されます。終了マーカーは前に空白を付けず、単独の行に置いてください。

cat > calibration.txt <<'EOF'
/practice/login:username=^USER^&password=^PASS^:S=Signed in as
EOF

シェル変数は、このターミナルで繰り返し使うテキストを保存します。$(cat calibration.txt) がファイルを読み、form= が結果を保存します。= の前後に空白を入れてはいけません。あとで "$form" を引用符付きで使うと、空白も 1 つの引数の中に保たれます。この変数は現在のターミナルセッションに属します。再接続したら代入をやり直してください。

form=$(cat calibration.txt)
hydra -I -C practice-pairs.txt -s 8080 -t 1 -o calibration.json -b json 127.0.0.1 http-post-form "$form"
python3 -m json.tool calibration.json

報告されるのは preview:Preview24 だけのはずです。誤ったパスワード、利用できないアカウント、HTTP 503 は認証されていません。条件の調整には既知の成功例も必要です。すべてを拒否する条件も誤りだからです。十分に広く失敗を捉えるパターンは、この成功パターンと同等にできます。特定の S= の書き方を強制するものではありません。保存された引数は、キーワードを含むだけで受け入れられるのではなく、既知の応答それぞれに対して個別にテストされます。

指定された出展者の資料を取得する

このステップでは、調整した方法を指定出展者に適用し、その後、独立して認証して実際の業務文書を取得します。

Exhibitor Portal を開き、Exhibitor sign-in、続いて View your review assignment を選択します。指定アカウントは papertrail、POST パスは /signin です。使えるのは candidates.txt 内の 3 つのパスワードだけです。練習アカウントは別のフォーム用です。Workstation に切り替え、候補を読みます。

cat candidates.txt

指定パスと同じフィールド、同じ条件を使って、2 つ目の再利用可能な引数を保存します。

cat > form.txt <<'EOF'
/signin:username=^USER^&password=^PASS^:S=Signed in as
EOF
form=$(cat form.txt)

-C と異なり、-l papertrail は固定のユーザー名を、-P candidates.txt はそのアカウントに許可されたパスワードを指定します。小規模な指定監査を実行し、新しい元の JSON 結果を保存します。

hydra -I -l papertrail -P candidates.txt -s 8080 -t 1 -o findings.json -b json 127.0.0.1 http-post-form "$form"
python3 -m json.tool findings.json

唯一の本物の検出は papertrail、パスワードは InkPaper7 です。この結論は指定アカウントと候補集合だけに適用されます。サイト全体が安全だと主張するものではありません。

Exhibitor Portal に切り替えます。Exhibitor sign-in を選び、見つかった組を入力して Sign in、続いて Open your workspace を選択します。papertrail、ブース N-14、到着 09:15、North loading door を確認してください。Download booth kit を選ぶと、実際にブラウザでダウンロードできます。そのファイルはブラウザのダウンロード先にあり、演習用コンテナには自動で現れません。

指定 papertrail ワークスペースと本物のダウンロードリンク

ダウンロードを使う前に、梱包の注意書きの上にある出展者とブースのフィールドを確認してください。

必要な VM 内コピーを保存するため、Workstation に戻ります。Cookie はサーバーが発行するセッション識別子です。-c exhibitor.cookies は、このターミナルでのログインが受け取った Cookie を保存します。この Cookie ファイルは curl のもので、ブラウザや Hydra と自動で共有されません。応答本文は signin.html に保存されます。

curl -s -c exhibitor.cookies -o signin.html --data 'username=papertrail&password=InkPaper7' http://127.0.0.1:8080/signin

同じファイルで認証済みのダウンロードを取得します。-b は保存された Cookie を送信します。-f は、HTTP 拒否のときに非ゼロの終了状態を返し、エラーページを資料として黙って保存しないようにします。

curl -f -s -b exhibitor.cookies http://127.0.0.1:8080/kit.json -o booth-kit.json

403 または curl の終了状態 22 は、このクライアントに受け入れられたセッションがないことを意味します。ユーザー名、パスワード、フォームのパス、Cookie ファイル名を確認し、ログインコマンドをもう一度実行してから再ダウンロードしてください。404 はパスの間違いです。これらは修正できるエラーです。プレビューのコピーで資料を代用してはいけません。

python3 -m json.tool booth-kit.json

出展者、ブース、到着時刻をページと照合します。完全な資料には、印刷物用ラック 3 台、テーブルクロス 2 枚、番号付きの印刷物用スリーブに関する注意書きも含まれます。ファイルがあるだけ、または出展者名が一致するだけでは、文書全体が正しい証明にはなりません。

最後に Exhibitor Portal で Visitor guide を開きます。公開の到着案内が引き続き利用できる必要があります。変更したのは自分のファイルとセッションだけであり、サービス、アカウント、業務データは保たれています。最終成果物は作業ディレクトリ内の form.txt、findings.json、booth-kit.json です。チェックは既存のログインとダウンロードの事実を読み、別の使い捨てサービスで保存した引数を試します。実際のポータルで不足している作業を補うものではありません。

まとめ

実際に認証されたワークスペースを、パスワード誤り、利用できないアカウント、サービスエラーの応答と比較しました。Hydra の誤検出を再現し、成功例と失敗例の両方で再利用可能なフォーム条件を調整したうえで、独立した Cookie セッションを使って指定された出展者の識別情報を確認し、その完全な資料を取得しました。HTTP 200、実行成功フラグ、一般的な Welcome メッセージは、どれも単独では認証の証明になりません。