Shikata Ga Nai

Private? There is no such things.

不完全なファイルアップロード検証を悪用してWebシェルを設置する方法

Hello there, ('ω')ノ

✅ 実際のWebサイトは「無防備」ではない

実際の運用環境では、 前回のラボのように完全に制限がないファイルアップロード機能は珍しくなっています。 ほとんどのサイトは何らかのアップロード制限や検証機能を設けています。


⚠️ しかし、それでも脆弱な理由

検証がある=安全ではありません。 開発者の設定ミスや想定外の抜け道によって、 「不完全な防御(flawed validation)」 が多く存在します。

攻撃者はこのわずかな隙を突いて Webシェルをアップロードし、リモートコード実行(RCE) に持ち込むことができます。


🎯 不完全な検証の具体例

1. 📝 拡張子のチェックのみ

  • .php → 拒否
  • image.jpg.php → 通過
  • shell.pHp → 通過
  • .php5, .phtml → 通過

✅ 攻撃者は 複数の拡張子や大文字小文字 を駆使してバイパス可能。


2. 🖼️ Content-Typeだけを信じる

  • 攻撃者はBurp Suiteなどで Content-Type: image/jpeg と偽装可能。

Content-Typeは自己申告なので、信用してはいけない。


3. 🧪 MIMEタイプだけを検証

  • 実ファイルの先頭バイト(マジックナンバー)はチェックせず、 HTTPヘッダーのMIME情報のみで許可。

✅ 画像ファイル風に偽装した 実際はPHPファイル がすり抜ける。


4. 🗂️ ディレクトリ設定の不備

  • アップロード後のファイルが実行可能なディレクトリ(例:/uploads/)に配置される。

✅ アップロード自体は通さないのに、 他ディレクトリやCDN経由では実行されてしまうケースも。


💻 攻撃者の戦略:段階的バイパス

  1. ファイル名・拡張子でバイパスを試みる
  2. Content-Type偽装で通過を狙う
  3. サイズ制限の突破や長ファイル名攻撃を試す
  4. パス・ディレクトリ構造の不備でアクセス・実行可能か確認する

✅ 最終的には Webシェルがサーバー上に置かれ、直接アクセス可能になれば成功。


🛑 攻撃例:想定外バイパスの流れ

<?php echo system($_GET['cmd']); ?>
  1. ファイル名:avatar.jpg.php
  2. Content-Type:image/jpeg
  3. Upload → /uploads/avatar.jpg.php に保存
  4. URLアクセス:https://example.com/uploads/avatar.jpg.php?cmd=id
  5. サーバーでコマンド実行 → 結果がレスポンスで返る

✅ まとめ:防御側の教訓

やってはいけない防御 なぜダメか
ブラックリストのみ 例外が多すぎる
Content-Type信頼 攻撃者に偽装される
MIMEチェックのみ マジックバイトまで検証すべき
実行可能ディレクトリに保存 直接実行されるリスク大

「対策しているつもり」では守れない。 攻撃者はわずかな設定ミスや抜け道を常に探しています。

Best regards, (^^ゞ